6

I'm using Windows 2012 powershell to scrape values from a 3rd party executable. My goal is to re-arrange and simplify the output of the tool to display only a subset of the content and allow me to collect the data on many devices at once. I have most of the script working, but I'm stuck on a simple task that's so easy in Linux bash.

The 3rd party program is pulling status of a computer device to standard out. I can successfully set the standard out content to a variable. For example:

PS C:\> $status = mycmd.exe device1 --status
PS C:\> $status

The $status variable would return a multi-line list of values as follows:

Device Number:  1
PCIe slot:  3
Firmware Version:  5.1.4
Temperature:  45C
State:  Online

In this case, I would like to create a new variable for the firmware version. In Linux I would use something like this (although there are many options available):

Firmware=$(mycmd device1 --status | grep "Firmware" | cut -c 19-24)

In Powershell I can use the Select-String command to can find the "firmware" pattern and set it to a varible as follows:

$Firmware = $Status | select-string -Pattern "Firmware Version"

This gives me the entire Firmware version line. I can't figure out how to substring just the version number from the line as Powershell seems to only want to manipulate the item I'm searching for and not the content next to the pattern. Since this isn't a built in command with an object name, manipulating text seems much more difficult.

I would like the $Firmware variable to equal "5.1.4" or it could be placed into another variable if necessary.

1
  • Thank you for the extremely helpful examples. I was able to make use of several technique immediately and will find situations for the others. Commented Sep 9, 2014 at 21:12

5 Answers 5

3
Firmware = ($Status | Select-String -Pattern '\d{1}\.\d{1,2}\.\d{1,2}' -AllMatches | % { $_.Matches } | % { $_.Value }
Sign up to request clarification or add additional context in comments.

Comments

2
$Firmware = ($Status | Select-String -Pattern '(?<=Firmware Version:\s+)[\d.]+').Matches.Value

The regular expression here is looking for 1 or more combinations of digits \d and literal dots which are preceded by the Firmware Version: line.

Note that Select-String returns an object, so we use .Matches.Value to get the actual match (which in this case will only be the number).

Comments

1

Using -replace with a multi-line regex:

$Var = 
@'
Device Number:  1
PCIe slot:  3
Firmware Version:  5.1.4
Temperature:  45C
State:  Online
'@

$Firmware = $var -replace '(?ms).+^Firmware Version:\s+([0-9.]+).+','$1'
$Firmware

5.1.4

1 Comment

The purpose of the '(?ms) in the regular expression here is explained at stackoverflow.com/questions/27680097/what-does-ms-in-regex-mean
0

This works...I set used a [system.version] to parse the version number (and remove spaces).

$FirmwareLine = $Status | select-string -Pattern "Firmware Version"| select -expand line
[system.version]$firmware=$firmwareLine -split ":" | select -first 1 -skip 1

If you just need the string, you can remove the "cast"

$firmware=$firmwareLine -split ":" | select -first 1 -skip 1 

Comments

0

Another option is to replace the colons with '=', converting the output to key=value pairs and then turn that into a hash table (and then to a PS Object if you want) using ConvertFrom-StringData:

$Var = 
@'
Device Number:  1
PCIe slot:  3
Firmware Version:  5.1.4
Temperature:  45C
State:  Online
'@

$DeviceStatus = New-object PSObject -Property $(ConvertFrom-StringData $var.Replace(':','='))

$DeviceStatus.'Firmware Version'

5.1.4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.