Manage Learn to apply best practices and optimize your operations.

Best practices for preventing buggy Exchange PowerShell scripts

A simple slip of the keyboard is all it takes to accidentally create a buggy PowerShell script. Protect yourself from disaster with these best practices.

There’s no protection from a buggy PowerShell script. In fact, a buggy script can be just as dangerous as a malicious script. While you can implement execution policies to prevent unsigned or downloaded scripts from running, nothing is protecting you from in-house scripts. So how can you avoid making costly mistakes when developing PowerShell your own scripts?

The first step to avoid a buggy PowerShell script is to set up a lab environment to test your script before it runs in production. Although this is a good practice, lab testing isn’t foolproof.

Lab deployments often use different server names, domain names, mailbox names, etc., so scripts that are tested in a lab must be adapted to the production environment before use. That said, adapting the scripts can open them up to errors.

I also recommend building safety mechanisms into your scripts. One that you can use is the -Confirm switch. Appending the -Confirm switch to a PowerShell command forces a script to verify that you want to perform an action before it executes.

For example, if you linked the -Confirm switch to the Move Mailbox command, Exchange would tell you that a specific mailbox is being moved from location A to location B. However, instead of processing the move, Exchange would first confirm that you want to make the move.

It’s also good practice to include the -WhatIf parameter in untested scripts. Adding the -WhatIf parameter to the end of a command instructs Exchange to simulate the command without making any changes to the Exchange organization.

For example, suppose you wanted to enable a journal rule, but were unsure of how the Enable-JournalRule command works. Instead of blindly issuing the command, appending the –WhatIf parameter shows you what will happen if you run the command. It should look like this:

What if: Enabling Journal Rule

Note: Not every cmdlet supports the –WhatIf parameter. For a list of cmdlets that support it, enter the following code:

Get-ExCommand | Where { $_.Definition –Like “*Whatif*” }

Debugging PowerShell scripts
The PowerShell debugger is another way to validate scripts prior to use. To turn on the debugger, enter the Set-PSDebug command. You must run this command before executing the script. Adding a 0, 1 or 2 to the end of the script will start different functions; a 0 turns off debugging, a 1 provides a brief summary of each script line that’s being executed and a 2 provides more details on it. For example, adding a 2 to the end of the command displays assignments as they occur.

While debugging, I recommend that enabling the Step feature, which works similar to the –Confirm switch. The main difference is that you don’t have to modify your code when using this feature.

For example, to enable verbose debugging and step through a sample script, add the –Confirm switch to the end of each line of code. The catch is that this process would take forever if you’re testing a long script. In this case, enter the following command:

Set-PSDebug –Trace 2 –Step

When you run the script, you can see exactly what happens as it unfolds. When the script completes, enter the following command to turn off the debugger:

Step-PSDebug –Trace 0

Brien M. Posey, MCSE, is a seven-time Microsoft MVP for his work with Windows 2000 Server, Exchange Server and IIS. He has served as CIO for a nationwide chain of hospitals and was once in charge of IT security for Fort Knox. For more information visit

Dig Deeper on Exchange Server setup and troubleshooting

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.