An ErrorAction in PowerShell is a feature that helps direct the shell as to what action should be taken if a particular error or warning should occur when a section of code executes. One thing I have learned through trial and error is that ErrorAction is not perfect, it requires testing and validation and does not work for every cmdlet. So what purpose can you utilize them for in scripts? Well, let’s review a few real world examples to see how they fit and what the different results are. First, we need to review what actions are possible with ErrorAction.
ErrorActions: Continue, Ignore, Inquire, SilentlyContinue, Stop and Suspend Rather than reinvent the wheel, I’ve found a good explanation of these terms is located HERE
Examples
Now in terms of using these in a practical scenario, using real world examples would helpful. For myself personally, I find the STOP and SilentlyContinue options the most useful. For SilentlyContinue, one note that should be discussed is that this option will hide any potential errors. This may be a good thing until troubleshooting is needed. Then that will need to be removed so PowerShell can display the appropriate error message.
STOP This example is something that is repeatable in many scenarios. Basically we run some sort of query in PowerShell where we expect a result and then move on. However, what if that query fails? It could create a potential domino effect. So we can use Try {}Catch{} along with ErrorAction STOP to trigger an alternate path to keep the script going along a secondary path. Say for example we need to query for an object in Exchange – Public Folders – and this is being done as an assessment. One thing we cannot assume is that there are actually going to be Public Folders present. We can use this one-liner to make the query: Get-PublicFolder ‘\’ -Recurse In an environment without Public Folders, we will get an error message, like so:
Now, what if I don’t want to see that error message. I want to suppress it and make it more ‘User Friendly’. The large amount of red text can look worse than the situation is, in this case Public Folders just don’t exist. We can mitigate this with ErrorAction STOP and Try{}Catch{}, like so:
[sourcecode language=”powershell”]
Try { Get-PublicFolder '\' -recurse -ErrorAction STOP } Catch { Write-Host 'No Public Folders were found.' }
[/sourcecode]
In this case, we would have output like so:
That is far more useful and we can also log the same message to a log file if we wish as well. One side-effect of the change is that the information that we receive back is more compact and readable than the error message that we initially received when we were not use the ErrorAction parameter for the cmdlet.
This method is a repeatable process for handling all sorts of errors. We can use it for any query where there is a potential for a problem with the caveat that some cmdlets do not have ErrorAction as a parameter. For those that do, we can use the method about as well as supplement this by not entirely ignoring the error message by suppressing it as we did above and then logging the error message to a log file for examination. How do we do that?
In another example, I am trying to apply ACLs to a File Folder for a Windows Server. I want to have a failure be silent, but log the error to the file, we can do so with this variable ‘$_.Exception.Message’. This variable contains the error message from the last cmdlet that just ran. We can collect that and out put it to a file usimng ‘Out-File’. A real world example looks like:
[sourcecode language=”powershell”]
Try {
$Acl | Set-Acl $Subfolder -ErrorAction Stop
$Output = "$Date,SUCCESS – Set-Acl $Subfolder" | Out-file $ActionDestination
} Catch {
$Output = "FAILED – Set-Acl $Subfolder" | Out-file $ErrorDestination -Append
$Output = "$_.Exception.Message" | Out-file $ErrorDestination -Append
}
[/sourcecode]
The $_.ErrorDestination variable contents are now stored in a file whose name was stored in the $ErrorDestination.
Using -ErrorAction STOP to make a decision.
A potential use for -ErrorAction STOP is a decision point. If the no error occurs, then one action can occur and if there is a failure another path of action can be taken. An example of this technique is show below. There is a Try{}Catch{} section of code that is being used to check the Pagefile for a server. The first check is done with CIM. If this query fails, the Catch{} section sets a variable ($WMIQuery) to true. This is done to trigger another section of code to instead try the same query with WMI and not CIM. The thought process behind this is that sometimes a CIM query can fail where a WMI query might work.
[sourcecode language=”powershell”]
$NonManagedPagefile = $True
Try {
$MaximumSize = (Get-CimInstance -ComputerName $Server ` -Query "Select * from win32_PageFileSetting" | select-' object MaximumSize).MaximumSize
} Catch {
$WMIQuery = $True
} If ($WMIQuery) {
Try {
$PageFileCheck = Get-WMIObject -ComputerName $Server -Class WIN32_PageFile ` -ErrorAction STOP
$NonManagedPagefile = $True
} Catch {
$NonManagedPagefile = $False
}
[/sourcecode]
Silently Continue
For this ErrorAction, SilentlyContinue enables PowerShell to continue past and error and not display the message to the Shell where an operator can see it. This action can come in handy if you don’t have any error checking, or perhaps there is a known issue or problem that you need to work around for the script. In this case SilentlyContiue can come in quite handy. Example: In this example we run a query to find Public Folders in an environment. If we want to ignore any error messages (say if no PublicFolders exists or if a Public Folder normally generates an error, we can use it to hide that as well. Sample one-liner would look like this:
Get-PublicFolder -ErrorAction SilentlyContinue
Problems that come with SilentlyContinue are that is can hide the bad stuff (i.e. errors that may need actual attention) and it cannot be used to generate decisions in PowerShell scripts. The STOP action for ErrorAction is far more useful in 90% of use cases.