我需要得到一些业主的进程。下面的演示脚本将首先在本地查找进程的所有者,然后它将做同样的事情,但它调用同一框上的命令:
cls
write-host 'LOCAL CALL: '
$procs = @(Get-WmiObject win32_process |? {($_.getowner().user -eq 'APP_ACCOUNT') })
write-host $procs.count
$func = {
$procs = @(Get-WmiObject win32_process |? {($_.getowner().user -eq 'APP_ACCOUNT') })
write-host $procs.count
}
write-host 'REMOTE CALL: '
$session = New-PSSession -ComputerName 'SERVER'
$job = Invoke-Command -Session $session -ScriptBlock $func -AsJob
Wait-Job -Job $job
$job | Receive-Job
$job | Remove-Job
Remove-PSSession -Session $session
大多数时候,当我运行我的脚本时,它错误地输出如下:
LOCAL CALL:
38
REMOTE CALL:
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
26 Job26 RemoteJob Completed True SERVER ...
Exception calling "GetOwner" : "Not found "
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WMIMethodException
+ PSComputerName : SERVER
38
所以第一个38是它为所有者找到的在本地运行的进程数。第二次也会找到38,但是调用getowner时会出错。我不明白为什么第一次就成功了。当我调用命令时,它是否在某种"气泡"中运行?在我的大型脚本中,这会导致更严重的问题,因为作业状态变为失败,执行停止,即使它抛出相同的错误。不过一次只能解决一个问题。
似乎我需要做一个更好的工作,以确保我的进程仍然存在之前的所有者过滤:
$procs = @()
$allProcs = @(Get-WmiObject win32_process)
foreach($proc in $allProcs)
{
$procActive = get-process -Id $proc.processId -ErrorAction SilentlyContinue
if($procActive)
{
if($proc.getowner().user -eq 'jdholbrook')
{
$procs += $proc
}
}
}
write-host $procs.count
这可能是因为您想要查询所有者的进程已不存在。
您可以在本地PC上模拟此行为,如下所示:
启动一些应用程序,例如notepad.exe
。现在运行:
$w = (Get-WmiObject win32_process) # Your notepad process will now be the last in the `$w` array.
关闭notepad.exe
进程。
现在管道$w
的内容得到所有者:
$w | % {$_.getowner()}
对于最后一个对象,您将得到:
Exception calling "GetOwner" : "Not found "
At line:1 char:20
+ $w | % {$_.getowner <<<< ()}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WMIMethodException
要确保这是您刚刚关闭的notepad.exe
,您可以仔细检查:
$w[-1]; # last object
$w[-1].getowner(); # error
那么,现在你知道是什么导致的,你可以开始考虑如何处理它…