With the speed of development in Office 365, it is sometimes hard to track which changes have been made to your tenant. Of course, there is the roadmap and message board which you can use to keep up to date, but those are in general high level descriptions. Sometimes you may want to see what are the changes at the cmdlet level in your tenant, between tenants, or Azure Active Directory module. And there is also the occasional gem in the form of a yet undocumented cmdlet or parameter which could hint at upcoming features.
For this purpose I have created a simple script which has two purposes:
Export information on the current cmdlets available through Exchange Online or Azure Active Directory.
Compare two sets of exported information, and display changes in a readable way.
The script is in PowerShell (of course), and is called Compare-Cmdlets.ps1. To export information, you need to be already connected to either Exchange Online or Azure Active Directory (or both).
To export cmdlet information, use:
For Exchange Online and Azure Active Directory, separate export files are created. The files are prefixed with a timestamp and postfixed with the Exchange Online build or Azure Active Directory module version, e.g. 201803121814-ExchangeOnline-15.20.548.21.xml or 201803121815-AzureAD-188.8.131.52.xml.
After a few days/week, or when connected to another tenant or using a new Azure Active Directory PowerShell module, run the export again. You will now have 2 sets of Exchange Online or Azure Active Directory cmdlets, which you can compare using the following sample syntax:
Many people I encounter in the field of Office 365 or Exchange have an infrastructure background. That is, they know a lot about their product(s), how to make it work (or don’t), how to manage, deploy or troubleshoot, etcetera.
Then there is, the let us call it, the reality check of the cloud era, with a roller coaster of cloud-originating developments. This requires a different management focus for these products, resulting in products architected for scale, and introducing configuration and management instruments primarily designed to be ready for automation and operate on scale as well. PowerShell support in Microsoft products is such an instrument.
The introduction of PowerShell required folks with an infrastructure background to develop a new skill: instead of clicking buttons in an interface, they should also become a PowerShell practitioner. Not necessarily wizard level, but at least they need to know their way around when managing their environment using PowerShell, reading and interpreting scripts provided by Microsoft or other vendors prior to usage, or even make changes to make those scripts fit for their own environment.
Writing scripts is another matter. This requires a tad different mindset, where you make repeatable tasks repeatable (time-saving), less prone to error (job-saving), and reusable by your coworkers or even the community who may need to perform the same task. Of course, everybody also expects your scripts to be generic (no hard-coded elements), robust and resilient, adding 90% more code (a bit exaggerated, but you get the idea).
What most of administrators struggle with, is making the connection between managing the product using PowerShell, and how to start using PowerShell to develop their own set of scripts or tools to automate tasks their environment. Administrators wanting to learn such skills will usually find is great books about the product, and great books on learning (generic) PowerShell. Of course, existing scripts found using their favorite search engine can also be a great starting point, provided somebody already developed it for the task you are trying to accomplish.
With the Exchange Server 2016 administrator in mind, Exchange fellows Dave Stork and Damian Scoles tried to bridge that gap with their book, Practical PowerShell: Exchange Server 2016. It uses some practical Exchange-themed examples, how to approach the problem, and how to go from running a few cmdlets in sequence to developing small scripts which operate against one or multiple servers. Also, while this book aims at the on-premises Exchange administrators, the skills learned are not lost when the organization moves to Exchange Online as these scripting skills are compatible.
Knowing how difficult it can be to transfer knowledge to paper from my own experience, I think Dave & Damian did a respectable job. The timing of the book release is also interesting, as the product which introduced PowerShell to so many of us, Exchange Server 2007, is going End of Life soon, on April 2011, 2017 to be exact. Realizing PowerShell has been around now for so many years, there is no excuse to get your PowerShell skills going, unless you want to share the faith of dinosaurs.
A short blog on a small survey I’ve been running for some time now on the usage of Install-Exchange15, the PowerShell script for fully automated deployment of Exchange 2013 or Exchange 2016.
I started the survey because I was curious on a few things:
How the script is used; do folks use it for deploying in lab environments, or also actual production environments.
What Exchange versions are deployed; only current ones (n-2 at most, i.e. lagging 2 Cumulative Update generations at most), or also older versions.
What operating systems are used to deploy Exchange using this script.
The second and last items are of most interest, as keeping backward compatibility in the script, for example like deploying Exchange Server 2013 SP1 on Windows Servers 2008, requires keeping a lot of ‘legacy code’ in there.
Fortunately, the survey shows many of you use the script to deploy recent Exchange builds on current operating systems. So, in time, you will see support for older builds and operating systems being removed, making the script more lean and mean as well.
Now, on to the results:
In what environments do you use the script to deploy Exchange?
Do you use Install-Exchange15.ps1 for previous (N-2 or older) Exchange 2013/2016 builds?
On which Operating Systems do you deploy Exchange 2013/2016? (multiple options possible)
Windows Server 2008
Windows Server 2008 R2
Windows Server 2012
Windows Server 2012 R2
Windows Server 2016
Finally, a summary of the feedback and requests send in by respondents through the open comments section:
Installation on Windows Server 2016. The survey was created before Windows Server 2016 was supported, so we used the feedback given on people deploying on WS2016 in the above results.
In general, positive feedback on having this script for automated deployment, as well as the SCP feature.
Request for having a GUI to create the answer file.
Request to having the option to configure the virtual directories after installation. However, the script allows for inserting custom (Exchange) cmdlets in its post-configure phase.
Request to output cause of failed Exchange setup to the screen. That however, is something I wouldn’t recommend; the Exchange setup log files contain the details.
Request to have some sort of visible clue if the installation was successful or not.
Note: Due to Microsoft putting Ignite 2016 contents on YouTube and a new portal, I had to rewrite the download script. Mattias Fors was also working on this, and after integrating his contents pointers, I present you Ignite2016Download.ps1. Check the description on Technet Gallery page for usage options.
Today, the Ignite 2016 event will kick off in Atlanta, US. The agenda contains the whopping number of 1412 sessions, of which 395 touch Office 365 and 133 Exchange in some way or another.
With those numbers it is impossible to attend every session for folks interested in these topics, but luckily Microsoft will also publish Ignite 2016 sessions on Channel 9 this year.
Some of the interesting sessions to watch out for are (links should resolve to on-demand sessions, as they become available):
Secure Office 365 in a hybrid directory environment
For those that wish to view sessions offline, there is a script to download the slidedecks and videos. It does so by scraping the Ignite portal, downloading slidedecks from the portal itself, and videos from the related YouTube video link using an utility youtube-dl.exe (which you can also use to download playlists, quite neat). The script can take some parameters:
DownloadFolder to adjust the download folder.
Format to alter the dimensions and quality of the downloaded videos (see help for supported formats).
Title to filter on title keyword
Keyword to filter on description keyword.
Start to use a different version number to start scraping. Scraping is done sequentially; in the output you will notice a (#nnn) next to the title. That is the current post number.
NoVideos to skip downloading videos.
You can download the script from the TechNet Gallery here.
When deploying Exchange 2013 or Exchange 2016 in co-existence with a legacy version of Exchange, there comes a point where all traffic is routed through Exchange 2013/2016. Traffic for mailboxes hosted on legacy Exchange versions will be proxied by Exchange 2013/2016 to the back end.
This proxy process has some built-in limits for certain protocols, which you could encounter. Symptoms of these limits are Event 2022’s being logged in the Application log by the MSExchange Front End HTTP Proxy service:
Per Exchange 2013 CU7, this message should be considered a notice, despite the confusing event description. No connections are being blocked. However, the events create noise in your logs, which can be prevented by raising these limits. To accomplish this, you need to dive in to the web.config of the applicable HTTP Proxy protocols:
After adjusting these values, recycle the relevant application pools, e.g. MSExchangeSyncAppPool and MSExchangeRPCProxyAppPool.
The above steps need to be performed on all Exchange 2013/2016 Client Access Servers.
To automate this process of tedious editing in web.config files, I have created a small script which lets you alter these values for EAS and RPC against the local server or remotely. The script, Configure-HTTPProxyTargetBackEnd.ps1, has the following parameters:
Server to specify server to configure. When omitted, will configure local server.
AllServers to process all discoverable Exchange Client Access servers
Almost 3 years ago, I wrote an article on how to enhance the PowerShell Integrated Scripting Environment, or ISE. That seemed adequate for the Exchange admin back then, who would mostly connect PowerShell sessions to their on-premises environment, and occasionally a bit of Exchange Online.
Fast forward to 2015, most modern Exchange administrators not only require a connection – if any – to their Exchange on-premises environment, but likely to one or more of the Office 365 services as well, including Exchange On-Premises, Azure Active Directory, Exchange Online Protection, Microsoft Teams, Skype for Business Online, SharePoint Online, Azure Information Protection or Compliance Center.
All these services use a different PowerShell session, use a different endpoint FQDN, and in some cases require a locally installed PowerShell module. Likely common denominator is the credential used to access each of these services. So, tired of re-entering my credentials every time when switching from Exchange Online to Exchange Online Protection, I created a script with a set of functions to allow me connect to each individual Office 365 service or Exchange Online:
Connect-AzureActiveDirectory: Connects to Azure Active Directory
Connect-AIP: Connects to Azure Information Protection
Connect-ExchangeOnline: Connects to Exchange Online
Connect-SkypeOnline: Connects to Skype for Business Online
Connect-EOP: Connects to Exchange Online Protection
Connect-ComplianceCenter: Connects to Compliance Center
Connect-SharePointOnline: Connects to SharePoint Online
Get-ExchangeOnPremisesFQDN: Gets FQDN for Exchange On-Premises
Get-Office365Tenant: Gets Office 365 tenant name (SharePoint)
Set-Office365Environment: Configures Uri’s and region to use
Get-TenantID: Returns TenantID using previously used credentials
Note that functions and credentials used in the script are global, and in principle only need to be entered once per shell or ISE session. If you need different credentials, call Get-Office365Credentials again. User interaction is a very basic (Read-Host), but it does the job. The script will also detect if any PowerShell module supporting Multi-Factor Authentication is installed. If so, you will be prompted if for using MFA when authenticating to workloads such as Exchange Online, Azure Active Directory, Microsoft Teams, Skype for Business Online or SharePoint Online.
Requirements During initialization, the script will detect the modules which are required for certain Office 365 services. When not installed, it will notify you, and provide a link where to obtain the PowerShell module. The related Connect function will not be made available. PowerShell is required to run this script, which is tested against version 5.1 (but should work with lower versions down to version 3).
Usage The functions are contained in a script called Connect-Office365Services.ps1. You can call this script manually from your PowerShell session to make the functions available. However, more convenient may be to have them always available in every PowerShell or ISE session. To achieve this, you need to edit your $profile, which is a script which always starts when you start a PowerShell or ISE session. By default this file does not exist and you need to create it, including the path. Also note that the files for PowerShell and ISE are different, Microsoft.PowerShell_profile.ps1 and Microsoft.PowerShellISE_profile.ps1 respectively.
Now, of course you can copy and paste the functions from the script file to your own $profile. Better is to call the script from your $profile, as this allows you to overwrite the Connect-Office365Services.ps1 with updates. To achieve this, assume you copied the Connect-Office365Services.ps1 in the same location as your $profile, for example C:\Users\Michel\Documents\WindowsPowerShell. You can then make PowerShell and ISE call this script by adding the following line to the $profile scripts:
Now when you start a PowerShell session, you might see the following:
This shows the default environment is targeted (AzureCloud), the Exchange Modern Authentication PowerShell module as well as other modules mentioned in the example are installed. When online version checking is enabled (OnlineModuleVersionChecks variable), a check will be performed against the online repository, e.g. PSGallery, and outdated modules will be reported, like the Skype for Business Online module in the example. It’s also possible to automatically update modules setting the variable OnlineModuleAutoUpdate.
When you load the script from ISE, it will show something similar. However, it will also detect ISE and make connect functions available through the Add-On menu:
Notes Customize this script to your liking. For example, by default the script will not perform version checking of installed modules as it slows down loading. In this case, module versions are checked against a built-in ‘last known version’ table. If you want to perform online version checking, look up the line $local:OnlineModuleVersionChecks = $false in the script, and change $false to $true. Automatic updates can be toggled setting local:OnlineModuleAutoUpdate to $true. Note that for updating modules, you need to have administrator permissions on the local system.
Exchange Server 2013 and Exchange Server 2016 enforces certain message size limits when it comes to client messages. These limits are in-place so clients can’t generate excessive load on your Exchange environment. These limits are determined for various access methods in multiple web.config files on Exchange Client Access Servers as well as Mailbox Servers.
Sometimes you may have good reasons to increase those limits. For example, when migrating to Office 365 using a product like MigrationWiz, you may want to increase the limit for Exchange Web Service (EWS) requests to allow for migration of larger items. Another example is when you want to allow for bigger attachments in Outlook WebApp (OWA). On TechNet, there’s an article on how to reconfigure these limits. However, the process consists of editing multiple web.config files, replacing multiple values in the same file, and following this process on each Exchange 2013/2016 server in your environment. This is not only labor intensive and prone to error, but becomes tedious when you consider that each Cumulative Update will overwrite your web.config files.
But do not despair. To execute these changes for OWA and EWS, I have created a PowerShell script which will perform these tasks for you.
Requirements Using the script requires Exchange 2013. You need to provide the server name (default is local server) or AllServers to apply to all Exchange 2013/2016 servers in your environment. The script will modify the web.config remotely using the system share (e.g. C$), using the location of the Exchange installation, and uses IISRESET tool to restart IIS. It will create a backup of the web.config before modifying it.
The script checks for running in elevated administrator mode when running against the local machine.
Current version of the script requires Exchange Management Shell, to run Exchange cmdlets for checking installed roles a.o., as the web.config files which require editing depend on the installed roles.
For OWA, add ~33% to the value you want to specify to compensate for encoding overhead.
When connected to an Exchange server, the script processes the server hosting the EMS session last to prevent abortion caused by IIS reset.
Script currently runs against Exchange 2013 or Exchange 2016.
Usage The script Configure-ClientSizeLimits.ps1 uses the following syntax:
Yesterday was the first day of Ignite, and Exchange fellow Tony Redmond put up a nice summary of the first day, keynoted included, here.
For those not attending Microsoft Ignite, attending different sessions or not able to enter a session because the room was full, Microsoft publishes Ignite sessions on Channel 9. Because you may want to watch sessions offline, some people created scripts to retrieve all session videos and slidedecks.
Here is a slightly modified script, originally from Claus Nielsen, to download all Microsoft Ignite 2015 videos and slidedecks as the become available on Channel9. You can select sessions based on category or speaker, which helps narrowing down the contents offered at Ignite to sessions you are interested in. The script also allows you to download other session videos and decks, for example from Build 2015 or last year’s TechEd NA.
You can download the script from the TechNet Gallery here.
Note: The procedure has changed for Exchange 2016, which can use overrides to make this setting persistent. For these instructions, consult this article.
Anyone who has configured Exchange 2013 IM integration with Lync Server at some point has to modify the web.config file on the Mailbox servers to configure OWA with the proper certificate for enabling IM. Another thing (read: nuisance) is that when you have configured IM integration and you apply a Cumulative Update to Exchange 2013, the web.config will be overwritten, in which case you need to reapply those changes to the web.config file.
This is where the script Configure-IMIntegration.ps1 might come in handy.
Requirements Using the script requires Exchange 2013 and Lync Server. You need to provide the Lync pool and the Mailbox server you want to configure needs to have a valid certificate assigned to IIS (or UM) service. The script will modify the web.config remotely using the system share (e.g. C$), using the location of the Exchange installation, and uses WMI to recycle the OWA Application Pool in IIS. It will create a backup of the web.config before modifying it.
Note that the script does not perform the following steps:
It does not perform the Lync Server parts to configure IM integration, e.g. configure Exchange as a trusted application.
It does not configure Lync Server as an partner application for Exchange (Configure-EnterprisePartnerApplication.ps1).
Usage The script Configure-IMIntegration.ps1 uses the following syntax:
Or, you can quickly configure Mailbox servers and CAS servers for IM integration after performing the required steps to configure the trusted application settings and installing and assigning the certificate for UM:
Anyone sizing for Exchange Server 2013/2016 or even still Exchange Server 2010, using the Server Role Requirements Calculator, has to determine processor requirements at some point. This is accomplished by looking up the SPECint_rate2006 score of the planned processor configuration and matching that against the calculated number of required megacycles by the calculator. To account for fail-over situations, additional overhead needs to be added to the number of megacycles. The process as part of the overall sizing has been explained in detail by Jeff Mealiffe here.
The Exchange consultants’ Swiss army knife when determining SPECint rates is the Exchange Processor Query Tool, an Excel sheet designed by Scott Alexander from Microsoft, which allows you to easily look up and determine the SPECint_rate2006 value by inputting a processor model. While still useful, the tool has been out there since 2011. Also, it would be nice sometimes to see which systems are eligible for a certain sizing specification, rather than validating if the planned processor configuration meets the sizing requirements.
So, I wrote a PowerShell script which can query the SPECint rates for you. Because the rating scores are returned as objects, you can perform additional tasks using PowerShell functionality, such as:
Use additional criteria, such as vendor, min/max number of cores, etc.
Calculate the average SPECint2006 Rate Value for a certain CPU/cores configuration.
You can use the SPECint value calculated by the Server Role Requirements Calculator to find hardware configurations which meet the required total megacycles requirements, optionally including a required overhead percentage.
You can select if you are sizing for Exchange Server 2010 or Exchange Server 2013.
The script requires PowerShell and internet access to query the SPECint database.
The script is called Exchange-PQT.ps1, in honor of the Processor Query Tool (PQT). The syntax is as follows:
The information returned and which you can use for post-processing is: Vendor, System, CPU (processor description), Cores, Chips (number of CPU’s), CoresPerChip (number of Cores per CPU), Speed, Result, Baseline, MCyclesPerCore (megacycles per core), MCyclesTotal (total megacycles), OS and Published. Note that megacycles calculations are based on the selected Exchange version, by default this is Exchange Server 2013.
A quick walk-through on the parameters:
CPU, Vendor or System can be used for partial matching on the respective attribute.
Type specifies what calculation to perform. Possible values are 2010 for Exchange Server 2010 and 2013 for Exchange Server 2013. Default value is 2013.
MinCores/MaxCores/Cores can be used to only return information for systems with less, more or a specific number of cores.
MinChips/MaxChips/Chips can be used to only return information for systems with this more, less or a specific number of CPU’s.
MinMegaCycles can be used to specify a threshold for the total megacycles value for returned items, using the specified Type for calculations.
Overhead can optionally be used to take into account a certain percentage for megacycles overhead. Default is 0 (0%).
Ratio/vCPU can be used to specify the vCPU:pCPU ratio. For example, specify a Ratio of 2 to use a 2:1 vCPU to pCPU ratio. Default is 1 (1:1). Use the vCPU paramete to specify the the number of vCPU allocated.
MinCores/MaxCores and MinChips/MaxChips are mutually exclusive, because we can not specify both in the query against the SPECint database. However, you can use additional filtering on objects returned in the pipeline to distill information, e.g.
To calculate when using a non-1:1 vCPU:pCPU ratio, use Ratio in combination with vCPU. For example, to calculate the average SpecInt rate for 20 core systems with an E5-2670 CPU, using a 2:1 vCPU:pCPU ratio, allocating 12 vCPU cores: