Category Archives: 13185

Tips for Connecting to Office 365 using PowerShell in Hybrid Environments

The Office 365 portal and Exchange Admin Console are fairly powerful to allow you to manage your tenant and on-premises environments. But as you are no doubt aware, there are many administrative tasks that require you to use PowerShell.



The sequence you usually find on the web to connect to Office 365 via PowerShell is:

[PS] C:\>$LiveCred = Get-Credential -credential admin@contoso.onmicrosoft.com
[PS] C:\>$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
[PS] C:\>Import-PSSession $Session

If you are in a hybrid environment with Exchange and Office 365 you will discover that both environments have a lot of the same cmdlets, such as Get-Mailbox, Set-DistributionGroup, etc. This causes a conflict when the Office 365 PowerShell cmdlets are loaded within the Exchange Management Shell. You either need to connect to Office 365 PowerShell from a regular PowerShell console (separate window) or you need to use the -AllowClobber parameter, which overwrites the existing EMS cmdlets with the Office 365 versions. This is not ideal if you are working with both on-prem and cloud objects at the same time.

Proxy creation has been skipped for the following command … Use the AllowClobber parameter if you want to shadow existing local commands
I wrote a PowerShell script called Connect-Office365.ps1 that overcomes these conflicts by using the -Prefix parameter with the Import-PSSession cmdlet. The Prefix parameter tells PowerShell to add the specified prefix to all cmdlets it loads from Office 365. For example, if you set the prefix to “cloud” the Get-Mailbox cmdlet for Office 365 becomes Get-cloudMailbox and the Get-Mailbox cmdlet still applies to on-prem. This way you can use both sets of cmdlets in the same EMS console. The script also connects to the MSOLService so you can use the MSOL cmdlets to manage Azure AD.

Connect-Office365.ps1 with “cloud” prefix
Here’s the four line Connect-Office365.ps1 script:
$LiveCred = Get-Credential -credential “admin@contoso.onmicrosoft.com”
 
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection

Import-PSSession $Session -WarningAction SilentlyContinue -Prefix cloud

Connect-MsolService -Credential $LiveCred

I usually copy the script to the C:\Windows folder on my Exchange servers and my management computer so it can be run from any directory whenever I need it.




How to Determine Which Receive Connectors are External Relay Connectors

There are times, particularly during an Exchange migration, when you want to determine which Exchange receive connectors are configured as external relays. External relay receive connectors allow connections (usually from anonymous users) to be relayed to another external domain. When these connectors accept connections from anonymous users they are sometimes called “open relay”connectors. A common use case for this is to allow internal application servers to send emails to external users.



In the course of an Exchange migration, you will usually create new receive connectors on the new Exchange servers that have the same settings as the old Exchange servers. Most of these settings are easy to see and copy, but the ability of a receive connector to perform as an external relay is configured using the ms-Exch-SMTP-Accept-Any-Recipient extended AD permissions which is not so visible.



The following EMS one-liner is useful to determine which receive connectors in the organization are open relay connectors so you can configure the new ones likewise:

Get-ReceiveConnector | Get-ADPermission | Where {$_.User -Like ‘*anon*’ -And $_.ExtendedRights -Like ‘ms-Exch-SMTP-Accept-Any-Recipient’} | ft Identity, User, ExtendedRights

If your existing external relay receive connectors use a specific account rather than anonymous (NT AUTHORITY\ANONYMOUS LOGON) users, change ‘*anon*’ to the specific account name.



See the following articles for more information about Exchange receive connectors:






Fixing Sign-On Name for Renamed Users in Office 365

When using DirSync, the user’s userPrincipalName attribute in Active Directory is used to construct the user name in Office 365. The Office 365 user will use this username to login to Office 365 for OWA, Outlook Anywhere, and ActiveSync for mobile devices, so you’ll usually want this UPN to match Active Directory.



In a recent project I performed a staged migration from Exchange 2003 to Office 365.  There were several users whose names changed over the years due to marriages.  Their pre-Windows 2000 AD logon name was changed as well to reflect their new name.  However, these dirsynced users were getting an Office 365 user name based on their old name from a non-updated userPrincipalName in AD.



For example, here’s what Mary Smith’s user account looks like in Active Directory:



UPN is unchanged from Mary Osgood



Mary has been logging in as contoso\mary.smith ever since she got married and her account was changed.  However, when DirSync was run Mary’s account in Office 365 was set to the UPN, mary.osgood@contoso.onmicrosoft.com. 






You’ll notice that you cannot change the user name field in Office 365 and the display shows, “This user is synchronized with your local Active Directory. Some details can be edited only through your local Active Directory.”



You can change the UPN in AD, but it will not update the user name in Office 365 when DirSync runs. The Office 365 username is configured once during the initial sync and will not be updated.  The only way to change it is by using Windows Azure Active Directory Module for Windows PowerShell.



Login to Windows Azure Active Directory Module for Windows PowerShell with Office 365 administrator credentials and run the following command:

Set-MsolUserPrincipalName -UserPrincipalName mary.osgood@contoso.onmicrosoft.com -NewUserPrincipalName mary.smith@contoso.com

This cmdlet will change the Office 365 user name from mary.osgood@contoso.onmicrosoft.com to mary.smith@contoso.com.  You can change the UPN to any valid domain.


How to Configure Granular Permissions to End Users for Distribution Group Management

Exchange Online in Office 36, Exchange 2013, and Exchange 2010 offer end users the ability to create, edit, and delete Exchange distribution groups in the Global Address List.  This feature is a role assignment called MyDistributionGroups in the User Role’s Default Role Assignment Policy and by default it is not enabled.

User’s Default Role Assignment Policy
If you enable this role by selecting the checkbox and saving the policy, all users can create, edit, and delete distribution groups that they own (the user is listed in the Owners multivalued property of the group).

But what if you only only want users to be able to edit their own distribution groups? Or maybe you want them to only be able to edit and delete their own groups? Or maybe only add and edit their own groups?  The cmdlets below will configure these options for the Default Role Assignment Policy.

Run the following cmdlets in an Exchange Management Shell session:

New-ManagementRole -Name CanEditDistributionGroups -Parent MyDistributionGroups
Remove-ManagementRoleEntry CanEditDistributionGroups\New-DistributionGroup -Confirm:$false
Remove-ManagementRoleEntry CanEditDistributionGroups\Remove-DistributionGroup -Confirm:$false

New-ManagementRole -Name CanCreateDistributionGroups -Parent MyDistributionGroups
Remove-ManagementRoleEntry CanCreateDistributionGroups\Remove-DistributionGroup -Confirm:$false

New-ManagementRole -Name CanRemoveDistributionGroups -Parent MyDistributionGroups
Remove-ManagementRoleEntry CanRemoveDistributionGroups\New-DistributionGroup -Confirm:$false

New-ManagementRoleAssignment -Role CanEditDistributionGroups -Policy “Default Role Assignment Policy”
New-ManagementRoleAssignment -Role CanCreateDistributionGroups -Policy “Default Role Assignment Policy”
New-ManagementRoleAssignment -Role CanRemoveDistributionGroups -Policy “Default Role Assignment Policy”

Once the script completes, you will want to configure the Default Role Assignment Policy in Permissions/User Roles as shown below.  Log into the EAC with Organization Management rights and click Permissions > User Roles and edit the Default Role Assignment Policy.























By default, all three sub-items will be checked.  Clear the checkbox for roles you want to assign and clear the ones you don’t want to give, then click Save. The example above allows all users to edit and remove distribution groups where they are the Owner.  Users are unable to modify or delete groups they do not own.



The checkbox for MyDistributionGroupMembership allows users to add or remove themselves from distribution groups that allow it.



Users can manage distribution groups from the Global Address List in Outlook or from Options > Groups in Outlook Web App.


Inbox Rules Do Not Work on Unity Connections 8.5.1 Messages

I ran into this with a customer recently and wanted to document what I found.  The customer is using Cisco Unity Connections 9.1 for voicemail with Single Inbox and Exchange 2010 SP3.



Cisco’s Single Inbox provides a UM experience similar to Exchange Unified Messaging, where voicemails are delivered to the user’s Inbox as emails with attached WAV files.  The voicemail messages are linked by Unity Connections so that if a user deletes a voicemail in Unity, the email message is also deleted.  Likewise, if the user deletes the voicemail email message in Exchange the voicemail is deleted in Unity.



Unity Connections 8.5.x and later uses Exchange Web Services (EWS) for connectivity to Exchange 2007 and Exchange 2010 mailboxes using a service account.  How Unity programmatically does this is a mystery since it is not documented anywhere in Cisco’s documentation.



The issue here is that the way Unity Connections Single Inbox creates the message in the recipient’s mailbox bypasses the rules table associated with the mailbox.  The result is that rules don’t fire for these messages.  For example, it’s common for users to create an Inbox rule that moves messages from Unity Connections to a custom folder like “Voicemails”.  If you manually run the rule it works as expected.




This issue is documented somewhat in the Cisco Community Forums here: https://supportforums.cisco.com/docs/DOC-17854.  A comment in this forum post implies this is an Exchange bug, but I’ve confirmed that Inbox rules fire correctly when messages are sent via EWS in a normal manner.  Fellow Exchange MCM, Mike Pfeiffer, has a great post on Sending Email with PowerShell and the EWS Managed API.  I used this PowerShell function to send emails using EWS and test Inbox rules, which worked perfectly.



I’ve tried every creative trick I know to work around this issue, to no avail.  In the end, there’s really nothing that can be done to fix this until Cisco changes to the way it sends Single Inbox messages using EWS.


Exchange 2013 Health Check Monitors and Journaling

Exchange 2013 includes built-in health monitors that monitor the health of system resources.  Microsoft calls this new process “Managed Availability”.



The Exchange 2013 Server Health and Performance topic on TechNet says,
“Exchange 2013 introduces the concept of managed availability. Managed availability runs on every Exchange 2013 server. It’s made up of two processes, the Exchange Health Manager Service (MSExchangeHMHost.exe) and the Exchange Health Manager Worker process (MSExchangeHMWorker.exe), and the following asynchronous components:
  • Probe engine   The probe engine takes measurements on the server.
  • Monitoring probe engine   The monitoring probe engine stores the business logic about what constitutes a healthy state. It functions like a pattern recognition engine, looking for patterns and measurements that differ from a healthy state, and then evaluating whether a component or feature is unhealthy.
  • Responder engine   When the responder engine is alerted about an unhealthy component, its first action is to try to recover that component. Managed availability enables multi-stage recovery actions. The first attempt may be to restart the application pool, the second attempt may be to restart the corresponding service, and the third attempt may be to restart the server. And, the final attempt may be to put the server offline, so that it no longer accepts traffic. If all of these actions fail, an alert is sent to the help desk.”

When you install Exchange 2013 it automatically creates several HealthMailbox<guid> objects in Active Directory used by the managed availability service.  There are two health mailboxes that are created for a single mailbox database, one for mailboxes, and one for Public Folders (if deployed).  These hidden mailbox objects can be viewed from EMS by running the following command:

Get-Mailbox -Monitor

Exchange 2013 managed availability uses these HealthMailbox<guid> objects to send emails through Exchange to verify mail flow every 5 minutes.  This causes problems if you’re doing organization-wide journaling in the RTM version of Exchange 2013.  The org-wide Journal Rule will journal all these health probe emails, polluting the journal with thousands of useless messages.

Examples of these journaled health monitor messages are:



Sender: HealthMailboxac09e6fd942f4b40aba364cf2bf34e6b@contoso.com
Subject: MBTSubmission/StoreDriverSubmission/00000047-0000-0000-0000-0000b7145037-MapiSubmitLAMProbe
Message-Id: <2f33c299d6594de9b2ade02dee24e0c9@EX1.contoso.com>
To: HealthMailboxac09e6fd942f4b40aba364cf2bf34e6b@contoso.com

Sender: HealthMailboxc8a6d67ca286431abdf771e24a58093e@contoso.com
Subject: Client submission probe
Message-Id: <70701396-16e9-49ed-9888-11e39257d03e@EX1.contoso.com>
Bcc: HealthMailboxc8a6d67ca286431abdf771e24a58093e@contoso.com

Sender: inboundproxy@inboundproxy.com
Subject: Inbound proxy probe
Message-Id: <20d4e3a7-34a4-4b59-9773-9e1b51328b5a@EX1.contoso.com>
Recipient: HealthMailboxc8a6d67ca286431abdf771e24a58093e@contoso.com



Exchange 2013 Journal Mailbox filled with HealthMailbox* reports


This issue is supposed to be fixed in the first half of 2013, but if you can’t wait that long (who could blame you), here’s a workaround:

  • Add “Ignore” as the value of the ExtensionCustomAttribute1 attribute on each HealthMailbox* object in Active Directory using the following command from the Exchange Management Shell:
Get-Mailbox -Monitoring | Set-Mailbox -ExtensionCustomAttribute1 ‘Ignore’
  • Use the Exchange Management Shell to create a new Dynamic Distribution Group using the following two commands:
New-DynamicDistributionGroup -Name ‘Journaled Users’ -Alias JournaledUsers -RecipientFilter {((((CustomAttribute1 -ne ‘Ignore’) -and (RecipientType -eq ‘UserMailbox’))) -and (-not(Name -like ‘SystemMailbox{*’)) -and (-not(Name -like ‘CAS_{*’)) -and (-not(RecipientTypeDetailsValue -eq ‘MailboxPlan’)) -and (-not(RecipientTypeDetailsValue -eq ‘DiscoveryMailbox’)) -and (-not(RecipientTypeDetailsValue -eq ‘PublicFolderMailbox’)) -and (-not(RecipientTypeDetailsValue -eq ‘ArbitrationMailbox’)))}
Set-DynamicDistributionGroup -HiddenFromAddressListsEnabled $true
  • The commands above create an Exchange Dynamic Distribution Group called Journaled Users that contains all email enabled objects where the ExtensionCustomAttribute1 doesn’t equal Ignore.  It then hides the Dynamic Distribution Group from the Exchange address lists.  Note that users will not see this DDG in the list of groups they are members of.
  • Create a new journal mailbox to hold the journal reports and hide it from Exchange address lists.  In this example, I call it Journal Mailbox.
  • Lastly, create a new Journal Rule that journals all emails for the Journaled Users DDG to a journaling mailbox called Journal All using the following command from EMS:
New-JournalRule -Name ‘Journal All’ -JournalEmailAddress ‘journalmailbox@domain.com’ -Scope ‘Global’ -Enabled $true -Recipient ‘JournaledUsers@domain.com’

It’s important that you don’t update the Dynamic Distribution Group using the Exchange Management Console.  Doing so will update the DDG to a “precanned” RecipientFilter and the HealthMailbox* mailboxes will be journaled.



How to Boot Directly into Desktop with Windows Server 2012




I love Windows Server 2012, I really do.  But who’s bright idea was it to boot to the “Modern UI” (aka, Metro) instead of the Windows Desktop?  There’s really no reason for this, so I wrote a PowerShell script that configures Windows Server 2012 to boot directly into the Desktop after signing in.



This is not a hack.  The script simply changes rights on an existing registry key to allow the value to be changed, and changes it.



NOTE: This script does not work on Windows 8 — It only works on Windows Server 2012.  Early beta builds of Windows 8 allowed you to toggle booting to the Desktop.  Microsoft removed those hacks in the RTM build of Windows 8, sorry.  :(



You may also want to read my article, How to Enable Autologon for Windows Server 2008 Member Servers and Windows 7 Member Workstations.  Those procedures also work for Windows Server 2012 and Windows 8.



Copy and paste the following text into Notepad and save it as BootToDesktop.ps1 on your Windows Server 2012 computer:



#Take Ownership of the “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server” registry key
$definition = @”
using System;
using System.Runtime.InteropServices;
namespace Win32Api
{
    public class NtDll
    {
        [DllImport(“ntdll.dll”, EntryPoint=”RtlAdjustPrivilege”)]
        public static extern int RtlAdjustPrivilege(ulong Privilege, bool Enable, bool CurrentThread, ref bool Enabled);
    }
}
“@
Add-Type -TypeDefinition $definition -PassThru
$bEnabled = $false
$res = [Win32Api.NtDll]::RtlAdjustPrivilege(9, $true, $false, [ref]$bEnabled)
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(“SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server”, [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
$acl = $key.GetAccessControl()
$acl.SetOwner([System.Security.Principal.NTAccount]”Administrators”)
$key.SetAccessControl($acl)

#Give Full Control of the key to BUILTIN\Administrators

$acl = Get-Acl “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server”
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(“BUILTIN\Administrators”,”FullControl”,”Allow”)
$acl.SetAccessRule($rule)
$key.SetAccessControl($acl)
$key.Close()

#Set the value of ClientExperienceEnabled to 0 to enable boot to Desktop

Set-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server” -Name ClientExperienceEnabled -Value 0



Optionally, you can download the BootToDesktop.ps1 script here.



Now simply run the BootToDesktop.ps1 script from an elevated Windows PowerShell prompt and reboot.  The next time you sign in Windows Server 2012 will go straight into the Desktop.



The PowerShell script does three things:

  • It assigns ownership of the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server registry key to the local built-in Administrators group.  By default this key is owned by the protected TrustedInstaller security principal.
  • Full control is given on the key to the built-in Administrators group.  By default built-in Administrators only have Read access.  Full control gives us the ability to change values in the key.
  • Changes the ClientExperienceEnabled value from 1 to 0, which configures Windows to start directly to the Desktop.






Windows Server 2012 and Windows 8 secure protected registry keys and files using the TrustedInstaller security principal.  TrustedInstaller is a core part of Windows Resource Protection (WRP) technology.  Windows usually assigns ownership of WRP protected items to TrustedInstaller and they normally cannot be modified or deleted.  This script overcomes that and allows you to change the value of the ClientExperienceEnabled value.



Since this is really just a simple registry change, you can safely use it in your server imaging process for all your Windows Server 2012 computers.  It only needs to be run once per server and affects all users who logon to that server.

Install and Configure Windows PowerShell Web Access in Three Easy Steps

Windows PowerShell Web Access Gateway Architecture


Windows PowerShell Web Access is a new feature in Windows Server 2012. It is an IIS application that provides a Windows PowerShell console in a web browser. The IIS application acts as a gateway between the web browser and the machines that you can connect to in your environment. These machines should have Windows PowerShell remoting enabled.

There are a number of resources that explain how to configure PowerShell Web Access, including this video.  I want to tell you how to do it in as few steps as possible. 

The following is all done from an elevated PowerShell window of the Windows 2012 server you want to install PWA on.

1.      Install
the Windows PowerShell Web Access feature

Install-WindowsFeature -Name WindowsPowerShellWebAccess -IncludeAllManagementTools


2.      Install
the Web Application in IIS

Install-PswaWebApplication [-UseTestCertificate]
 
Add the -UseTestCertificate  parameter if you don’t already have an SSL certificate installed on the server.  This will install a self-signed SSL certificate that will expire in 90 days.

To use an existing SSL certificate, make sure it is configured in Bindings on the Website to use that certificate.


3.      Configure
Authorization Rules


Add-PswaAuthorizationRule -UserName domain\username -ComputerName * -ConfigurationName *
 

This Authorization Rule will allow the specified account to connect to any computer with any configuration name.

If you are installing on a workgroup server substitute the computer name for domain.



That’s all there is to it! 

You can access Windows PowerShell Web Access from Internet Explore using the following URL: https://servername/pswa

Windows PowerShell Web Access Login

Enter your user name, password, and the computer name you want to connect to and then click Sign In

 


Windows PowerShell Web Access
 

A Windows PowerShell window will open in your IE browser, connected to the computer you targeted.

 

As mentioned above, the target computer must have Windows PowerShell remoting enabled.  You can do this by running the following command from an elevated PowerShell prompt:

 

 Enable-PSRemoting -Force


Exchange 2010 SP2 Roll Up 4 Does Not Install – Error Code 1603

Event 1024 MSiInstaller – Error code 1603




I had an interesting problem installing Exchange 2010 SP2 Update Rollup 4 (UR4) on servers that have never had issues installing updates before.  When I tried to install SP2 UR4 on the Edge Transport or typical installation servers it would rollback the installation and log the following error in the application log:

Product: Microsoft Exchange Server – Update ‘Update Rollup 4 for Exchange Server 2010 Service Pack 2 (KB2706690) 14.2.318.2′ could not be installed. Error code 1603. Windows Installer can create logs to help troubleshoot issues with installing software packages.

Normally this issue us fixed by installing the Update Rollup from an elevated CMD prompt (see http://blog.c7solutions.com/2011/03/exchange-2010-update-rollups-and-error.html), but this time it still wasn’t working.



I enabled MSI Installer logging as per http://go.microsoft.com/fwlink/?LinkId=23127 and dived into the setup logs.  I found the following error being logged in the ServiceControl.log:

[19:51:28] [Error] System.Management.Automation.ParseException: At C:\Program Files\Microsoft\Exchange Server\V14\Scripts\ManageScheduledTask.ps1:462 char:5
+                 return $success
+                 ~~~~~~~~~~~~~~~
Control cannot leave a finally block.
 
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

I examined the ManagedScheduleTask.ps1 script which apparently disables the ‘Database One Copy Alert’ scheduled task, but could not determine what the error is.  I also ran the script from EMS, which returned the same error.  Nothing showed up on the Interwebs other than a few references to PowerShell 3.0, which is not installed on these servers.



I finally resolved it by renaming the ManageScheduledTask.ps1 script to ManageScheduledTask.old and creating a new empty ManageScheduledTask.ps1 script.  The script must exist and return a non-error code when executed for the UR4 installer to work.  I renamed the script back when the installer finished.



This may be an esoteric problem, but I wanted to document it in case anyone else has the same problem.  If this does happen in your environment, please leave a comment below.  Thanks.

Get to know the Test-Message cmdlet

Exchange 2010 includes a little known cmdlet called Test-Message.  This cmdlet is used to troubleshoot the impact of Inbox rules on a message and gather detailed information about how rules are processing it.  It’s also useful for testing the flow of moderated messages and to see the affects of large distribution group expansion without actually sending a message.



The RTM version of Test-Message is documented at http://technet.microsoft.com/en-us/library/dd298101(EXCHG.140).aspx, but there are a couple of additional parameters added in Exchange 2010 SP1 that are not listed there.  The purpose of this article is to show you how to configure the cmdlet and give examples its use.



To use the Test-Message cmdlet, you must add a user account or security group to the “Support Diagnostics” RBAC role in Exchange 2010.  You do this from the Exchange Management Shell by running the following command:



New-ManagementRoleAssignment -Role “Support Diagnostics” -SecurityGroup “Organization Management”



The command above adds the Exchange 2010 Organization Management group to the Support Diagnostics RBAC role.  If you want to add the role to an individual user, use the following command:



New-ManagementRoleAssignment -Role “Support Diagnostics” -User Jeff



Note that the added user must close and restart EMS to see the new cmdlet, since access to cmdlets is granted by RBAC when EMS is started.  You can find out which users have the Support Diagnostics role assigned to them by running the following command:



Get-ManagementRoleAssignment -Role “Support Diagnostics”



Now that we have the access to the Test-Message cmdlet through RBAC, let’s see what we can do with it.  The examples below use the Exchange 2010 SP1 version of the cmdlet, which includes two additional non-documented parameters, -Arbitration (optional) and -InboxRules (required).



The simplest test would be:



Test-Message -Sender amy@contoso.com -Recipients jason@contoso.com -InboxRules:$false -SendReportTo jeff@contoso.com



This test will send a system generated message from Amy’s mailbox to Jason’s mailbox, bypassing Jason’s Inbox rules, and then send the resulting report to Jeff’s mailbox.  The report looks like this:






Here we can see that the message originated from Amy’s Inbox, it evaluated Jeff’s Inbox rules, displays the SCL Junk Threshold, and tells you the target folder for the message after the rules have run.  This is an easy way to troubleshoot messages that are deleted or delivered to another folder other than the Inbox.



It’s important to note that the Sender parameter can be any SMTP email address, even an external address.  This is useful for testing various rule behaviors.



Note that the message also includes two attachments: mailbox-rules.xml and automatic-reply-history.xml.  Mailbox-rules.xml contains an export of all the rules for the target mailbox.  This can be used to backup the Inbox rule set and/or export to another user’s mailbox.  Automatic-reply-history.xml which lists all the recipients where an OOF message fired.



By default, Test-Message adds the header, X-MS-Exchange-Organization-Test-Message: Supress to the message (and yes, “Supress” is mispelled that way).  This header causes Exchange to delete the message before it is delivered to the recipient mailbox.  If you want the message to be delivered to the recipient add the -DeliverMessage parameter.  An Exchange Diagnostic Message will then be delivered with the text, “This message was generated by an Exchange administrator. You can ignore this message, unless your administrator has requested otherwise.



See Tom Kern’s article, Test-Message Improvements in Exchange 2010 Sp1 for even more info on the Test-Message cmdlet.