我正在尝试获取远程计算机上的进程 运行 已加载的模块

I am trying to obtain modules that a process running on a remote computer has loaded

如何使用 PowerShell 获取远程计算机上的进程 运行 加载的模块。

有些进程模块出现错误,例如权限被拒绝和无法枚举。我该如何解决这些错误。

Cannot enumerate the modules of the "services" process.+ CategoryInfo : PermissionDenied: (System.Diagnostics.Process (services):Process) [Get-Process], ProcessCommandException+ FullyQualifiedErrorId : CouldnotEnumerateModules,Microsoft.PowerShell.Comands.GetProcessCommand + PSComputerName

使用命令:

$Module = Invoke-Command -Session $session -ScriptBlock { Get-Process -Module }

该问题并非特定于远程处理:有些进程的模块根本[1] 由于缺少权限而无法枚举,即使 运行 海拔(作为管理员).

由于错误报告是非终止错误,您可以简单地忽略(所有)错误-ErrorAction Ignore 来源:

Invoke-Command -Session $session -ScriptBlock { Get-Process -Module -ErrorAction Ignore }

如果要捕获错误消息,以便确定枚举失败的进程,请使用 -ErrorVariable errs -ErrorAction SilentlyContinue,它会消除错误,但会收集它们在变量 $errs 中供以后检查:

Invoke-Command -Session $session -ScriptBlock { Get-Process -Module } -ErrorVariable errs -ErrorAction SilentlyContinue

具体来说,$errs.TargetObject将列出无法枚举其模块的进程对象。


如果目的是查找(并可能杀死)所有使用感兴趣的模块 (DLL) 的进程,请使用标准 tasklist.exe utility or taskkill.exe utility/m 参数.

$moduleOfInterest = 'oleaut32.dll' # example DLL
$pids = (tasklist /m $moduleOfInterest /fo csv | ConvertFrom-Csv).PID

# Alternatively, use `taskkill` in lieu of `tasklist` above in 
# order to kill the processes directly.
if ($pids) { Stop-Process -Id $pids -WhatIf }

注意:上面命令中的-WhatIf common parameter预览操作。删除 -WhatIf,一旦您确定该操作将执行您想要的操作。

但是,使用这种方法您也可能 运行 遇到权限问题。

请注意,tasklist.exetaskkill.exe 通过参数 /S 具有内置远程功能,允许将单个远程计算机作为目标。

但是,使用 PowerShell 的通用远程处理(通过 Invoke-Commands -ComputerName / -Session 参数)为您提供了更大的灵活性,特别是针对 多个目标的能力 台并行计算机。


[1] 至少在默认情况下,仅靠海拔是不够的;如果有人知道是否有办法枚举,请告诉我们。 This related question 专门询问该信息。