Хотите обернуть PSList в функцию Powershell для использования значений конвейера - PullRequest
2 голосов
/ 08 мая 2011

Мне нравится PSList, и я использую ЦП и истекшее время, чтобы определить процессы, которые нужно уничтожить.Я хотел бы обернуть его в функцию powershell, которая возвращает значения конвейера, чтобы я мог сделать что-то вроде следующего:

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

Я застрял в , возвращая значения из функции - чтоЯ понимаю, что должен быть массив объектов.

Вот как выглядит моя первая версия:

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

}

Принимая предложение Дуга Финке, которое довольно лаконично, вот моя слегка адаптированная версия, который хорошо работает со значениями конвейера.

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

Спасибо всем!

Ответы [ 2 ]

1 голос
/ 08 мая 2011

Как указывает empo, вам нужно отправить $ obj обратно в конвейер. Вот еще один способ преобразования текста списка в объекты 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]} 

    }
}
0 голосов
/ 08 мая 2011

Чтобы вернуть массив значений, переданных в конвейер одно за другим, вам просто нужно вернуть несколько значений в вашей функции.Например:

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

    # your staff to $obj

    # output $obj
    $obj
  }
}

Результатом функции является массив $obj.При подключении к конвейеру массив будет зарегистрирован, и все значения будут переданы потоку одно за другим.

...