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(核心)。
- 请注意,特定用途 cmdlet 上的
错误详细信息:
该错误特定于以下组合:
通过管道提供具有
.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/