121

I have some code:

$foo = someFunction

This outputs a warning message which I want to redirect to $null:

$foo = someFunction > $null

The problem is that when I do this, while successfully supressing the warning message, it also has the negative side-effect of NOT populating $foo with the result of the function.

How do I redirect the warning to $null, but still keep $foo populated?

Also, how do you redirect both standard output and standard error to null? (In Linux, it's 2>&1.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ted
  • 2,275
  • 5
  • 20
  • 17
  • 2
    What produces the warning message? If you are the author of `someFunction`, you might change it appropriately. – stej May 04 '11 at 19:30
  • 1
    Actually, in Bourne Shell (Linux), it's `2>/dev/null 1>/dev/null`; The redirect you've shown redirects stderr to the same place as stdout -- which may be `/dev/null`, or may be a regular file. – jpaugh Dec 13 '16 at 15:17

6 Answers6

205

I'd prefer this way to redirect standard output (native PowerShell)...

($foo = someFunction) | out-null

But this works too:

($foo = someFunction) > $null

To redirect just standard error after defining $foo with result of "someFunction", do

($foo = someFunction) 2> $null

This is effectively the same as mentioned above.

Or to redirect any standard error messages from "someFunction" and then defining $foo with the result:

$foo = (someFunction 2> $null)

To redirect both you have a few options:

2>&1>$null
2>&1 | out-null

ADDENDUM:

Please note that (Windows) powershell has many more streams than a linux based OS. Here's the list from MS docs:

enter image description here

Thus you can redirect all streams using the wildcard with *>$null, and you can also use a file instead of $null.

not2qubit
  • 14,531
  • 8
  • 95
  • 135
J Bills
  • 2,059
  • 1
  • 11
  • 2
  • 1
    This solution worked for me after I wrapped the statements in {curly braces} instead of (parenthesis). I may be using a newer PS version. – ManEatingCheese Sep 08 '19 at 09:43
  • 2
    And if we are creating a background job, we need to quite the job'ing itself: `{ myCommandWithAnyOutput & } | Out-Null` – arberg Sep 28 '19 at 08:10
15

If it's errors you want to hide you can do it like this

$ErrorActionPreference = "SilentlyContinue"; #This will hide errors
$someObject.SomeFunction();
$ErrorActionPreference = "Continue"; #Turning errors back on
Christian Flem
  • 680
  • 9
  • 7
15

This should work.

 $foo = someFunction 2>$null
ravikanth
  • 24,922
  • 4
  • 60
  • 60
6

Warning messages should be written using the Write-Warning cmdlet, which allows the warning messages to be suppressed with the -WarningAction parameter or the $WarningPreference automatic variable. A function needs to use CmdletBinding to implement this feature.

function WarningTest {
    [CmdletBinding()]
    param($n)

    Write-Warning "This is a warning message for: $n."
    "Parameter n = $n"
}

$a = WarningTest 'test one' -WarningAction SilentlyContinue

# To turn off warnings for multiple commads,
# use the WarningPreference variable
$WarningPreference = 'SilentlyContinue'
$b = WarningTest 'test two'
$c = WarningTest 'test three'
# Turn messages back on.
$WarningPreference = 'Continue'
$c = WarningTest 'test four'

To make it shorter at the command prompt, you can use -wa 0:

PS> WarningTest 'parameter alias test' -wa 0

Write-Error, Write-Verbose and Write-Debug offer similar functionality for their corresponding types of messages.

Rynant
  • 23,153
  • 5
  • 57
  • 71
1

using a function:

function run_command ($command)
{
    invoke-expression "$command *>$null"
    return $_
}

if (!(run_command "dir *.txt"))
{
    if (!(run_command "dir *.doc"))
    {
        run_command "dir *.*"
    }
}

or if you like one-liners:

function run_command ($command) { invoke-expression "$command  "|out-null; return $_ }

if (!(run_command "dir *.txt")) { if (!(run_command "dir *.doc")) { run_command "dir *.*" } }
Elroy Flynn
  • 3,032
  • 1
  • 24
  • 33
0

Recently, I had to shut up powershell on a Linux host, this wasn't that obvious to figure out. After back and forth I found out that wrapping a command in $( ) and adding a explicit redirection after the wrapper works.

Anything else I tried, wouldn't - I still don't know why since the PowerShell Docs are of desirable quality (and full of inconsistency...)

To import all modules on startup, I added the following. This produced some stderr output by powershell that couldnt be put to rest by ErrorAction or redirection without using the wrapping...

If anyone could elaborate on why's that would be very appreciated.

 # import installed modules on launch 
 $PsMods = $(Get-InstalledModule); 
 $($PsMods.forEach({ Import-Module -Name $_.Name -ErrorAction Ignore })) *> /dev/null 
Inoperable
  • 1,429
  • 5
  • 17
  • 33