In order to be informed when PowerShell Startup / Logon scripts running on remote computers have bugs, I tend to end scripts with the following:
If ($Error) {
(Code that sends a notification email to system administrators attaching the contents of the $Error variable for troubleshooting)
}
This is a great 'tell tale' to pick up edge cases / bugs. However, I've found some basic built-in PowerShell cmdlets dump data into $Error even on successful runs - for example, try:
$Error.Clear()
Get-NetIPConfiguration
$Error
And you'll see a load of errors in $Error that are not shown during normal output but look like:
Get-NetRoute : No matching MSFT_NetRoute objects found by CIM query for instances of the ROOT/StandardCimv2/MSFT_NetRoute class on the CIM server: SELECT * FROM MSFT_NetRoute WHERE ((DestinationPrefix LIKE '0.0.0.0/0')) AND ((InterfaceAlias LIKE 'OpenVPN Wintun')). Verify query parameters and retry.
Get-NetConnectionProfile : No MSFT_NetConnectionProfile objects found with property 'InterfaceAlias' equal to 'Local Area Connection'. Verify the value of the property and
retry.
or
$Error.Clear()
Get-NetIPAddress
$Error
will return:
“Infinite : The term '“Infinite' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
(A nice little bug for Microsoft to solve at some point, doubtless!)
Since it's unlikely that the cmdlets will be fixed any time soon, is there a way to run these cmdlets without them clogging up $Error with their useless information?
This is not a duplicate of Powershell: How can I stop errors from being displayed in a script? since that covers errors that actually display in red on the PowerShell console during a 'failed' run of the cmdlet; this is about errors generated by some cmdlets in the background during an apparently 'successful' run of a cmdlet which for some reason only get written to the automatic $Error variable.
Nonetheless I have already tried a number of solutions suggested in that post:
- Running the cmdlets with -ErrorAction Ignore
- Running the cmdlets with -ErrorAction SilentlyContinue
- Running the cmdlets inside try {} catch {}
- Running the cmdlets inside try {} catch {} with -ErrorAction Stop
- Running the cmdlets with 2>$null following them
- Setting $ErrorActionPreference = "SilentlyContinue" before running the cmdlets
I may be asking the impossible, but the way these cmdlets behave does make $Error very hard to use as an actual log, just want to know if I'm missing a trick.
I would like to be able to encapsulate buggy cmdlets in such a way that 'hidden' errors do not go into the automatic $Error variable.