Home > Net >  Suppress Error output Where-Object on a cmd command
Suppress Error output Where-Object on a cmd command

Time:09-23

I'm trying to suppress an error output from a Where-Object of a cmd command (gpresult /r), first I saved the output of the gpresult to a variable, then I filtered the variable with the Where-Object and added two filters, to find two AD groups that the user should be member of.

The problem comes when the user is not in any of those groups (that it could happen because not everyone uses the programs related to those groups), the console prints a ugly error that we don't want the user to see... I tried adding -ErrorAction SilentlyContinue to the Where-Object with no avail, the error is still popping up.

Do you guys have any clue on this? Here's the code, so you can understand better what I'm trying to suppress:

$gpresult = gpresult /r
$userGroups = ($gpresult | Where-Object -FilterScript {($_ -match 'Group1_*') -or ($_ -match 'Group2_*')} -ErrorAction SilentlyContinue).Trim()

Thanks in advance!

Edit: Here's the error I get (with 2>$null): "Can't call a method in a expression with null value"

CodePudding user response:

I tried adding -ErrorAction SilentlyContinue to the Where-Object to no avail, the error is still popping up.

The unwanted error happens during the (...).Trim() method call, not in the Where-Object pipeline:

If the pipeline produces no output, the statement is equivalent to $null.Trim(), which predictably causes the following statement-terminating error:

You cannot call a method on a null-valued expression.

Therefore, to avoid this error, you must avoid the .Trim() call if the pipeline produces no output:

$userGroups = 
  $gpresult | 
  Where-Object -FilterScript {($_ -match 'Group1_*') -or ($_ -match 'Group2_*')} |
  ForEach-Object Trim

Note: The above uses simplified syntax to call .Trim() on each input object from the pipeline; if there is no input object, no call is made, which avoids the error.

The non-simplified equivalent of ForEach-Object Trim is ForEach-Object { $_.Trim() }

You could alternative use a try { ... } catch { ... } statement to suppress the error (a simplified example: try { $null.Trim() } catch { }), but note that catching statement-terminating errors (exceptions) is comparatively slower than the above approach.

CodePudding user response:

I am not completely sure I understand what you are trying to do but you can separate standard out and standard error streams For example redirecting stderr to null will completely remove it. If you add this to the end of your command.

2>$null

2 is error stream

If you want to separate them later you should be able to. Because data from stdout will be strings and data from stderr System.Management.Automation.ErrorRecord objects.

$gpresult = gpresult /r
$stderr = $gpresult | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
$stdout = $gpresult | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }
  • Related