如何在Powershell中访问“私人工作集”

时间:2018-07-11 10:17:27

标签: c# windows powershell memory-management process

我正在尝试通过以下代码获取专用的内存工作集。有可能做到吗?

Param(
    [ValidateSet("Pid","Name","CpuPercent","PrivateBytes","Description","ParentPid","SessionId","Handles","Threads","Path")]
    [string] $OrderBy = "Pid",
    $Descending = $false,
    [int] $Top = "99999",
    [ValidateSet("text","csv","json","list")]
    [string] $Format = "json"
)


Set-StrictMode -Version 2.0
$ErrorActionPreference = "stop"


$Desc = [System.Convert]::ToBoolean($Descending);


$PoshProcesses = @(Get-Process)


Function Get-WmiProcPerfSample
{

    Get-WmiObject -Class Win32_PerfRawData_PerfProc_Process -Filter 'IDProcess != 0' -Property IDProcess,CreatingProcessID,PercentProcessorTime,TimeStamp_Sys100NS,ElapsedTime
}


$WmiPerfData = @{}
$sampleSet1 = @{}
Get-WmiProcPerfSample | ForEach-Object {$sampleSet1[$_.IDProcess] = $_}
Start-Sleep -Seconds 1


Foreach ($sample in Get-WmiProcPerfSample) {

    $procTime = $sample.PercentProcessorTime
    $timeWindow = ($sample.TimeStamp_Sys100NS - $sample.ElapsedTime)


    If ($sampleSet1.ContainsKey($sample.IDProcess))
    {
        $procTime = $sample.PercentProcessorTime - $sampleSet1[$sample.IDProcess].PercentProcessorTime
        $timeWindow = $sample.TimeStamp_Sys100NS - $sampleSet1[$sample.IDProcess].TimeStamp_Sys100NS
    }

    $WmiPerfData["$($sample.IDProcess)"] = New-Object -TypeName PSObject -Property @{
        "PID"=$sample.IDProcess;
        "CreatingProcessID"=$sample.CreatingProcessID;
        "PercentProcessorTime"=($procTime / $timeWindow) * 100 / [System.Environment]::ProcessorCount
    }
}

$OutputObjects= @();
foreach ($PoshProcess in $PoshProcesses)
{
    $WmiProcess = $WmiPerfData["$($PoshProcess.Id)"];
    if (-not $WmiProcess -or $PoshProcess.Id -eq 0) {
        continue;
    }


    $OutputObject = New-Object -TypeName PSObject
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Pid -Value $PoshProcess.Id
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Name -Value $PoshProcess.Name
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name CpuPercent -Value ([Math]::Round($WmiProcess.PercentProcessorTime, 2))
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name PrivateBytes -Value $PoshProcess.PrivateMemorySize64
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Description -Value $PoshProcess.Description
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name ParentPid -Value $WmiProcess.CreatingProcessID
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name SessionId -Value $PoshProcess.SessionId
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Handles -Value $PoshProcess.Handles
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Threads -Value $PoshProcess.Threads.Count
    Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name Path -Value $PoshProcess.Path

    $OutputObjects += $OutputObject
    $OutputObject = $Null
}



[System.Collections.ArrayList]$OutPutOrdering = $OutputObjects[0].psobject.Properties | Select-Object -ExpandProperty Name

$OutPutOrdering.Insert(0,$OrderBy)

$OutPutOrdering = $OutPutOrdering | Select-Object -Unique | Foreach-Object {$_.ToString()}

if ($Format -eq 'text')
{
    $OutputObjects `
        | Sort-Object -Property $OrderBy -Descending:$Desc `
        | Select-Object -First $Top -Property $OutPutOrdering -ExcludeProperty Path `
        | Format-Table -AutoSize `
        | Out-String -Width 4096 `
        | Write-Host
}
elseif ($Format -eq 'csv')
{
    $OutputObjects `
        | Sort-Object -Property $OrderBy -Descending:$Desc `
        | Select-Object -First $Top -Property $OutPutOrdering `
        | convertto-csv -NoTypeInformation `
        | Out-String -Width 4096 `
        | Write-Host
}
elseif ($Format -eq 'json')
{
    $OutputObjects `
        | Sort-Object -Property $OrderBy -Descending:$Desc `
        | Select-Object -First $Top -Property $OutPutOrdering `
        | convertto-json `
        | Out-String -Width 4096 `
        | Write-Host
}
elseif ($Format -eq 'list')
{
    $OutputObjects `
        | Sort-Object -Property $OrderBy -Descending:$Desc `
        | Select-Object -First $Top -Property $OutPutOrdering -ExcludeProperty Path `
        | Format-List `
        | Out-String -Width 4096 `
        | Write-Host
}

我知道我们可以通过

(Get-Counter "\Process(*)\Working Set - Private").CounterSamples

但是我想尽可能在​​当前代码中使用“私有工作集”,因为我也需要JSON输出。是否可以对所有pid同时使用Get-Counter?如何在上面的代码中实现它?如果您知道,也可以使用其他方法。

0 个答案:

没有答案