Powershell: Filter out specific value from custom output of a program

Viewed 690

Have a utility program which outputs some data as below format:

PS C:\> C:\Users\abc\Desktop\Tools\testApp.exe -i
TestApp version 1.5, Copyright (c) 2021 ABC, Inc.


abcadxx an bn cn id       name           model       xsize   test p/n
======= == == == ==== =============== ============== ======= ==== ==============
   0    09 00 00 73A0 Abc1x          Abc10LX          10000  pass 113-D41LXT-011    

I want to filter out the value of name in this case Abc1x I've tried Select-Object -Property 'name' but getting

PS C:\> C:\Users\abc\Desktop\Tools\testApp.exe -i | Select-Object -Property 'name'

name
----

Tried ExpandProperty but that threw error. Since this is a custom output how can I get the value of name?

3 Answers

What an external program outputs is a stream of text lines (strings) from PowerShell's perspective, not a stream of objects whose properties you can access.

  • As the comments note, if you can get your external program to output a structured text format (via a program-specific parameter), such as CSV, you can let PowerShell convert it to objects via a cmdlet such as Import-Csv, which then enables OO processing.

Absent that, you need to perform text parsing.

  • Avshalom's helpful answer shows how to transform the for-display text output to CSV format, which then allows you to parse it into objects.

  • If you're only interested in one value from the name column (the 6th), you can use the following shortcut:

(-split (C:\Users\abc\Desktop\Tools\testApp.exe -i)[-1])[5]
  • (C:\Users\abc\Desktop\Tools\testApp.exe -i) collects testApp.exe's output lines in an array (assuming two or more output lines), and [-1] extracts the last output line, assumed to contain the data of interest:

  • The unary form of the -split operator splits that line into fields by whitespace, and [5] returns the 6th field.

Well I don't have your program to test, but just for example:

I converted it to text like this:

$text = @"
abcadxx an bn cn id       name           model       xsize   test p/n
======= == == == ==== =============== ============== ======= ==== ==============
   0    09 00 00 73A0 Abc1x          Abc10LX          10000  pass 113-D41LXT-011
"@ -split "\n" ## The split will make it array of lines...

Then remove the decorator line [=======]:

$text = $text | ? {$_ -notmatch "^="}

Then replace the white space with commas and get rid of the first comma in the abcadxx row as it has two spaces instead of one like all other rows:

$text -replace '\s{1,}',',' -replace "^," 

So it will look like that:

abcadxx,an,bn,cn,id,name,model,xsize,test,p/n,
0,09,00,00,73A0,Abc1x,Abc10LX,10000,pass,113-D41LXT-011

Then finally convert it from CSV and select the value of the Name column:

$text -replace '\s{1,}',',' -replace "^," | 
ConvertFrom-Csv | Select -ExpandProperty Name

Will show the desirable value:

Abc1x
Related