2013-06-13 5 views
1

소유자가 procs를 가져와야합니다. 아래 내 데모 스크립트는 먼저 로컬, 다음은 같은 일을 할 것입니다 소유자가 발동을 찾을 것입니다,하지만 같은 상자에 명령을 호출 :Powershell : "GetOwner"예외 호출 : 작업으로 호출 할 때 "찾을 수 없음"

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를 호출하는 데 오류가 발생했습니다. 나는 그것이 처음 일한 이유를 이해하지 못한다. 명령을 호출 할 때 어떤 종류의 "거품"으로 작동합니까? 내 큰 스크립트에서는 작업 상태가 실패로 돌아가고 동일한 오류가 발생하더라도 실행이 중단되므로이 문제가 더 심각한 문제로 나타납니다. 하나의 문제는 한 번에.

답변

1

이것은 아마도 소유자를 쿼리하려는 프로세스가 더 이상 존재하지 않기 때문일 수 있습니다. 다음과 같이

당신은 당신의 로컬 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 당신은 당신이 두배로 할 수있다 닫혀 있는지 확인하기 위해 -check :

$w[-1]; # last object 
$w[-1].getowner(); # error 

이제 무엇이 원인인지 알 수 있습니다.

$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 
+0

다보르 하나 개 여기에 조각 혼란이를 : 당신은 –

+0

@JustinHolbrook _ 나는 getowner 호출에 get-wmiobject 권한의 결과를 파이핑하므로 무시할 수없는 지연이 예상됩니다 ._' Get-WmiObject win32_process'의 내부 작업에 대해서는 확신 할 수 없습니다. 파이프를 시작하기 전에 프로세스 목록을 캐싱 할 수도 있습니다. 어쨌든, 당신은 항상 프로세스와 getowners를 기록 할 수 있습니다. 나는 어떤 프로세스가이 오류를 일으키는 지 알게되면 많이 배울 것이라고 생각합니다. 나는 당신의 연구 결과에 호기심을 갖고 있습니다. –

+0

나는 그 오류에 대한 범인 인 내 프로세스가 아닌 것을 깨달았다. 나는 모든 프로세스가 getowner에게 piping하는 중이다. 원격으로 호출하면 시간이 오래 걸리기 때문에 일부 프로세스가 종료되는 데 충분한 지연이 발생할 수 있습니다. 이것은 제가 관심을 가지고있는 프로세스의 수를 일정하게 유지하는 이유를 설명합니다. –

2

나는 여전히 소유자에 의해 필터링하기 전에 존재해야합니다 내 프로세스를 만드는 더 나은 일을 할 필요가 보인다 ... 그것을 처리하는 방법에 대한 생각을 시작할 수 있습니다. 데모 스크립트를 여러 번 실행하고 반복적으로 38 개의 procs를 얻습니다. 나는 카운트가 전혀 변동하지 않는 것을 정말로 보지 못한다. 또한 나는 procs를 발견 할 때부터 getowner를 호출 할 때까지 기다리지 않고 있습니다. get-wmiobject의 결과를 getowner 호출에 파이프하는 중이므로 무시할 수있는 지연이 예상됩니다. 이것이 재생산 될 수있는 지연의 종류가 아닙니다. 또한 원격 호출 중에 만 발생하는 것으로 보이는 사실은 매우 문제가 있습니다.
+1

이것은 좋은 해결책이지만'$ _. getowner()'에서'try/catch'를 사용하는 것이 더 좋고/더 안전 할 것이며 아마도 더 우아 할 것입니다. –

+0

아마 시간이 허락하는 한 내 예를 바꿀 것입니다. 다른 사람들이이 주제를 다룰 경우에 대비 한 작업 예제를 문서화하고 싶습니다. 자유롭게 답변에 추가하면 솔루션으로 지정하겠습니다. –