-ErrorAction and -ErrorVariable



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