skrenato
skrenato

Reputation: 97

Reduce output from three commands to one line

I have this script:

$counterWS = "\Process(powershell)\Working Set"
$counterWSPe = "\Process(powershell)\Working Set Peak" 
$counterWSPr = "\Process(powershell)\Working Set - Private"

$dataWS = Get-Counter -Counter $counterWS
$dataWSPe = Get-Counter -Counter $counterWSPe
$dataWSPr = Get-Counter -Counter $counterWSPr

$dataWS.countersamples | Format-Table Timestamp,@{Name='WorkingSet';Expression={($_.CookedValue/1KB)}},WorkingSetPeak,WorkingSetPrivate -Auto | findstr Timestamp
$dataWS.countersamples | Format-Table Timestamp,@{Name='WorkingSet';Expression={($_.CookedValue/1KB)}},WorkingSetPeak,WorkingSetPrivate -Auto | findstr [-]

while ($true) {
    $dataWS.countersamples | Format-Table Timestamp,@{Name='WorkingSet';Expression={($_.CookedValue/1KB)}},WorkingSetPeak,WorkingSetPrivate -Auto | findstr [:]
    $dataWSPe.countersamples | Format-Table Timestamp,WorkingSet,@{Name='WorkingSetPeak';Expression={($_.CookedValue/1KB)}},WorkingSetPrivate -Auto | findstr [:]
    $dataWSPr.countersamples | Format-Table Timestamp,WorkingSet,WorkingSetPeak,@{Name='WorkingSetPrivate';Expression={($_.CookedValue/1KB)}} -Auto | findstr [:]
    Start-Sleep -s $args[0]
}

and the result is like:

Timestamp           WorkingSet WorkingSetPeak WorkingSetPrivate
---------           ---------- -------------- -----------------
29/07/2016 18:41:12      10644                                 
29/07/2016 18:41:13                     10676                  
29/07/2016 18:41:14                                        3056

Is there a way to reduce to make output like this:

Timestamp           WorkingSet WorkingSetPeak WorkingSetPrivate
---------           ---------- -------------- -----------------
29/07/2016 18:41:12      10644          10676              3056

Upvotes: 3

Views: 277

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200273

Collect all 3 counters at once (the parameter -Counter accepts a list of arguments), then split the result into separate calculated properties:

$ws     = '\Process(powershell)\Working Set'
$wsPeak = '\Process(powershell)\Working Set Peak'
$wsPriv = '\Process(powershell)\Working Set - Private'

Get-Counter -Counter $ws, $wsPeak, $wsPriv |
    Select-Object Timestamp,
        @{n='WorkingSet';e={$_.CounterSamples[0].CookedValue / 1KB}},
        @{n='WorkingSetPeak';e={$_.CounterSamples[1].CookedValue / 1KB}},
        @{n='WorkingSetPrivate';e={$_.CounterSamples[2].CookedValue / 1KB}}

The CounterSamples property is a list of PerformanceCounterSample objects that can be accessed individually by index.

If you don't want to rely on the results being returned in the order of the parameters passed to Get-Counter you can select them by their path, e.g. like this:

@{n='WorkingSetPeak';e={
  ($_.CounterSamples | Where-Object { $_.Path -like '*peak' }).CookedValue / 1KB
}}

For continuous sample collection add the parameters -Continuous and -SampleInterval to Get-Counter. A loop is not required.

$interval = 5  # seconds

Get-Counter -Counter $ws, $wsPeak, $wsPriv -Continuous -SampleInterval $interval |
    Select-Object ...

Upvotes: 4

Related Questions