1

Is there existing tooling to take text-based output and pipe it to a dynamic object that can be queried as columns?

Specifically, I'm invoking ..

query session /server:MYSERVER 

.. which is outputting ..

SESSIONNAME USERNAME ID STATE TYPE DEVICE services 0 Disc console Jon 1 Active 

This is my first task in a DevOps role, to act upon this output based on conditions of the columns, but after multiple tries to pipe into foreach etc I realized that it's all just multiple lines of strings.

What I was hoping for was something like ..

query session /server:MYSERVER | foreach ` { ` if ($_.Username -eq "Jon") ` {` custom-action $_.ID ` } ` } 

(Note that I do not necessarily need to evaluate the Username, or not only the Username, I am only doing so in this example.)

Obviously this won't work because this ..

query session /server:192.168.1.103 | foreach { echo $_.GetType() } 

.. outputs this ..

IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object True True String System.Object True True String System.Object 

The only solution I've found is manually extracting the columns using String.Substring(). I was hoping there was PowerShell tooling that automated this.

[[This is an example,]] but some columns are blank, and the fixed-width columns are not the same width between each other, so parsing this would be much more manual than the examples there. I was hoping that Powershell version updates might have better tooling perhaps?

Using Windows Server 2012 R2 (which has PowerShell 4).

3 Answers 3

3

There is nothing built in.

However it shouldn't be too hard to create a helper (in a module for easy reuse of course) that takes a definition of each column (eg. name, starting position, length, type, ...; or perhaps alternate criteria to separate the columns if lengths cannot be pre-determined) and creates a custom object.

1
  • see my self-answer as my comment (it was too long to post as a comment) Commented Sep 11, 2013 at 8:13
1

A lot of these pre-PowerShell utilities query various underlying Windows APIs, such as WMI. Before digging into text parsing I'd try and find where the util gets its info from and start from there. For your particular case, I wouldn't be surprised if it actually is querying the Win32_LogonSession WMI class, which you can easily enumerate using PowerShell - and get properly formatted objects back. This approach may not work in all situations, but it would be a good place to start, at least.

$users = get-wmiobject -query "Select * from Win32_LogonSession" 

With a bit of googling, this looks like a promising function for what you need: get-loggedonuser function

1

This is a comment for Richard's response.

This is what I came up with. One would foreach{} on all the lines (except the first line, which is $head) and pass to this function.

Function ParseFixedWidthCols($head,$line) { $colnamematches = $head | select-string "(\s*\w+\b\s*)" -allmatches | foreach { $_.matches } $cols = @() for ($ci=0; $ci -lt $colnamematches.Count; $ci++) { $col = $colnamematches[$ci].Value $cols += $col } $col = $cols[0] $ret = New-Object PSObject $cc = 0 for ($ci=0; $ci -lt $cols.Count; $ci++) { $value = $line.Substring($cc, $cols[$ci].Length) $ret | Add-Member -MemberType NoteProperty -name $cols[$ci].Trim() -value $value.Trim() $cc += $cols[$ci].Length } return ret; } 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.