2011-05-08 5 views
2

PSList를 좋아하고 CPU 및 경과 시간을 사용하여 죽여야하는 프로세스를 식별합니다. 내가 좋아하는 뭔가를 할 수 있도록 I 파이프 라인 값을 반환하는 파워 쉘 기능에 포장하고 싶은 다음Powershell 함수에서 PSList를 래핑하여 파이프 라인 값을 사용하려고합니다.

get-remoteprocess server1 | where {$_.CPUMinutes -gt 4} 

나는 기능에서 반환 값에 박히 - 내가 할 필요가 이해 객체의 배열 파이프 라인 값으로 잘 작동 나의 약간 적응 버전은, 여기, 유쾌히 간결하다 더그 Finke 사용자의 제안을 복용

function get-remoteproc { 
param ($hostname) 
$results = pslist "\\$hostname" 

for ($i= 3; $i -le $results.length; $i++) { 
    $strline = $results[$i] 
    $StrWithPrefix = " "+$results[$i] 
    $trimmedline = $StrWithPrefix -replace '\s+', " "; 
    $Splitline = $trimmedline.Split(" ") 
    $ProcessName = $Splitline[1] 
    . 
    . 
    $ProcessCPUTime = ":"+[string]$Splitline[7] 
    $SplitCpuTime = $ProcessCPUTime.Split(":") 

    $CpuHours = $SplitCpuTime[1] 
    $CpuMinutes = $SplitCpuTime[2] 
    $CpuSeconds = $SplitCpuTime[3] 
    . 
    . 
    . 

    $obj = New-Object PSObject 
     $obj | Add-Member Noteproperty -Name "Name" -Value $Name 
     $obj | Add-Member Noteproperty -Name "PPid" -Value $Ppid 
     $obj | Add-Member Noteproperty -Name "Pri" -Value $Pri 

} 

:

은 Heres는 내 첫 번째 버전의 모습.

function get-remoteproc { 
    param ($hostname=$env:COMPUTERNAME) 

    $results = PsList "\\$hostname" 

    foreach($record in $results[3..($results.Count)]) { 
     # Remove spaces 
     while ($record.IndexOf(" ") -ge 0) { 
      $record = $record -replace " "," " 
     } 

     $Name,$Processid,$Pri,$Thd,$Hnd,$Priv,$CPUTime,$ElapsedTime = $record.Split(" ") 

     $properties = @{ 
      Name = $Name 
      Pid = $Processid 
      Pri = $Pri 
      Thd = $Thd 
      Hnd = $Hnd 
      Priv = $Priv 
      CPUTime = $CPUTime 
      ElapsedTime = $ElapsedTime 
     } 

     New-Object PSObject -Property $properties | 
      Add-Member -PassThru ScriptProperty CPUH {[int]$this.CPUTime.Split(":")[0]} | 
      Add-Member -PassThru ScriptProperty CPUM {[int]$this.CPUTime.Split(":")[1]} | 
      Add-Member -PassThru ScriptProperty CPUS {[int]$this.CPUTime.Split(":")[2]} | 
      Add-Member -PassThru ScriptProperty ElaH {[int]$this.ElapsedTime.Split(":")[0]} | 
      Add-Member -PassThru ScriptProperty ElaM {[int]$this.ElapsedTime.Split(":")[1]} | 
      Add-Member -PassThru ScriptProperty ElaS {[int]$this.ElapsedTime.Split(":")[2]} 
    } 
} 

그리고 개체가 파이프 라인을 통해 소비를 위해 제대로 풀려 있는지 보여주는 함수를 호출 :

get-remoteproc "Server1" | where {(($_.CPUM * $_.CPUS) -gt 60) -and ($_.name -notmatch "Idle")}| 
ft name, pid, pri, thd, hnd, priv, CPUH, cpuM, cpuS, ElaH, ElaM, ElaS -auto 

감사합니다, 여러분!

+0

함수는 객체를 출력하기 위해 코드 –

답변

0

파이프 라인에 전달 된 값 배열을 하나씩 반환하려면 함수에서 여러 값을 반환하면됩니다. 예를 들어

 
function get-remoteproc { 
param ($hostname) 
    $results = pslist "\\$hostname" 
    for ($i= 3; $i -le $results.length; $i++) { 

    # your staff to $obj 

    # output $obj 
    $obj 
    } 
} 

함수 결과 $obj 배열이다. 파이프 라인에 연결되면 배열이 등록되고 모든 값이 하나씩 스트림에 전달됩니다.

+0

에 미세 라인을 않을거야 무슨 말을하기가 어렵 없이는 닫는 중괄호를 누락'$ obj'은 아주 충분하다. '$ objs'의 사용은 여기서 유효하지 않습니다. (그런 배열의 경우'+ ='는 매우 느린 연산입니다, 참고). –

+0

$ objs는 효과적이지 않지만, $ objs가 될 것이라고 저는 믿습니다. – mjolinor

+0

@Roman : 나는 그렇게 생각하지 않는다. 함수는 필터와 다르게 작동합니다. 이 함수는 후속 파이프 라인에서 처리 할 수 ​​있도록 배열을 반환해야합니다. –

1

empo가 가리키는 것처럼 파이프 라인에 $ obj를 다시 보내야합니다. plist 텍스트를 PowerShell 개체로 작업하는 또 다른 방법입니다.

function get-remoteproc { 
    param ($hostname=$env:COMPUTERNAME) 

    $results = PsList "\\$hostname" 

    foreach($record in $results[3..($results.Count)]) { 
     # Remove spaces 
     while ($record.IndexOf(" ") -ge 0) { 
      $record = $record -replace " "," " 
     } 

     $Name,$Processid,$Pri,$Thd,$Hnd,$Priv,$CPUTime,$ElapsedTime = $record.Split(" ") 

     $properties = @{ 
      Name = $Name 
      Pid = $Processid 
      Pri = $Pri 
      Thd = $Thd 
      Hnd = $Hnd 
      Priv = $Priv 
      CPUTime = $CPUTime 
      ElapsedTime = $ElapsedTime 
     } 

     New-Object PSObject -Property $properties | 
      Add-Member -PassThru ScriptProperty CPUHours {$this.CPUTime.Split(":")[0]} | 
      Add-Member -PassThru ScriptProperty CPUMinutes {$this.CPUTime.Split(":")[1]} | 
      Add-Member -PassThru ScriptProperty CPUSeconds {$this.CPUTime.Split(":")[2]} 

    } 
} 
관련 문제