【问题标题】:Suppress and handle stderr error output in PowerShell script抑制和处理 PowerShell 脚本中的 stderr 错误输出
【发布时间】:2021-01-19 14:18:30
【问题描述】:

我想使用 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 来抑制该错误,但这失败了。

显然,这是因为“网络视图”是 CMD,因此无法通过 try / catch 控制。所以我的问题是:我怎样才能 a) 抑制下面的系统错误?和 b) handle 这个错误发生时(即抛出“此主机没有响应'net view'”或东西而不是错误)?

System error 53 has occurred.
The network path was not found.

【问题讨论】:

  • 顺便说一句:您不需要$(...) 来运行外部程序;简而言之:$(...) 仅在可扩展字符串 ("...") 中或在其他语句中嵌入整个语句时需要。
  • 另一边:net.exe 是一个控制台应用程序,因此与任何特定的 shell 无关。作为一个控制台应用程序,它只有两个输出流可供使用:stdout(标准输出),用于数据,stderr(标准错误)用于错误消息和/或状态消息。

标签: powershell networking ip stderr smb


【解决方案1】:

来自外部程序的Stderr(标准错误)输出未与PowerShell的错误处理集成,主要是因为此流不仅用于传达错误 em>,还有状态信息。
(因此,您应该只根据其退出代码推断外部程序调用的成功与失败,如$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 的错误处理中,但在 this RFC 中提出了修复该问题。

[2] 在 PowerShell 7.0 之前,任何2> 重定向都会意外在自动$Error 集合中记录stderr 行。此问题已在 v7.1 中得到纠正
作为一个不幸的副作用,在 v7.0 之前的版本中,如果 $ErrorActionPreference = 'Stop' 恰好生效,并且至少发出一条 stderr 行,2> 重定向也可能引发脚本终止错误。

【讨论】:

    猜你喜欢
    • 2017-01-31
    • 2011-10-25
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多