The short version of this post if that if you use a RETURN statement inside a Measure-Command block expecting the script to return to the command prompt that won’t happen. The next line of code after the Measure-Command block will run instead which definitely won’t be what you were expecting. Skip to the examples if you like….
I was recently working on a script and wanted to store in the logs how long some parts of the script were taking to run. I thought it might be useful therefore to warp parts of the code in a Measure-Command block and store the time taken to a variable that I could then write into the log. Over time I could easily see if the script was slowing down and specifically if any section was slowing down by comparing the log files.
This seems like a good idea and it probably still is but there is a gotcha that I didn’t know about. Most of my script run inside of Active Roles and Quest / One Identity state not to use the Exit command in any of your custom scripts. In fact if you use exit in your scripts the Powershell ISE closes completely when debugging so I’m guessing a similar thing happens to the ARS command shell which is why they say not to use it.
I used to use Throw statements to end all my ARS schedule task scripts so that it would update the task last run message. When I had an ARS issue recently though, Quest support wanted me to clear all the errors from the logs when my scripts run. I wrote a function to update the last run message so I got the same functionality and then changed the throw statements to a Return statement. As I expected this didn’t resolve the issue I was having with ARS but that’s another story entirely.
Anyway back to the Measure-Command block gotcha – if we take a look at this simple script:
Write-Host ‘start’
Return
Throw ‘Stopping script no other lines should run’
Write-Host ‘still here’
The throw statement and the last write-host is never reached as expected but if you wrap it in a measure command block to see how long the script took
Clear-Host
Measure-Command {
Write-Host ‘start’
Return
Throw ‘Stopping script no other lines should run’
}
Write-Host ‘still here’
Throw will be skipped as expected because it’s after the Return statement but the last line of code will run and print ‘still here’ to the console.
I guess this is logical if you think about it but it’s still a gotcha!