在 PowerShell 中将输出重定向到 $null,但要确保变量保持设置

我有密码:

$foo = someFunction

这将输出一条警告消息,我想将其重定向到 $null:

$foo = someFunction > $null

问题是,当我这样做时,虽然成功地取消了警告消息,但它也有不填充 $foo 函数的结果的负面影响。

如何将警告重定向到 $null,但仍然保持 $foo 填充?

另外,如何将标准输出和标准错误都重定向到 null? (在 Linux 中是 2>&1。)

169912 次浏览

This should work.

 $foo = someFunction 2>$null

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

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.

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

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 *.*" } }

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