Musings of a Data professional

Stuart Moore

Powershell, using ErrorVariable and WarningVariable

If you’re looking to record the error and warning outputs from your PowerShell commands whilst keeping your console free of nasty red text, then the ErrorVariable and WarningVariable parameters are just what you’re looking for.

Let’s take a look at a quick simple example:

Get-ChildItem -Path C:\DoesNotExist\
$ErrVar = 'ErrorVariable'
$ErrVar
Get-ChildItem -Path C:\DoesNotExist\ -ErrorVariable ErrVar
$ErrVar

Which assuming you don’t have C:\DoesNotExist\ on your workstation, then you should see output like this:

From this quick example a couple of things stand out:
* you pass the name for the Error variable in without the $
* If you resuse a variable name it’ll get clobbered, so be careful (or read on)
* The error is still output to the screen

The last one is not what we want. So one more little tweak will make that disapper

Get-ChildItem -Path C:\DoesNotExist\ -ErrorVariable ErrVar -ErrorAction SilentlyContinue
$ErrVar

That’s much better, no more red text! -ErrorAction SilentlyContinue does exactly what it says on the tin.

WarningVariable and WarningAction work in exactly the same way, just on Warning events rather than Errors.

Even better news is that any advanced functions you write automatically get these options:

function Test-ErrorVariable {
  [CmdletBinding()]
  Param(
    [string]$Path
  )
  Process {
    Get-ChildItem -Path
  }
}
Test-ErrorVariable -Path c:\DoesNotExist -ErrorAction SilentlyContinue -ErrorVariable ErrVar
$ErrVar

That’s it, just write an advanced function and PowerShell puts all this in behind the scenes for you

Now, what happens if you’re calling multiple commands and want to store the error output from all of them. Do you need to specify a new ErrorVariable for each one? That could get horribly messy with auto generating variable names in a loop. Luckily there’s a built in method for handling that, prepend the variable name with + and the new data will be added to the variable (which is an array):

Test-ErrorVariable -Path c:\DoesNotExist -ErrorAction SilentlyContinue -ErrorVariable ErrVar
Test-ErrorVariable -Path c:\DoesNotExistEither -ErrorAction SilentlyContinue -ErrorVariable +ErrVar
$ErrVar
$ErrVar.GetType()
$ErrVar[0]
$ErrVar[1]

So you can reuse the same name throughout your script. Don’t worry about when to add the + to the string, behind the scenes PS checks if the variable exists and if it doesn’t creates it the first time it’s used.

These Error and Warning paramters are very useful for collecting information about failed runs, and from hiding nasty screens of red text from end users if you don’t want to worry them.

Previous

Using the Chronometer PowerShell module to analyse module performance

Next

Creating a Time Series database for SQL Server Restore testing

3 Comments

  1. Eduardo Perez

    Hello:
    I try to do this:
    Set-DynamicDistributionGroup -Id _lp -Notes “adios”
    $ErrVar = ‘ErrorVariable’
    $ErrVar
    Set-DynamicDistributionGroup -Id _lp -Notes “adios” -WarningVariable ErrVar
    $ErrVar
    But the $ErrVar variable value is not modified . Yes when I play with ErrorVariable.
    Can you help?
    Regards

    • Avatar photo

      Hi Eduardo,
      Do you meant that $ErrVar still contains ‘ErrorVariable’? That shouldn’t happen. For example:

      PS /Users> $warnvar = 'warning'
      PS /Users> $warnvar
      warning
      PS /Users> $null = Get-ChildItem . -WarningVariable warnvar
      PS /Users> $warnvar
      PS /Users>

      This is correct as Get-ChildItem has created a ‘new’ Warnvar variable, which has no content.

      If you run the Set-DynamicDistributionGroup command without the WarningVariable parameter do you get a warning? If you don’t then then ErrVar will be empty like it is in my example above.

      Does that help? Please let me know if it doesn’t and we can work through some more examples

  2. Eduardo Perez

    After more debug trying to isolate, and testing, I found that commands executed inside remote connetions (at least a Exchange remote powershell sessions) doesn’t write the warningvariable.
    I found a written comment of a user that helped as workaround , executing the command with invoke-command syntax:

    PS J:\> Get-DynamicDistributionGroup _lp_mundo|Set-DynamicDistributionGroup -ModerationEnabled $false
    ADVERTENCIA: El comando finalizó correctamente, pero no se ha modificado ningún valor de configuración de “domain.local/Servicios/_lp_Mundo”.
    PS J:\> $a
    PS J:\> Get-DynamicDistributionGroup _lp_mundo|Set-DynamicDistributionGroup -ModerationEnabled $false -WarningVariable a
    ADVERTENCIA: El comando finalizó correctamente, pero no se ha modificado ningún valor de configuración de “domain.local/Servicios/_lp_Mundo”.
    PS J:\> $a
    PS J:\> Invoke-Command {Get-DynamicDistributionGroup _lp_mundo|Set-DynamicDistributionGroup -ModerationEnabled $false} -WarningVariable a
    ADVERTENCIA: El comando finalizó correctamente, pero no se ha modificado ningún valor de configuración de “domain.local/Servicios/_lp_Mundo”.
    PS J:\> $a
    El comando finalizó correctamente, pero no se ha modificado ningún valor de configuración de “domain.local/Servicios/_lp_Mundo”.
    PS J:\>

    Do you find a why?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Powered by WordPress & Theme by Anders Norén