powershell - 需要帮助捕获 PowerShell 中的错误消息

标签 powershell error-handling

我正在尝试从网络上的多个服务器捕获本地管理员组中的用户。我最初从一个脚本开始,我发现它执行 WMI 调用,但所有这些都在网络上被阻止。

我终于得到了以下工作,但是当我收到错误时,它会给出 Powershell 错误,我想通过仅给出简短的答案来简化它,例如“访问被拒绝”或“WinRM 无法处理请求。”等...我必须将报告交给非技术用户。

我想捕获以下错误消息:后面的句子到句点。

如果有更好的方法或输出,我愿意接受建议。

感谢您的帮助

$computerlist = get-content "C:\ServerList.txt"


ForEach ($computer in $computerList)
    {
    &{$computer 
    Invoke-Command -ComputerName $computer -ScriptBlock {Get-LocalGroupMember -Group administrators} |
        Select-Object Name,PrincipalSource|Format-table -AutoSize 
    Write-Output " "} 2>&1 >>.\output.txt
    
    }

[XXXXXXX] Connecting to remote server XXXXXXX failed with the following error message : WinRM cannot process the request. The following error occurred while using Kerberos authentication: Cannot find the computer XXXXXXX. Verify that the computer exists on the network and that the name provided is spelled correctly. For more information, see the about_Remote_Troubleshooting Help topic. + CategoryInfo : OpenError: (EPICSOAPT:String) [], PSRemotingTransportException + FullyQualifiedErrorId : NetworkPathNotFound,PSSessionStateBroken

最佳答案

尝试以下操作:

Invoke-Command -ComputerName $computerList -ScriptBlock { 
  Get-LocalGroupMember -Group administrators | Select-Object Name, PrincipalSource 
} 2>&1 | ForEach-Object {
  if ($_ -is [System.Management.Automation.ErrorRecord]) { # an error
    # Extract the substring of interest from the error message and prepend 
    # the computer name.
    # Write the result as a *warning*
    # Note: Warnings are sent to a different output stream,
    #       which in this case means that all warnings print *before* 
    #       Format-Table's output.
    Write-Warning ("$($_.TargetObject ): " + (($_ -split ' : ')[1] -split '\.')[0] + '.')
  }
  else { # an output object, pass it through
    $_ 
  }
} | Format-Table -GroupBy PSComputerName -AutoSize > .\output.txt
  • 最好在一次单次调用中将计算机列表传递给Invoke-Command,这会导致这些计算机并行定位。

    • 注意:目标计算机的输出保证按输入顺序到达,但您可以插入 Sort-Object PSComputerName管道段,以便按计算机名称的字母顺序对结果进行排序。
  • 正如您的方法一样,2>&1 用于将错误流 (2) 合并到成功 (1) 中流。

  • ForEach-Object脚本 block ,-istype(-inheritance) / interface test operator用于检测输入对象中的错误 ( System.Management.Automation.ErrorRecord ) 实例。

    • 如果找到这样的实例,-split operator用于提取感兴趣的错误消息部分,并在前面添加计算机名称。

    • Write-Warning用于以视觉上显眼的方式发出错误消息;请注意,警告会发送到不同的 output stream (#3) ,在本例中,这意味着所有警告都会在由 Format-Table 格式化的成功输出之前打印。

    • 如果您想在之后发出警告,则必须将字符串收集到数组(或列表)中,然后在单独的语句中输出它们。

  • Format-Table-GroupBy 参数用于通过 .PSComputerName 属性对格式化的成功输出对象进行分组,该属性由 Invoke-Command 隐式添加。并包含源计算机的名称。

    • 请注意,默认情况下,.PSComputerName 属性和另一个添加的属性 .RunspaceId包含在表输出中。您可以通过将 -HideComputerName 开关添加到 Invoke-Command 调用来避免包含 PSComputerName;但是,仍然包含 RunspaceId 属性。为了避免这种情况,请使用Format-Table-Property 参数来传递要显示的属性名称的显式列表。 (另一个更方便但更昂贵的选项是使用 -HideComputerName,并在 Format 之前将 Select-Object * -Exclude RunspaceId 命令插入管道中-表调用)。

示例输出(假设成功检索的对象具有属性 onetwothird;注意如何首先打印有关连接失败的警告):

WARNING: server2: WinRM cannot complete the operation.

   PSComputerName: server1

one two three PSComputerName RunspaceId
--- --- ----- -------------- ----------
  1   2     3 server1        29b0bc1e-cf7f-4d9b-b267-86deff2b7ed0
  4   5     6 server1        ab2ed6a9-3fba-4083-b13e-b43617048ecf

   PSComputerName: server3

one two three PSComputerName RunspaceId
--- --- ----- -------------- ----------
  7   8     9 server3        39b0bc1e-cf7f-4d9b-b267-86deff2b7ed1

关于powershell - 需要帮助捕获 PowerShell 中的错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65311824/

相关文章:

c# - 从 Powershell 调用的 DLL 的当前目录错误

Powershell - 如何将 laSTLogon 转换为天数

powershell - 我应该使用 Active Directory 模块 cmdlet 还是 DirectoryServices .NET 类

java - 如果文件使我的应用程序崩溃则删除文件

knockout.js - John Papa 的 HotTowel this.handleError 未定义...为什么?

r - 在R(coxph)中拟合 Gamma 脆弱模型

PowerShell/WMI 电源管理

powershell - 成员枚举在 PowerShell 3 中如何工作?

error-handling - CRM 2011 - ITracingService 在运行时访问 traceInfo

javascript - 尽管被捕获,但生成器内部抛出的错误完成了它