IT/DEV Connections 2015 Wrap-Up

imageNote: For those that attended Jaap and my workshop on Monday, Managing Exchange On-Premises and Exchange Online using PowerShell, the slidedeck is available here and the sample code is available here.

Last weekend, I returned from one of the largest, independent conferences on Microsoft technologies, IT/DEV Connections. The conference, which took place in the city of Las Vegas, is spread over a 3-day period on popular topics, like Exchange, Windows, SQL or SharePoint, and has a track for Infrastructure as well as Development (hence the ‘IT/DEV’). Apart from the many speakers, most of them experienced Microsoft Valuable Professionals, Microsoft celebrities like Tim McMichael were also presenting sessions.

Like many conferences nowadays, IT/DEV Connections took off with several pre-conference workshops on Monday. One of these workshops was done by fellow Exchange MVP and countryman Jaap Wesselius and myself. We talked a whole day about ‘Managing Exchange On-Premises and Exchange Online using PowerShell’. The turn-up was above expectation, which is always nice, and we had good interaction with, and feedback from the audience. This made our session, from a presenter’s viewpoint, very worthwhile.

imageSince I had no sessions after the workshop, I was free to attend sessions by fellow presenters. Tony Redmond kicked off with a keynote, analyzing the current landscape for Exchange and Office 365, and making references to sessions later that week, should people be interested in those topics. It’s also where you learn who is running what, and as it turned out most attendees are running Exchange 2010 or Exchange 2013 On-Premises, but with an increasing interest in Office 365.

During the week, apart from the excellent contents presented, I was very humbled to learn lots of presenters made references to several of my scripts, e.g.

This conference is also the place where Exchange MVP fellows Tony Redmond, Michael van Horenbeeck, Paul Cunningham and Jeff Guillet presented their 2nd edition of their book, ‘Office 365 for Exchange Professionals’.  Congratulations to them reaching this milestone, looking at the non-stop amount of changes happening in the Office 365 environment. You can get your own copy of the updated book here.

It’s becoming a tradition that the last Exchange session of the conference is a ‘Ask the Experts’ panel session, where the audience can ask a panel of presenters questions, or where the current landscape for Exchange or Office 365 can be discussed. It’s a great way to close the conference, before everyone gets back to their corners of the world, back from the crazy city that is Las Vegas to reality.

imageIf you didn’t consider IT/DEV Connections before, you should. The conference is a must-visit, especially with Microsoft having consolidated MEC, MMS etc. in a single, huge event which is Ignite now. Connections is not small, but the more intimate setting allows you to catch up with peers more easily, have discussions over a pint, great catering, and without the need to max out your step counter. The Aria resort is very nice place to host this event, great for business with a pleasant conference area without too much of the distractions like the other hotels. If you plan on visiting next year, save the date: September 19-22, 2016!

I also want to thank ENow for again hosting an epic Scheduled Maintenance party. Location this time was the Ghostbar at the 55th floor in Palms Resort, which gave an amazing view over the city of Las Vegas and the Strip. I wore my ENow-branded NFL jersey to the party, a gift from ENow last year. This lead to funny moments, as this is ENow’s event gear, and many people mistook me for an employee, thanking me when leaving the party.

Finally, here are some of the other Exchange Connections wrap-ups:

IT/Dev Connections 2015

imspeakingatdevconnections[1]I am in Las Vegas at the moment for the IT/DEV Connections conference which will take place in Las Vegas this week. Looking at the schedule and list of speakers, the conference is bound to be a success. If you’re not in Las Vegas, you can follow the conference on Twitter. The designated hashtag is #ITDEVCON.

itdevconMany thanks to Penton Media for giving me the opportunity to co-host the “Managing Exchange On-Premises and Exchange Online with PowerShell” workshop in the Enterprise Collaboration with Jaap Wesselius, on September 14th in Bluethorn 4. I will be present at the conference the whole week, so if you have questions or just want to say hi, look me up or ping me on Twitter or e-mail.

Client Message Size Limits

powershellLast Update: Version 1.2, February 15th, 2017

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.

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.


  1. The script checks for running in elevated administrator mode when running against the local machine.
  2. 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.
  3. For OWA, add ~33% to the value you want to specify to compensate for encoding overhead.
  4. When connected to an Exchange server, the script processes the server hosting the EMS session last to prevent abortion caused by IIS reset.
  5. Script currently runs against Exchange 2013 or Exchange 2016.

The script Configure-ClientSizeLimits.ps1 uses the following syntax:

.\Configure-ClientSizeLimits.ps1 [-Server |-AllServers] [-OWA <size>] [-EWS <size>] [-EAS <size>] [-Reset] [-NoBackup] 

A quick walk-through on the parameters and switches:

  • Server specifies the server to configure. When omitted, it will configure the local server. This parameter is mutually exclusive with AllServers.
  • AllServers switch specifies to configure all Exchange 2013 servers. This switch is mutually exclusive with Server.
  • OWA configures the message size limit for Outlook Web Access. Value is in bytes.
  • EWS configures the message size limit for Exchange Web Services. Value is in bytes.
  • EAS configures the message size limit for Exchange ActiveSync. Value is in bytes.
  • NoBackup tells the script not to make backup copies of modified web.config files.
  • Reset switch specifies to perform an IISRESET against servers after reconfiguration of client-specific message size limits.

So, suppose you want to configure OWA, EWS and EAS client message size limits on the local Exchange server, you can use:

.\Configure-ClientSizeLimits.ps1 -OWA 15MB -EWS 15MB EAS 15MB


If you want to configure EWS limits for all servers, resetting IIS, you could use:

.\Configure-ClientSizeLimits.ps1 -AllServers -EWS 10240 -Reset

You can download the script from the TechNet Gallery here.

Feedback is welcomed through the comments. If you got scripting suggestions or questions, do not hesitate using the contact form.

See TechNet Gallery page.

To Do
Compatibility with Exchange 2010 and removal of dependency on Exchange Management Shell.

Why Exchange Admins should learn PowerShell

techtarget_logoAs some of you may or may not be aware of, recently I have joined the ranks of Exchange and The UC Architects fellows Michael van Horenbeeck and Steve Goodman and started writing for the Exchange section at TechTarget.

The first two articles are a call to action for Exchange admins to start working on their PowerShell skills if they have not already done so. Learning can take the more academic approach, starting from scratch and learning the basics topic by topic, or a more practical one by reading and getting to understand existing scripts which may suit the more time-constrained admin.

Read the full articles here and the follow-up article here.

If you got topic suggestions, use the contact form or send me an e-mail.

Regular Expressions and Named Groups

powershellWhen processing strings, you may sometimes need to split those strings into several parts based on criteria. For example, you may need to split the ActiveSync DeviceUserAgent string, which can be used to identify the model and version of a device, for example:

  • Apple-iPhone4C1/1002.142
  • Apple-iPad2C1/1002.141
  • Apple-iPhone4C1/1001.523

Now let’s assume you want to take this string apart in the device model and the version, using the slash as a marker. When asking 10 people, a majority will come up with something along the following kind of structure:

$pos= ($Device.DeviceUserAgent).IndexOf("/")+1
$Device= ($Device.DeviceUserAgent).Substring(0, $pos)
$Version= ($Device.DeviceUserAgent).Substring($pos+1)

Of course, this works but you need to understand what’s going on and additional code is required the handle situations when there’s no “/” present. Perhaps a more elegant and readable way, especially if you want to split the string in more than 2 parts, is using regular expressions to perform pattern matching. When used in combination with named groups, you will get easily referable parts using a name.

For the purpose of demonstrating it’s power, we’ll start by assigning some user agent strings to a variable. Note that you could use the DeviceUserAgent property of a collection of ActiveSync devices as well.

$UserAgents=@("Apple-iPhone4C1/1001.523", "Apple-iPhone3C1/801.293")


The pattern to look for in each user agent string is it starts with some characters, followed by a slash, followed by a number, followed by a dot and ending in a number. Translated to regular expression, the pattern would be:



  • ^ marks the start of the subject;
  • (.*) marks a sub pattern of any character, the * indicates it’s present zero, one or more times;
  • The slash is marked by (surprise!) a /;
  • (\d+) marks a sub pattern of decimal digit, the + indicates it’s used one or more times;
  • \. will match the dot (escaping it with “\” makes sure next character is used literally as ‘dot’ normally means any character);
  • $ marks the end of the subject.

When matching a pattern against a string you can use –match, e.g. “string” –match “pattern”. When this results in True, a match is found; when the result is False, the format of the string is invalid (of course requires properly defined pattern). After performing a match, the predefined variable $matches will contain an array containing the results, where element [0] contains the complete matching string and [1] .. [n] each matching (sub) pattern.


You see that each match returns True (match found) and $matches[1] for example contains the first sub pattern for each match, i.e. the device. This is nice and perhaps neater than splitting strings as mentioned in the start of this article, but wouldn’t it be even cooler if you can refer to those parts using names, e.g. device?

Here’s where named groups come into play and you can compare it to PowerShell’s calculated properties (select @{Name=”KB”; Expression={$_.Size/1kb}}) or column aliases in SQL (SELECT ColA as Name). To use named groups, put “?<name>” at the start of the (sub) pattern. For example, to use the name “device” for the first sub pattern “(.*)”, the expression would become “(?<device>.*)”. The complete pattern using named groups would then become something like:


The cmdlet for this example would then become:

$UserAgents | ForEach { [void]($_ -match "^(?<device>.*)/(?<major>\d+)\.(?<minor>\d+)$"); $matches }

Which will give the following results:


Note that I’ve added casting (i.e. converting a variable to a different type) the output of “-match” to [void] so the match results (True or False) won’t be part of the output.

Having named groups now allows us to use easily match individual parts, filter or group information, e.g.:

$UserAgents | ForEach {
    [void]($_ -match "^(?<device>.*)/(?<major>\d+)\.(?<minor>\d+)$")
    If( $matches.major –gt 800) { 
        echo $matches[0]

Of course it’s a matter of taste, but having this information available as $matches.device instead of $matches[1] makes introducing changes more easy (no need to renumber when inserting/removing a sub pattern) and results in more readable code.

NGN Exchange Event, Tips & Tricks Presentation

On October 31st, the NGN – a Dutch society for IT professionals – held its 3rd Exchange themed event, this time at The Reehorst in Ede (NL). Because of the recently released Exchange 2013 and all the news and related questions, we planned for a whole day of sessions and it was nice to see the turn up was nearly 100 IT professionals.

Since all people would still be on pre-2013 versions of Exchange, I figured a presentation using real-world Exchange 2010 Tips and Tricks might be more appropriate. I was glad a quick poll amongst the attendees showed a significant increase in Exchange 2010 deployments (around 80%) when compared to last year’s event, but as expected there’s still some Exchange 2007 and few Exchange 2003 out there.

I decided to stick with two deep-dive topics, which were Message Trackings Logs and Cmdlet Extension Agents. On those topics I went from basics to more advanced examples, hoping it would ignite people with no experience and people with experience could still pick up a thing or two.I’m still waiting for evaluation results, the only way to get feedback from these sessions apart from the occasional e-mail or tweet.

(picture by Dave Stork)

You can find my presentation here (partially Dutch) and the accompanying sample script on Message Tracking Logs here and the one on Cmdlet Extension Agents here (script); the ScriptingAgent.xml file can be downloaded here.

As always, these events are also a time to catch up with fellow Exchange people and discuss topics with attendees during the breaks. There were even Exchange fellows present who didn’t have a session, like Johan Veldhuis (MVP) and Maarten Piederiet (MCM); they did join in on the Q&A Panel.

The sessions and speakers were:

  • Introduction (Jaap Wesselius, MVP)
  • Building with Exchange 2013: Architecture (Dave Stork)
  • Exchange and Virtualisation (Jetze Mellema)
  • Exchange 2010 Tips & Tricks (Ashley Flentge, MCM & Michel de Rooij)
  • Exchange 2013 Coexistence and Migrations (Kay Sellenrode, MCM and MCA)
  • Exchange and Load Balancing (Jetze Mellema)
  • Q&A Panel

The NGN published all presentations in a single ZIP file which can be downloaded here. Unfortunately, NGN didn’t record the sessions so I can’t share those with you. They did record the Q&A Panel session; you can view it here (in Dutch):

PS: When you see references to “exchangedag”, like in the Twitter hashtag, you need to know “dag” means day in Dutch; it’s no form of professional deformation.

Adding Exchange Shell items to PowerShell ISE

I’ve become a fan of using the PowerShell Integrated Scripting Environment (PowerShell ISE) for creating, testing and debugging scripts, using breakpoints and step-by-step execution; features found in many development environments. Depending on the script I’m working on and for what customer or environment, I may need to add snap-ins or switch contexts, like connecting to Exchange Online.

One of the powerful features of ISE is that it allows customizing through the ISE object model. For example, you can explore ISE through the $psise object:


To add custom menu options to ISE, we’re going to add items to the submenu of $psISE.CurrentPowerShellTab.AddOnsMenu, which is “Add-ons”. An item needs to consist of:

  • Display Name, which is used for displaying the menu item;
  • Action, which can be a PowerShell cmdlet, scriptblock or function;
  • Optionally, you can assign a keyboard shortcut to the menu option.

To automatically load the custom entries after starting up ISE, we’re going to define the entries in our default ISE profile file, Microsoft.PowerShellISE_profile.ps1, which location is stored in $profile. The file doesn’t exist by default, so when required you can simply create the file in the proper location using notepad $profile.

In our example, we’ll add three entries:

  • Implicit Remoting to connect to Exchange using a static FQDN;
  • Loading the Exchange 2010 Snap-in and connecting to Exchange using Autodiscover (unsupported, will bypass RBAC);
  • Connecting to Exchange Online.

Note that the example won’t be using stored credentials and will let ISE prompt the user for credentials when required, which is perfectly fine if you need to access different Office 365 tenants for example.

Now, in the Microsoft.PowerShellISE_profile.ps1 file, add the following contents:

    "Connect to Exchange @ Contoso", {
        $ExSession= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Authentication Kerberos
        Import-PSSession $ExSession
    "Connect to Exchange On-Premise", {
        Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
        . $env:ExchangeInstallPath\bin\RemoteExchange.ps1
        Connect-ExchangeServer –auto
    "Connect to Exchange Online", {
        $o365Cred= Get-Credential
        $o365Session= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $o365Cred -Authentication Basic -AllowRedirection
        Import-PSSession $o365Session

After starting ISE you’ll see the Add-ons menu now contains three extra items:


When selecting “Connect to Exchange Online” (or pressing the configured keyboard shortcut), ISE will execute the associated code block; the progress is displayed in the output window. You will be prompted for credentials after which ISE will connect to Exchange Online and import the remote session.


After the session has been imported, you have the additional commands at your disposal in ISE and you can work on your scripts since they’ll be running in the context of the environment you’ve connected to.

Of course, this is just an example of what you can customize in ISE (pink background anyone?). For more information on customizing PowerShell ISE check here. If you’re new to PowerShell ISE, check here.

TechEd North America 2012 sessions

With the TechEd North America 2012 event still running, recordings and slide decks of finished sessions are becoming available online. Here’s an overview of the Exchange-related sessions:

Exchange & PowerShell Presentation (Dutch)

After last years NGN Exchange event, where I presented a session on Exchange Autodiscover,  it was time for a followup. This event took place on May 19th and had a turn up of about 80 attendees, which was better than expected given the fact this was a non-free NGN event unlike last year. Early questions indicated large part of the attendees are still on Exchange 2003, though the figure has dropped a bit from last year’s 80%.

I held a duo-presentation with Maarten Piederiet on the topic PowerShell and the Exchange 2003 Administrator. A fingers up poll also showed lots of people still working with batchfiles, VBScript or KiXtart. This was expected, so our topic was spot on since we included PowerShell primer topics. Of course, this 45 minute session doesn’t replace a proper PowerShell course, let alone a course for decent development skills but our goal was to get people enthusiastic by demonstrating how simple yet powerful PowerShell is.

Besides presenting, which went a lot better than last year on a side note, it was also a time to catch up with fellow Exchange MVPs and enjoy discussions with attendees during the Ask The Expert breaks.

Below you’ll find the presenters’ slidedecks in PDF format. Note that the presentations are in Dutch.

Unfortunately, NGN decided not to publish the recorded sessions so I can’t share those with you.

Remote PowerShell to Office 365

imageWhile trying Office 365 you might want to connect your to a remote Exchange Management Shell session instead of using the portal interface. Here’s how to proceed.

Start up a PowerShell session. The first thing we’re going to do next is store credentials in a variable for later usage:

$cred= Get-Credential

A popup will be displayed where you can enter your Office 365 admin credentials, e.g.

Next, create a new remote PowerShell session using the following cmdlet:

$o365= New-PsSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -AllowRedirection -Authentication Basic


Next, we can import the session. However, this might be confusing since you have no context; are you creating a mailbox local or in the Office 365 environment?

The cool thing is that with Import-Session you can specify a prefix. This prefix can be specified before the cmdlet noun so that PowerShell knows which session you want the cmdlet to run against. As you probably know, cmdlets are normally constructed using <verb>-<noun> syntax, but this should be <verb>-<session prefix><noun>. When the session prefix is omitted, PowerShell assumes the current session.

For example, let’s import our Office 365 session with a prefix of “o365”:

Import-PsSession $o365 –Prefix o365


Now, we can use that “o365” prefix before the noun. For example, to get a list of our Office 365 mailboxes, you’d use something like:



Cool and simple, eh?

Don’t forget to close your online session afterwards using:

Remove-PsSession $o365

Have fun exploring Office 365 using PowerShell.