Iron Scripter 2019 is Coming

It is a new year and the Chairman is preparing a fiendish new challenge for this year’s PowerShell + DevOps Summit. That time is rapidly. If you partook in last year’s battle then you understand what is expected of you. if you have not already done so align yourself with the faction that best suits you.

In order to prepare you for battle the Chairman has prepared a series of preparatory challenges. It is a foolish warrior who goes into battle unprepared. Just sayin’.

To prepare you for the upcoming battle, see what you can create according to the guiding principles of your faction that solves the following problem. The bottom line is that your solution should work.





The Challenge

The Get-Counter cmdlet is very useful in obtaining performance counter information. Unfortunately, the Chairman feels the output is less than friendly. Especially if you wish to consume the output such as with additional filtering, exporting to a json file or writing to a database.

Your challenge is to create a PowerShell function that takes the output from Get-Counter and transforms it into a more user friendly object. Each counter sample should be a separate object with these properties:

  • Timestamp
  • Computername
  • CounterSet
  • Counter
  • Value

You are free to use whatever property names you want as long as it is clear what the values represent. A sample might look like this:

PS C:\> Get-Counter -computername server01 | MyFunction
Datetime    : 2/6/2019 1:34:30 PM
Computername: SERVER01
Counterset  : memory
Counter     : cache faults/sec
Value       : 0
Datetime    : 2/6/2019 1:34:30 PM
Computername: SERVER01
Counterset  : physicaldisk(_total)
Counter     : % disk time
Value       : 5.63389896275325

Advanced Challenge

If you want to really challenge yourself, define a custom type and format view that gives you a result like this:

PS C:\> get-counter -computername server01 | myfunction
   Timestamp: 2/6/2019 4:51:34 PM
Computername Counterset                                                  Counter                              Value
------------ ----------                                                  -------                              -----
SERVER01     network interface(intel[r] ethernet connection [2] i219-lm) bytes total/sec            63.933330323139
SERVER01     processor(_total)                                           % processor time          2.29286092227079
SERVER01     memory                                                      % committed bytes in use  58.2262708009747
SERVER01     memory                                                      cache faults/sec          9.98958286299047
SERVER01     physicaldisk(_total)                                        % disk time               0.06629201377444
SERVER01     physicaldisk(_total)                                        current disk queue length                0

All the information you need to know is included in this post. The Chairman will share a possible solution within the week. Good Luck and Good Scripting!


9 Replies to “Iron Scripter 2019 is Coming”

    • Daniel Evans

      I took a shot at this and here’s what I came up with. The function allows you to specify -tableView $true or $false, and the results will display accordingly as specified by the challenge criteria. If you do not declare -tableView when calling the function, it will default to false and display the list.

      function Parse-CounterData($input, [bool]$tableView)
      {

      $objectArray = @()
      $functionData = $input.CounterSamples | Select Path, CookedValue, Timestamp
      $functionData | Foreach-Object {

      $varPath = $_.Path
      $pathObjects = $varPath.Split(‘\’)

      $object = New-Object -TypeName PSObject
      $object | Add-Member -MemberType NoteProperty -Name ComputerName -Value $pathObjects[2]
      $object | Add-Member -MemberType NoteProperty -Name CounterSet -Value $pathObjects[3]
      $object | Add-Member -MemberType NoteProperty -Name Counter -Value $pathObjects[4]
      $object | Add-Member -MemberType NoteProperty -Name Value -Value $_.CookedValue

      If ($tableView -ne $true)
      {
      Return $object
      }
      else
      {
      $objectArray += $object
      $timestamp = “Timestamp: ” + $_.Timestamp
      }
      }

      If ($tableView -eq $true)
      {

      Return $timestamp, $objectArray | Format-Table
      }

      }

      Get-Counter | Parse-CounterData -tableView $true

  1. Rob Hagman

    Who needs a function

    Get-Counter|foreach-object{
    $Timestamp = $_ |Select-object -expandproperty Timestamp
    $_.CounterSamples | Where-object {$_.path -match “\\\\(.*)\\(.*)\((.*)\)\\(.*)”} | foreach-object{
    $_|Select-object @{l=’Timestamp’;e={$Timestamp}},
    @{l=’Computername’;e={$matches[1]}},
    @{l=’Counterset’;e={$matches[2]}},
    @{l=’Instance’;e={$matches[3]}},
    @{l=’Counter’;e={$matches[4]}},
    @{l=’Value’;e={$_.CookedValue}}
    }}|format-table

    to simple for a function really

  2. Radjin Sardjoe Missier

    function MyFunction {
    param(
    [parameter(Mandatory, ValueFromPipeline)] [object] $InputObject
    )

    $InputObject.CounterSamples | ForEach-Object {
    [void] ($_.Path -match ‘\\\\(?.+?)\\(?.+?)\\(?.+)’)
    $_ | Select-Object -Property @{n=’Datetime’; e={$_.Timestamp}},
    @{n=’Computername’; e={$matches.Computername}},
    @{n=’Counterset’; e={$matches.Counterset}},
    @{n=’Counter’; e={$matches.Counter}},
    @{n=’Value’; e={$_.CookedValue}}
    }
    }

Comments are closed.