Script Troubleshooting in PowerShell

While writing many of my PowerShell scripts I have found numerous helpful techniques when troubleshooting where a script is, what a certain variable has carried over or dumping the contents of an array or CSV file. I use techniques/commands like write-host, foreach loops for arrays, send-emailmessage, debug and write-eventlog. These methods come in handy when writing something you’ve never written before; working with commands you are unfamiliar with or even just to verify the results of a certain section of code. How would you go about using these in your scripts?

write-host
Let’s say you have a section of code that has an IF/ELSE loop when reading a CSV file or maybe an array. I use the write-host command to give feedback as to where the script may be processing. So let’s say we have a loop and it sends an email based on a value. The value is represented by $array. If a number is below a certain value like 4, then one type of email is sent. If it’s above 4, then a different email is set. Here is the sample script:

foreach ($number in $array) {
	If ($number -lt 4){
		send-mailmessage -to $to -from $from -subject "Test" -body $number" is your number!" -smtpserver localhost
	} Else {
		send-mailmessage -to $to -from $from -subject "Test" -body $number" is too big. Too bad." -smtpserver localhost
	}
}



After you run the script, no emails are generated. How would you troubleshoot this? The first method to try is “write-host”. Adding a simple message to display in the PowerShell would help locate where the script is at any point. Here is the revised script:

foreach ($number in $array) {
	If ($number -lt 4){
		send-mailmessage -to $to -from $from -subject "Test" -body $number" is your number!" -smtpserver localhost
		write-host "Value is under 4 and the current value is "$number
	} Else {
		send-mailmessage -to $to -from $from -subject "Test" -body $number" is too big. Too bad." -smtpserver localhost
		write-host "Value is over 4 and the current value is "$number
	}
}

Our output, prior to the changes, was:

PS-Event05

and now it looks like this:

PS-Event06

At the very least I know the script ran correctly and the loop worked. From here I can look at the individual commands to see if something is incorrect, or in my case I can check the Exchange Message Tracking Logs to see if the message was delivered or failed.

Write-EventLog
The next technique you can use is to write an event to the Event log when something occurs in the script as a checkpoint mechanism. So let’s say you have a script that renames files and the code is something like this:

foreach ($number in $array) {
	If ($number -lt 4){
		rename-item $number.txt $number.old
	} Else {
		rename-item $number.txt $number.new
	}
}

For some reason your files aren’t renaming and you are unsure which part of the loop is having an issue. So you add some event writing code into the script to log what has happened:

New-EventLog -logname "Application" -source "PS-Script"
Write-EventLog -logname "Application" -source "PS-Script" -eventid 1 -message "Script Starting"
foreach ($number in $array) {
	If ($number -lt 4){
		rename-item $number.txt $number.old
		Write-EventLog -logname "Application" -source "PS-Script" -eventid 1 -message "Script Renaming under 4."
	} Else {
		rename-item $number.txt $number.new
		Write-EventLog -logname "Application" -source "PS-Script" -eventid 1 -message "Script Renaming over 4."
	}
}
Write-EventLog -logname "Application" -source "PS-Script" -eventid 1 -message "Script Ended"

Once you run the script several events should be logged in the Application Log if the script ran well. Here is what the events look like:

PS-Event07

PS-Event08

After your script runs you now have some information about what was performed and when stored in the Application Log.

Foreach loops for arrays
Let’s say that you wanted to store information about your Exchange servers in an array. To do so, you can use code similar to this:

$ExchangeServer = get-exchangeserver

To verify the contents of you array, the easiest method is a foreach loop which will look at each line:

$ExchangeServer = get-exchangeserver
Foreach ($line in $ExchangeServer) {
	write-host $line.name"     "$line.serverrole"     "$line.AdminDisplayVersion
}

The output will be the selected contents of the array:

PS-Event09

Debug
The last resort command is always debug. Debug usually gives way too much information unless you know what you are looking for. I honestly have not used this feature as I am able to troubleshoot my scripts using the above techniques. See below for more information on debugging.

TechNet Articles

Advertisements

2 thoughts on “Script Troubleshooting in PowerShell

  1. Hey, thanks a lot for this TS tips, I am currently learning powershell and this is a great hint to troubleshoot my scripts. Keep up the good work! 🙂

  2. Pingback: Netrix LLC – Powershell, Reporting and Notifications

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s