Get-Process -computername 管道输入仅适用于名字

Get-Process -computername pipeline input works only with the first name

Get-Process 通过管道 (ByPropertyName) 接受 -computername 参数。 我导入的文件如下所示:

computername
sql01
sql02
sql03

当我通过管道传输时,我将仅从列表中的第一台计算机 (sql01) 获取进程?

$a = Import-Csv C:\temp\computers.txt
$a | get-process -name dwm # output only from the first computer in the list
get-process dwm -ComputerName $a.computername # here correct output from 3 computers

您似乎在 Windows PowerShell 中遇到了错误 - 请参阅底部了解详细信息。

  • bug 不太可能得到修复, 鉴于 Windows PowerShell 只会看到重要的修复。

  • 您已经知道解决方法:将计算机名称数组作为参数传递给-ComputerName 而不是通过管道。

    # Windows PowerShell only.
    Get-Process dwm -ComputerName $a.computername
    
  • 从更广泛的角度来看,考虑改用 PowerShellremoting, where only the general-purpose Invoke-Command cmdlet facilitates execution of arbitrary commands remotely, using a modern, firewall-friendly transport. Similarly, the CIM cmdlets (e.g. Get-CimInstance),它们使用相同的传输方式,应该优先于它们取代的过时的 WMI cmdlet(例如,Get-WmiObject)。

    # Works in both PowerShell editions, assuming the target computers
    # are set up for PowerShell remoting.
    # Note: Invoke-Command does NOT support passing computer names via the pipeline.
    Invoke-Command -ComputerName $a.computername { Get-Process dwm -ComputerName }
    
    • 请注意 purpose-specific cmdlet 上的 -ComputerName 参数,例如 Get-ProcessRestart-Computer 在 PowerShell (Core) 7+ 中不再可用WMI cmdlets,因为它们基于 .NET Remoting, a form of remoting unrelated to PowerShell that has been declared obsolete,因此不属于 .NET Core / .NET 5+。因此,根据定义,手头的错误不会影响 PowerShell (Core)。

错误详情:

该错误特定于以下组合:

  • 通过管道提供具有 .ComputerName 属性 的对象,以便将 属性 值绑定到 -ComputerName 参数

  • 通过 name(s),通过(可能位置隐含的)-Name 参数,或定位 all 进程(既不传递 -Name 也不传递 -Id 参数)

换句话说:通过 PID(进程 ID)定位进程 ,通过 -Id 参数 不受 影响 -但是使用 -Id remotely 仅在您之前从给定计算机获得 PID 并且仅针对 one[=108= 时才有用] 电脑.

在 Windows PowerShell 中,Get-Process-ComputerName 参数旨在将通过管道提供的具有 .ComputerName 属性 的对象绑定到-ComputerName参数:

WinPS> Get-Help Get-Process -Parameter ComputerName

-ComputerName <System.String[]>
    # ...
    Accept pipeline input?       True (ByPropertyName)
    # ...

但是,正如您所观察到的,只有 第一个 以这种方式绑定的计算机名称被 Get-Process-Name 结合使用 - 任何剩余的那些被悄悄地忽略了:

# Target the local machine (.) and a NON-EXISTENT machine ('NOSUCH')
WinPS> [pscustomobject] @{ ComputerName='.' }, 
       [pscustomobject] @{ ComputerName='NOSUCH' } | 
         Get-Process -Name powershell

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    970      48   170860      29120      56.41   4656   1 powershell

也就是说,报告了本地计算机的 PowerShell 进程,non-existent 计算机名称被悄悄忽略了。 注意:Any 后续计算机名称将被忽略,无论它们是否引用现有计算机。使用 non-existent 应该明显地显示为错误。 如果将 -Name powershell 替换为 -Id $PID,您确实会看到错误。

问题是不是参数绑定之一,如Trace-Command调用的输出显示:

WinPS> Trace-Command -pshost -name ParameterBinding { 
         [pscustomobject] @{ ComputerName='.' }, 
         [pscustomobject] @{ ComputerName='NOSUCH' } | Get-Process -Name powershell 
       }

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-Process]
# ...
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-Process]
# ...
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Get-Process]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.PSCustomObject]
# ...
DEBUG: ParameterBinding Information: 0 :     Parameter [ComputerName] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [.] to parameter [ComputerName]
# ...
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.String[]] to param [ComputerName] SUCCESSFUL
# ...
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Get-Process]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.PSCustomObject]
DEBUG: ParameterBinding Information: 0 :     BIND arg [NOSUCH] to parameter [ComputerName]
# ...
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.String[]] to param [ComputerName] SUCCESSFUL
# ...
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing

BIND arg [.]BIND arg [NOSUCH],后跟 SUCCESSFUL 状态,表示两个计算机名称都已正确绑定。

换句话说:错误必须出现在随后使用正确绑定参数的代码中。