Exchange Updates Released!

Microsoft has just released Exchange updates!

Exchange updates for 2010

Exchange 2010 Service Pack 3 Rollup 5 resolves various customer updates and includes previously released security bulletins:

  • 2887459 Public folder expiry time is set incorrectly in Exchange Server 2010 SP3
  • 2892257 Email items are lost when you move items between shared folders by using EWS delegate access
  • 2897935 “Cannot save the object ‘\FolderName'” error message when you try to replicate Exchange Server 2010 public folders
  • 2898908 EdgeTransport.exe crashes if the From field is empty in an email message
  • 2903831 Only a single character is allowed in the disclaimer content in ECP
  • 2904459 RPC Client Access service crashes if you add “Signed By” or “Send From” column in Outlook online mode
  • 2913413 RPC Client Access service crashes with an exception in Exchange Server 2010
  • 2913999 Meeting request body and instructions are lost in delegate’s auto-forwarded meeting request
  • 2916836 EdgeTransport.exe crashes when a transport rule sends a rejection message to an empty address
  • 2919513 Memory leak or memory corruption occurs in Exchange Server 2010
  • 2924971 RPC Client Access service stops when you select an inactive search folder in Outlook 2007 in an Exchange Server 2010 SP3 environment
  • 2926057 EdgeTransport.exe crashes if seek operation failed in Exchange Server 2010
  • 2927856 Incorrect recurring meeting if disclaimer transport rule is enabled in Exchange Server 2010

Exchange updates for 2013

Exchange 2013 SP1 improves security and compliance features:

  • Data Loss Preventions (DLP) features are improved.
  • S/MIME back in OWA which will allow OWA users to make use of signed and encrypted messages.

SCOM: Exclude a group of objects from another group of objects

Consider the situation in which you have a group in SCOM with dynamic members and you need to exclude a subset of the membership based on another group with dynamic members. This may occur with a group used for monitoring in a 7×24 environment; some SCOM objects may not need to be monitored, thus needing to be excluded from the 7×24 monitoring group used for alerting.

Kevin Holman’s System Center Blog is the inspiration for this post but here I’ll describe in detail how to exclude SCOM objects as opposed to Windows Computer objects.  There is not a straightforward change in the GUI that can accomplish the goal. The underlying management pack XML must be modified since there is a lack of a Not expression when creating group membership from the GUI.

The steps that must be completed to exclude a group of objects from another group of objects is the following at a high level.

  • Create a new group with dynamic group membership.
  • Put the new group into a new management pack.
  • Create a second group with dynamic group membership and put it into the new management pack.
  • Export and modify the management pack XML to exclude one group of objects from another group of objects.
  • Import the management pack back into SCOM
  • Verify that the changes exclude a group of objects from another group of objects.

For this exercise we will use these groups:

  • Test 7×24 – Contains all production objects.
  • Test Non 7×24 – Contains a subset of the members found in Test 7×24 which may be pre-production or overly chatty objects that require alert tuning.

Create a new group and name it “test 7×24”.

Create a new group in SCOM

Create new management pack, name it “Test Group Exclusion”. Click create to create the management pack.

Create a new management pack in SCOM

Next use the drop down to select “object” and click the Add button.  Then use insert and use “Display name” for the property then use “Contains” for the operator.  Finally enter the unique value of objects within your environment.  This example will include all objects with DN1, DN2, DN3, or DN4 which coincide with Exchange 2010 DAG node mailbox servers.  The last thing to do is to switch to using OR group by right clicking the text “AND group for Object (all of these are true)” and select “Switch to OR Group”.  Below is screenshot of what the group will look like before the XML file is edited.

Set up dynamic membership for group

Create a second group and name it “Test Non 7×24”. Select the same management pack that was created earlier which was named “Test Group Exclusion”.

On the Dynamic Members configuration click the create/edit rules and specify “Object”. Using the same setup as above in the Test 7×24 group, specify a subset of members.  For simplicity this example specifies DN1 and will be used to exclude these objects from the Test 7×24 group.  Finalize creating the groups by clicking through the remaining steps of the wizard.  Below is screenshot of what the group will look like before the XML file is edited.

Create a new group in SCOM

In the navigation pane select administration and then select management packs.  Locate the newly created management pack and export it.

Edit the management pack and identify the element ID for each group.  These are located at the very end of the file:

Use the element ID for Test 7×24 to find the line with a matching GroupInstanceID:

The first instance of an expression below this must be modified to include an AND expression.



Additionally at the bottom of the same list of regular expressions the group to exclude is inserted with a NotContained expression.  The NotContained section must include the element ID of the group of objects that will be excluded from the 7×24 group.



Save the changes and import the management pack.  If you have made any errors the management pack import process will show an error and will fail on import.

Now it is time to review the groups after the changes made to the management pack. Switch to the Administration view in the navigation pane and display the properties of the Test Non 7×24 group and click the create/edit rules button on the dynamic members tab.  The default behavior is to use an AND group and you’ll notice that even though initially an OR group was used; the logic has reverted to default.  If you use additional expressions be sure to switch the logic to OR group otherwise the dynamic membership will not work, you’ll not have any group members.

Group default is to use AND group

Confirm that the Test Non 7×24 group contains the objects that should be excluded in the Test 7×24 group membership.  To verify the group membership right click on the Test Non 7×24 group and select View Group Members…

Next display the properties of the Test 7×24 group and view the dynamic members tab and click the create/edit rules.  There will be an error displayed for an unhandled exception which is related to the NotContained expression inserted into the management pack.

Expression causes error on SCOM group

Click continue on the error message to view the dynamic members query.  The query now contains an AND group as well as an OR group.  The last expression within the OR group will be blank, do not delete it.  This blank expression in the GUI represents the NotContained expression inserted into the management pack.

exclude a group of objects from another group of objects

Finally, confirm that the Test 7×24 group membership does not contain the objects that are members of the Test Non 7×24 group (the membership can take some time to update). To verify the group membership right click on the Test 7×24 group and select View Group Members…

If you have done everything correctly the group members in Test Non 7×24 should not be found in the Test 7×24 group.

The Importance of PowerShell Training

It is hard to argue that the based of knowledge created around PowerShell over the years has been something of a grass roots movement.  Don Jones, a well known author and expert on PowerShell, recently wrote an article for Redmond Magazine aimed at the IT decision maker.  He states the importance of Powershell training and that professional training for administrators is a must-have.  Even though the article is geared towards the IT decision maker within an organization,  there are some obvious take aways for the IT professional.  The point of the article, in his own words, of course is the following:

The moral of the story, of course, is to get your people trained.

He takes it a bit further by saying:

Find your best and brightest, the ones who can become your Automation Makers….You don’t need to train the entire team; the enterprise pattern is shaping up as having a relatively small number of bright, adaptable IT folks taking on the role of PowerShell Wrangler.

Read moreThe Importance of PowerShell Training

Seed an Exchange 2010 DAG database locally

If you have an Exchange 2010 DAG deployment it is very likely that you have multiple datacenters for disaster recovery scenarios.  You may find that you need to reseed a DAG database but since bandwidth is at a premium between sites, what can you do?  If you have multiple copies of a database in the same datacenter, the best scenario is to seed an Exchange 2010 DAG database locally.

Consider this situation:  You have  two DAG nodes in you DR site and one of them requires a hardware replacement.  It is possible to create another copy of the database on the other node in the same datacenter using the local database copy as the source.  Using this method you are able to preserve the database copies in the secondary datacenter.  When the hardware is replaced and the DAG node is functional, you can seed the database copies back to the original DAG node.    The following PowerShell commands should be used to seed an Exchange 2010 DAG database locally.  Let’s assume that you have ExSvr1 and ExSvr2 in the secondary datacenter.  Each holds a database copy from servers in the primary datacenter.  You must create a copy of DB01 on ExSrv2 before shutting down ExSvr1.

Create a new database copy on ExSvr2.  Use the database name as the identity and set the mailbox server where this copy will live.  Also set the activation preference and postpone the seeding.

Once the PowerShell command completes you will receive the following warning.
WARNING: Replication is suspended for database copy ‘DB01’ because the database copy needs to be seeded.

The next step is to begin the seed process by using the -SourceServer switch and specifying ExSvr1 which is currently hosting the database copy in the secondary datacenter.

Here is a link to the official Microsoft Exchange 2010 documentation on the Update-MailboxDatabaseCopy which provides an example on how to seed an Exchange 2010 DAG database locally using the -SourceServer switch.

WSUS Reporting with Powershell Part 3

Edit: Find the complete script here.

This is the final installation that concludes WSUS reporting with PowerShell.  In part 1 I explained the basics of connecting to WSUS with PowerShell and making a few basic queries.  In Part 2 I covered using a specific group in WSUS and creating a summary of the updates that those group members needed.  In this post I’ll explain the following:

  • Filter the results to trim down the report.
  • Use HTML formatting to prepare an email.
  • Send the report via an HTML formatted email.

An example of the WSUS Reporting HTML email output is below:

WSUS Reporting HTML Email

WSUS Reporting with Powershell Part 2

Edit: Find the complete script here.

In my previous post I provided the basics of connecting to WSUS with PowerShell and making a few basic queries that will be used in a WSUS reporting script.  This is the second post about WSUS reporting and covers how to query a group in WSUS and provide a summary of computers that need updates from the most recent synchronization.

This script will provide an output in PowerShell but it is intended to be used in conjunction with an email alert.  The report has a very nice feature that takes the needed updates and converts them into a hyperlink with the text being the KB article number.

The result of the $SummaryStatus variable with the select-object filters above results in the following:

WSUS Reporting

The final section of this series involves filtering the returned data a little further and then using some HTML formatting to send an acceptable looking report.

WSUS Reporting with Powershell Part 1

Edit: Find the complete script here.

If you have ever used WSUS for pushing Microsoft patches then you’ll know that getting a quick report of the patching status can be cumbersome. This is the first post about WSUS reporting that will lay out the basics of using PowerShell to connect to WSUS and make some queries about the status of your environment. In this post I will explain the following.

  • How to load the WSUS assembly.
  • Make a connection to WSUS.
  • Create a computer scope and update scope, which is needed for making queries.
  • Generate a few basic queries that will be used in the WSUS reporting script.

The very first thing that must be done is to load the WSUS assembly.

The next thing to do is to make a connection to WSUS and set the connection into a variable for future use. At the end of the command substitute the WSUS server name, use $true to force a connection via SSL and finally enter the port number.

In order to make some queries within WSUS we’ll be using the GetSummariesPerComputerTarget method. This method requires a computer scope and additionally we will be using an update scope to refine the query. First create a default update scope and then modify it only include the latest approved revisions.

Next create the computer scope, no need to make a modification.

Now that we have this bit established we can take a look at a few things. Run the following to return the groups that you have established in the WSUS console:

Taking things a step further let’s identify one of the group ids and use Where-Object to filter a specific group and set it into a variable. Then enumerate all the members of the group:

You will now have detailed information about each computer object that is a member of your WSUS group stored in the $MemberOfGroup variable.  We’ll use this in the next section two find out what updates are needed for the members of this group and build upon the WSUS reporting script.

PowerShell Registry Update File MRU and Place MRU

Recently, as part of a data migration project and in an effort to create a seamless user experience in Microsoft Office, the recent documents and recent places needed to be updated with a new server name.  This prevented any users from using this Office feature and having problems.

Using PowerShell to make updates to the File MRU and Place MRU accomplishes this goal.


Redistribute Mailboxes Across an Exchange 2010 DAG

I have put together a script to redistribute mailboxes across an Exchange 2010 DAG and wanted to share my work with the Exchange community.  Over time some of the databases in an Exchange 2010 DAG  will have an uneven distribution of mailboxes.  The script in this post automates the assignment of mailboxes for redistribution based on a couple of criteria, standard mailbox count, large mailbox count and total mailbox count.  These definition of standard and large mailbox sizes are different in just about every environment.  Therefore, I’m making the assumption that if a mailbox in your environment is using the default database quotas, it is a standard mailbox.  Otherwise, the mailbox is not using the default database quotas and has a different, larger quota that is uniform across the board.  The high level steps are:

  • Gather all DAG databases.
  • Gather mailboxes on each database and categorize as standard or large.
  • Make calculations about each mailbox type per DAG database so that we can get accurate tallies and then evenly redistribute mailboxes.
  • Make new-moverequest assignments and track the changes that will occur on the mailbox count per database
  • Initiate the new-moverequest for mailboxes selected.

This script will require the Exchange 2010 snapin.

Set a variable for the new-moverequest batch name.

Get the databases within the DAG but skip recovery databases. Hopefully this makes the database gather process as generic as possible.

We’ll use $DBCountArray for tracking the mailbox count on each database. $MBXArray will be used to store every mailbox in your organization and leveraged to make each new-moverequest.

In this next code block we are taking each DAG database and then enumerating the mailboxes it contains.  This will take some time to execute so a progress bar is helpful here.  There are two variables used as counters (line 15 and 16) which are set to zero.  In the second foreach loop the script examines the current mailbox and determines if it is standard or large based on it using default database quotas or not.  The MBXObject variable records basic data about the mailbox and puts this data into the MBXArray.  At the end of the first foreach loop the script records each mailbox processed and tallies the count for each database.

We now take the $DBCountArray and pipe the collected counts to measure-object to get an average number for each of the three attributes; totalmailboxes, largemailbox, and standardmailbox.  Secondly use [Math] in order to round the averages to a whole number.

We’ll use all the calculated variables to continue building out what the database counts are within $DBCountArray.

In this block the script matches the current database in the foreach loop with where-object and makes a calculation on each criteria by subtracting the average value from the total value and adding the property to the $DBCountArray.  This lets us know where each database is in relation to the average.  The calculated number will be positive integer, negative integer, or will be zero.  This will be the basis on which database to move mailboxes from and where to move them to.

This section handles new-moverequest assignments for large mailboxes and tracking the database counts for each large mailbox.  The source databases are selected by sorting the totmbxdiff property using the descending switch.  Selecting the first one will always grab the database in the list that is farthest out of skew from the computed average.  I’ve devised a non elegant way to add and subtract each property in the array.  By using the do until code block the script nulls out the source and target during each iteration and will continue until either to source or target databases have reached zero, or in other words, until it runs out of mailboxes to move or a place to move them to.

This next section of code is rinse and repeat for the standard mailboxes.

If you have made it this far then take a peek at what has been generated in the $DBCountArray

Taking a look at the contents of the $MBXArray you will see something similar.  This example list shows standard mailboxes but the mailboxes are not assigned a database for a move request.  The $MBXArray will be used with the new-moverequest cmdlet to direct mailboxes to their new databases.

The final step is to initiate the new-move request.  This is accomplished by taking the $MBXArray and trimming out any mailboxes without the moverequest property populated using where-object.  The $MoveRequest variable contains all the mailboxes that will be moved so simply pipe that variable into a ForEach loop that creates a new move request.

Here is the script in it’s entirety:

PowerShell Try Catch Finally Error Handling

I’ve recently been experimenting with the script blocks in PowerShell try catch finally.  These script blocks can help you deal with terminating errors that may occur in your scripts.  A terminating error, otherwise known as an exception, will stop a command from processing the current object or from processing additional objects.  On the other hand, there are many situations that will result in a non-terminating error.  In a non-terminating error situation an error will generally be displayed on the console and continue processing.  An example of a non-terminating error is passing a variable containing a list of mailboxes to the Get-Mailbox cmdlet.  If an error occurs matching a name in the variable to an Exchange mailbox, the process continues but an error is displayed to the console.  A good resource for determining what exactly constitutes a terminating error or non-terminating error can be found in this MSDN article. This is where the script blocks try catch finally can be helpful. The try block is where you will put the code that you want to execute and monitor for errors.  If an error occurs then the code in the catch block is executed.  It is possible to include multiple catch blocks in order to catch certain types of errors.  The finally block runs no matter what happens during the try and catch script blocks.  The finally block can be used to provide informational output gather from a script or free up resources, per Microsoft’s documentation.  You may even choose to omit the finally block as part of your script if you don’t feel that it is necessary.

So if you are using the try catch finally blocks and have non-terminating errors within the try block, the catch block ignores the errors and does not fire.  It is possible to force any error in the try block by using the -ErrorAction switch.  Setting the error action to stop forces the catch block to see all errors, either terminating or non-terminating.

You’ll notice in the catch block that I’m using the $Error variable. This is where PowerShell stores all the errors for a given session.  Using [0] after the $Error variable denotes accessing the first time in a PowerShell array so we’ll be returning the most recent error in $Error.  Just for the sake of the example, the finally block unloads the Exchange 2010 PowerShell snapin.

Ok so this script is reinventing the wheel a bit but the try catch finally script blocks are extremely useful for handling terminating errors or when you want to trap non-terminating errors in your code.