抑制并处理 PowerShell 脚本中的 stderr 错误输出
Suppress and handle stderr error output in PowerShell script
我想使用 PowerShell 捕获 SMB 共享,但这不起作用
# Cannot use CIM as it throws up WinRM errors.
# Could maybe use if WinRM is configured on all clients, but this is not a given.
$cim = New-CimSession -ComputerName $hostname
$sharescim = Get-SmbShare -CimSession $cim
所以这让我想到了另一种使用网络视图的方法,如果主机是 Windows
# This method uses net view to collect the share names (including hidden shares like C$) into an array
# https://www.itprotoday.com/powershell/view-all-shares-remote-machine-powershell
try { $netview = $(net view \$hostname /all) | select -Skip 7 | ?{$_ -match 'disk*'} | %{$_ -match '^(.+?)\s+Disk*'|out-null ; $matches[1]} }
catch { $netview = "No shares found" }
所以,如果主机是 Linux,我会收到一个错误,如您所见,我在上面尝试使用 try / catch 来抑制该错误,但是失败了。
很明显,这是因为'net view'是CMD,所以不受try/catch的控制。所以我的问题是:我怎样才能 a) 抑制下面的系统错误?,和 b) 处理 这个错误发生时(即抛出一个“这个主机没有响应 'net view'" 或其他东西而不是错误)?
System error 53 has occurred.
The network path was not found.
来自 外部程序 的 Stderr(标准错误)输出未与 PowerShell 的错误处理 集成,主要是因为此流不仅用于传达错误,还有状态信息。
(因此,您应该只根据 退出代码 来推断 external-program 调用的成功与失败,如 $LASTEXTICODE
[1]).
但是,您可以重定向 stderr 输出,并将其重定向到$null
(2>$null
) 使其静音[2]:
$netview = net view \$hostname /all 2>$null | ...
if (-not $netview) { $netview = 'No shares found' }
[1] 从 v7.1 开始,按照惯例表示失败的非零退出代码也未集成到 PowerShell 的错误处理中,但在 [=18 中提出了修复=].
[2] 直到 PowerShell 7.0,任何 2>
意外重定向 also 在自动 $Error
集合中记录 stderr 行.此问题已在 v7.1
中得到纠正
作为一个不幸的副作用,在 v7.0 之前的版本中,如果 $ErrorActionPreference = 'Stop'
恰好有效,则 2>
重定向也可能引发 script-terminating 错误,如果至少有一个 stderr 行是发出。
我想使用 PowerShell 捕获 SMB 共享,但这不起作用
# Cannot use CIM as it throws up WinRM errors.
# Could maybe use if WinRM is configured on all clients, but this is not a given.
$cim = New-CimSession -ComputerName $hostname
$sharescim = Get-SmbShare -CimSession $cim
所以这让我想到了另一种使用网络视图的方法,如果主机是 Windows
# This method uses net view to collect the share names (including hidden shares like C$) into an array
# https://www.itprotoday.com/powershell/view-all-shares-remote-machine-powershell
try { $netview = $(net view \$hostname /all) | select -Skip 7 | ?{$_ -match 'disk*'} | %{$_ -match '^(.+?)\s+Disk*'|out-null ; $matches[1]} }
catch { $netview = "No shares found" }
所以,如果主机是 Linux,我会收到一个错误,如您所见,我在上面尝试使用 try / catch 来抑制该错误,但是失败了。
很明显,这是因为'net view'是CMD,所以不受try/catch的控制。所以我的问题是:我怎样才能 a) 抑制下面的系统错误?,和 b) 处理 这个错误发生时(即抛出一个“这个主机没有响应 'net view'" 或其他东西而不是错误)?
System error 53 has occurred.
The network path was not found.
来自 外部程序 的 Stderr(标准错误)输出未与 PowerShell 的错误处理 集成,主要是因为此流不仅用于传达错误,还有状态信息。
(因此,您应该只根据 退出代码 来推断 external-program 调用的成功与失败,如 $LASTEXTICODE
[1]).
但是,您可以重定向 stderr 输出,并将其重定向到$null
(2>$null
) 使其静音[2]:
$netview = net view \$hostname /all 2>$null | ...
if (-not $netview) { $netview = 'No shares found' }
[1] 从 v7.1 开始,按照惯例表示失败的非零退出代码也未集成到 PowerShell 的错误处理中,但在 [=18 中提出了修复=].
[2] 直到 PowerShell 7.0,任何 2>
意外重定向 also 在自动 $Error
集合中记录 stderr 行.此问题已在 v7.1
中得到纠正
作为一个不幸的副作用,在 v7.0 之前的版本中,如果 $ErrorActionPreference = 'Stop'
恰好有效,则 2>
重定向也可能引发 script-terminating 错误,如果至少有一个 stderr 行是发出。