PowerShell管道中如何访问外部Get-Process对象属性以避免重复调用?
解决PowerShell管道中访问上层对象属性的问题
嘿,这个问题提得很到位!你说得没错,完全没必要在Select-Object里重复调用Get-Process——咱们可以通过在ForEach-Object脚本块中暂存上层对象的方式,直接复用之前获取到的进程属性,既高效又简洁。下面给你两种实用的实现方式:
方法一:暂存进程对象到变量
在ForEach-Object的脚本块里,先把当前的进程对象(也就是Get-Process返回的$_)存到一个自定义变量中,后续处理TCP连接时直接引用这个变量即可,不用再重新查询进程:
$searchfor = @("wininit","TeamViewer") Get-Process $searchfor | ForEach-Object { # 暂存当前进程对象,避免后续重复调用Get-Process $currentProc = $_ Get-NetTCPConnection -OwningProcess $currentProc.ID | Select-Object ` @{Name='Process';Expression={$currentProc.ProcessName}}, LocalAddress, LocalPort, RemoteAddress, RemotePort, State }
原理说明:
- 当你在
Get-Process的管道中时,$_代表当前的进程对象; - 调用
Get-NetTCPConnection并进入它的管道后,$_会变成NetTCPConnection类型的对象,此时无法直接通过$_获取之前的进程属性; - 提前把进程对象存到
$currentProc变量里,就能在后续的Select-Object表达式中直接复用该对象的所有属性(比如ProcessName、Id、Path等)。
方法二:一次性传递所有需要的进程属性
如果需要展示更多进程相关信息,可以直接把进程的多个属性一起传递,让输出结果更丰富:
$searchfor = @("wininit","TeamViewer") Get-Process $searchfor | ForEach-Object { $proc = $_ Get-NetTCPConnection -OwningProcess $proc.ID | Select-Object ` @{Name='ProcessName';Expression={$proc.ProcessName}}, @{Name='ProcessId';Expression={$proc.Id}}, @{Name='ProcessPath';Expression={$proc.Path}}, LocalAddress, LocalPort, RemoteAddress, RemotePort, State }
这种方式不仅省去了重复查询进程的开销,还能避免因为进程在查询间隙退出导致的“找不到进程ID”错误。
内容的提问来源于stack exchange,提问作者SimonS
相关产品推荐
相关产品推荐

