PowerShell Tip #5

This week’s Tip of the Week article will concentrate on general troubleshooting of PowerShell scripts. In our troubleshooting process we’ll look at a real world example of script building and how to troubleshoot issues that arise while building this script. Of course the troubleshooting methodologies shown in this article are only one way to do this and there could of course be other ways to troubleshoot a production script. The thought of the methods here is to expose someone to some potential methods of troubleshooting PowerShell scripts in production.

For this example we’ll use a scenario where a company is moving a large number of users to Office 365. This requires some monitoring of the migration batches and reporting this potential on an automatic or at least periodic basis. Let’s review the basic cmdlets for checking on Migration Batches for Exchange Online.

In the script we want to track the progress of each migration user who is moving to Exchange Online. This requires us to look at each batch and several properties of those batches. What we also find is that if we have a large enough number of batches or users migrating we get timeouts and micro delays when connecting to Exchange Online. How to we troubleshoot this first issue? Well, we can split up our queries , put in some start-sleep cmdlets to pause our check or possibly close and reopen PS connections to Exchange Online for additional queries.
For the first troubleshooting method, splitting up the queries, we first need the list of batches:
[sourcecode language=”powershell”]
$BatchIDs = ((Get-MigrationBatch).Identity).Name
[/sourcecode]
Then when we have the batches, we can then run through each batch and gather stats:
[sourcecode language=”powershell”]
Foreach ($BatchId in $BatchIDs) {
#Gather Move Stats
$Mailboxes = Get-MigrationUser -BatchId $BatchId | Get-MigrationUserStatistics | select-object Identity, BytesTransferred, EstimatedTotalTransferSize, SyncedItemCount, TotalItemsInSourceMailboxCount, PercentageComplete
$Mailboxes | Out-file $Destination2 -Append
}
[/sourcecode]
Now, if we get a batch that fails, we can possible:

(1) Add a Try {} Catch sequence to catch error messages
(2) Or we can also run the cmdlet manually to see the errors that occur.
Once that error is resolved we can go back to writing our script. Some other items we can:
(1) Use a Transcript (Start-Transcript)
(2) Use the Tee-Object cmdlet if we are running the cmdlet live and also want to log what is going on.

Additionally, if running this interactively we can add Write-Host cmdlets to provide markers as to where the script is executing and failing or the same output can be dumped to a debug log for analysis later.

The last option we’ll mention in this article is to break up the script. Breaking it up into smaller fully function pieces may allow you to identify the part that breaks and needs to be fixed, or at least that separate part function well separately. In the case of the latter, it would just be a matter of figuring out which section is providing bad data. So separating out components allows for you to find bad code and fix it.

Related Post

CIM to WMICIM to WMI

Years ago WMI was de-emphasized for CIM. Wait. Do you know what those are? CIM – “The Common Information Model (CIM) is an extensible, object-oriented data model that contains information