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

标签 powershell powershell-remoting

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 中遇到了错误 - 有关详细信息,请参阅底部部分。

  • 鉴于 Windows PowerShell 今后只会看到关键修复,因此错误不太可能得到修复

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

    # Windows PowerShell only.
    Get-Process dwm -ComputerName $a.computername
    
  • 从更广泛的角度来看,考虑改用 PowerShell 的 remoting ,其中只有通用 Invoke-Command cmdlet 有助于使用现代的、防火墙友好的传输方式远程执行任意命令。同样,CIM使用相同传输的 cmdlet(例如 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 }
    
    • 请注意,特定用途 cmdlet 上的 -ComputerName 参数,例如 Get-Process重新启动计算机在 PowerShell (Core) 7+ 中不再可用WMI cmdlet 也不再可用,因为它们基于 .NET Remoting ,一种与 PowerShell 无关的远程处理形式,已声明 obsolete因此不是 .NET Core/.NET 5+ 的一部分。根据定义,当前的错误不会影响 PowerShell(核心)。

错误详细信息:

该错误特定于以下组合:

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

  • 通过(可能是位置隐含的)-Name 参数按名称定位进程,或定位所有进程(既不传递 -Name 也不传递 -Id 参数)

换句话说:通过 -Id 参数按 PID(进程 ID)定位进程受影响 - 但使用 -Id 远程仅在您之前从给定计算机获取了 PID 并且仅针对一台计算机时有用。

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

WinPS> Get-Help Get-Process -Parameter ComputerName

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

但是,正如您所观察到的,Get-Process-Name 结合使用时,只会尊重以这种方式绑定(bind)的第一个计算机名称> - 任何剩余的都会被悄悄忽略:

# 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 进程会被报告,并且不存在的计算机名称会被悄悄忽略。 注意:任何后续计算机名称都将被忽略,无论它们是否引用现有计算机。使用不存在的值应该会明显地被视为错误。 如果将 -Name powershell 替换为 -Id $PID,您确实会看到错误。

问题是不是参数绑定(bind)之一,如 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 状态,表明两个计算机名称均已正确绑定(bind).

换句话说:错误必须存在于随后使用正确绑定(bind)参数的代码中。

关于powershell - Get-Process -computername 管道输入仅适用于名字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72280138/

相关文章:

powershell - 从路径中删除最后一个扩展名

powershell - Azure VM 连接错误 - 用户帐户当前已禁用且无法使用

powershell - 在Powershell中使用7z解压缩文件

powershell - 使用 Kerberos 进行机器身份验证时 CredSSP PowerShell session 失败

powershell - 测试运行后,nunit-console在远程Powershell session 中挂起

windows - 通过 PowerShell 使用路径组件创建注册表项

excel - 从 .csv 中的列中提取数据

powershell - 如何在PowerShell中 “grep”并显示周围的行/上下文?

powershell - 是否可以通过 Powershell 远程处理以 "nt authority\system"启动进程?

powershell-2.0 - 远程启用 Psremoting