Nowadays, the IT professional is getting more involved with DevOps, and the use of code to create scripts and process is more and more common on a daily basis. I’ve been working in an Azure deployment and sometimes we need to retrofit configuration in several resources. PowerShell scripts are a great way to accomplish this type of requirement.
Test your cmdlets before incorporating them into PowerShell scripts
When writing your script, it is normal to line up all the commands and start testing, which is great, but before completing your script try your cmdlets and test them under both conditions: success and failure. See if your script is ready for both scenarios.
A simple example in the image below: Listing contents of a folder could generate the results expected but also generate a red error message. The only difference between those two cmdlets was a small type on the second try.
Handling errors
When IT professionals create PowerShell scripts, they are not expecting errors to occur, and we don’t treat errors accordingly in our scripts. If you have a development background, you may incorporate that into your scripts, and that is great! If not, using some of these simple tricks may help your scripts.
There are plenty of ways to deal with exceptions using PowerShell. We can start simply by understanding the parameters -ErrorAction and -ErrorVariable. Using -ErrorAction we can control how PowerShell will behave when an error occurs. The possible options are Continue, Ignore, Inquire, SilentyContinue, Suspend and Stop and they are self-explanatory. We can see the introduction of ErrorAction parameter in our previous cmdlet and at this time no errors — but we are masquerading the issue because although we are not being informed, the error it is still there). In that specific case, PowerShell wasn’t able to find that path.
get-item -Path HKLM:\SOFTWARE\ITPROCentralx
get-item -Path HKLM:\SOFTWARE\ITPROCentralx -ErrorAction SilentlyContinue
get-item -Path HKLM:\SOFTWARE\ITPROCentralx -ErrorAction SilentlyContinue
Using the -ErrorVariable parameter in the same cmdlet allows us to store the error message in a variable that we can use afterward. We are going to run both cmdlets below and you see them in action in the image below.
get-item -Path HKLM:\SOFTWARE\ITPROCentralx -ErrorAction SilentlyContinue -ErrorVariable vtmp
$vtmp
$vtmp
Note: When using the parameter –ErrorVariable, we do not use $. Afterward, however, we do use the $ because it is a variable.
When we are running PowerShell scripts, we can add the following code to list a specific Registry Key, and because that specific Registry Key does not exist we can use a combination of error variable and error action to keep the script running without an error and complete the operation.
get-item -Path HKLM:\SOFTWARE\ITPROCentralx -ErrorAction SilentlyContinue -ErrorVariable vtmp
If ($vtmp -eq $Null){
Write-Host "No errors found, good to go!"
}Else{
Write-Host -ForegroundColor Yellow "Errors found, we have room to inspect and be creative here..."
If ($vtmp.categoryinfo.category -eq "ObjectNotFound") {
New-Item -Path $vtmp.TargetObject
}
}
If ($vtmp -eq $Null){
Write-Host "No errors found, good to go!"
}Else{
Write-Host -ForegroundColor Yellow "Errors found, we have room to inspect and be creative here..."
If ($vtmp.categoryinfo.category -eq "ObjectNotFound") {
New-Item -Path $vtmp.TargetObject
}
}
One hint is to use the Windows PowerShell ISE (as depicted in the screenshot below), which allows the code to be written on the top frame and execution of the entire script or portion on the bottom frame.
In the example below, we can see that the code was executed, the Registry Key did not exist at the execution time, and it was created as part of the error handling. On the right side of the same picture we can see that the Registry Key was created.
Note: Depending on your configuration, only a Windows PowerShell ISE session or PowerShell running as administrator will be required to manage the Registry.
Before going any further, we need to explain how we got the pieces to check if the error was related to object not found/existent. The first step was to generate the error, which gives us the opportunity to debug the error message and start testing how we can treat the possible error.
In order to understand, we need to figure out what type the variable is ($vtmp) that we specified. We can use the following command: $vtmp.GetType(). Just replace $vtmp for the variable that you are using. That gives us the information that is an Array. When we use the command <variable> | Format-List -Property * -Force, we will have a list of the array and its keys and values. Both commands are shown in the image below.
The output on the <variable>.CategoryInfo will display all the information of that key, and as we can see we have another array of keys and values. The two that we are looking for is the Categoryand we can also use the targetname, which gives us an advantage where we can use that same piece of information to create the key (in case it does not exist).
When developing PowerShell scripts, there are tons of ways to get the same results, some of them more efficient than others. The script above could be much easier accomplished using the Test-Path cmdlet to validate before trying to create (actually that is a best practice to avoid error — perform your testing before the action and make sure that you have everything in place before executing an action), but the goal was to demonstrate how to handle errors stored in a variable.
More to explore
In this article, we covered a simple way to handle errors using PowerShell. But the sky is the limit when creating code to protect against human errors. In some cases, we can create loops to make sure that we force the desired command to be executed properly. We will explore more on this subject in an upcoming article.
No comments:
Post a Comment