Let me take a minute to tell you about 2 of my favorite things in Windows PowerShell: -ErrorAction and –ErrorVariable
You may have heard me talk about being maniacal about doing a great job with error handling … this is one the cornerstones of our architecture.
Here is the background: Cmdlets are implemented by subclassing a base class. The engine reflects against this class looking for public properties that have a .net attribute on them identifying them as a PARAMETER. Why is this a good idea? Well think about it, the base class can also have public properties with the PARAMETER attribute. And that’s exactly what we do. We call these Common Parameters (because I failed to convince our writers that it was a noble and worthwhile task to teach the planet the meaning of the word “ubiquitous”).
You might be asking yourself – how would I find out more about common parameters?
Hmmm… so you want to “get help about common parameters”. Hmmm, I wonder want a good way to express this idea in PowerShell would be ……
How about:
PS> get-help about_CommonParameters
TOPIC
Common Parameters
SHORT DESCRIPTION
Parameters that every cmdlet supports.
LONG DESCRIPTION
Windows PowerShell includes several common parameters that all
cmdlets support. This feature provides a consistent interface to
Windows PowerShell.
When a cmdlet supports a common parameter, the use of the parameter
does not cause an error. However, the parameter might not have any
effect in some cmdlets.
The common parameters are:
Parameter Description
——— ————————————————–
Verbose Boolean. Generates detailed information about the
operation, much like tracing or a transaction log.
This parameter is effective only in cmdlets that
generate verbose data.
Debug Boolean. Generates programmer-level detail about the
operation. This parameter is effective only in cmdlets
that generate debug data.
ErrorAction Enum. Determines how the cmdlet responds when an error
occurs. Values are: Continue [default], Stop,
SilentlyContinue, Inquire.
ErrorVariable String. Specifies a variable that stores errors from
the command during processing. This variable is
populated in addition to $error.
OutVariable String. Specifies a variable that stores output from
the command during processing.
OutBuffer Int32. Determines the number of objects to buffer
before calling the next cmdlet in the pipeline.
In addition to the common parameters, there are two parameters that
cmdlets support if they change the system state.
Parameter Description
——— ——————————————————-
WhatIf Boolean. Explains what will happen if the command is
executed, without actually executing the command.
Confirm Boolean. Prompts the user for permission before
performing any action that modifies the system.
SEE ALSO
For information about parameters, type:
help about_Parameter
You think it, you type it, you get it. 🙂
So back to -ErrorAction and -ErrorVariable. These are implemented by the engine on behalf of the Cmdlet – the developer doesn’t have to do anything. They just call WriteError() and we do the rest.
Here is the easiest way to show this working:
PS> Stop-Process 13,23
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ Stop-Process <<<< 13,23
Stop-Process : Cannot find a process with the process identifier 23.
At line:1 char:13
+ Stop-Process <<<< 13,23
PS> Stop-Process 13,23 -ErrorAction Stop # Only 1 error
Stop-Process : Command execution stopped because the shell variable “ErrorA
ctionPreference” is set to Stop: Cannot find a process with the process ide
ntifier 13.
At line:1 char:13
+ Stop-Process <<<< 13,23 -ErrorAction Stop # Only 1 error
PS> Stop-Process 13,23 -ErrorAction silentlycontinue # No errors
PS> Stop-Process 13,23 -ErrorAction inquire # ASK
Confirm
Cannot find a process with the process identifier 13.
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help
(default is “Y”):h
Stop-Process : Command execution stopped because the user selected the Halt
option.
At line:1 char:13
+ Stop-Process <<<< 13,23 -ErrorAction inquire # ASK
PS>
PS>
PS> Stop-Process 13,23 -ErrorVariable a -ErrorAction SilentlyContinue
PS> $a[0]
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ Stop-Process <<<< 13,23 -ErrorVariable a -ErrorAction SilentlyContinue
PS> $a[0] |fl * -Force
Exception : Microsoft.PowerShell.Commands.ProcessCommandExcepti
on: Cannot find a process with the process identifi
er 13.
TargetObject : 13
CategoryInfo : ObjectNotFound: (13:Int32) [Stop-Process], ProcessC
ommandException
FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Comma
nds.StopProcessCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
PS> $a |ft TargetObject -force -auto
TargetObject
————
13
23
Now one thing that is not obvious to people is that you can specify a “+” in front of the variable name for ErrorVariable and we will ADD the errors to that variable.
PS> $err=@()
PS> stop-process 13 -ea silentlycontinue -ErrorVariable err
PS> $err.count
1
PS> stop-process 23 -ea silentlycontinue -ErrorVariable +err
PS> $err.count
2
PS> $err
Stop-Process : Cannot find a process with the process identifier 13.
At line:1 char:13
+ stop-process <<<< 13 -ea silentlycontinue -ErrorVariable err
Stop-Process : Cannot find a process with the process identifier 23.
At line:1 char:13
+ stop-process <<<< 23 -ea silentlycontinue -ErrorVariable +err
Lastly, you don’t need to type out –ErrorAction or –ErrorVariable, we have defined parameter aliases for these so you can just type –EA and -EV
Enjoy
Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
Nice post, maybe the website should add markdown to make code more clear.