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.
To find a string inside of a string with PowerShell, you can use the Substring() method. This method is found on every string object in PowerShell. The first argument to pass to the Substring() method is the position of the leftmost character. In this case, the leftmost character is T .
The $_ is a variable or also referred to as an operator in PowerShell that is used to retrieve only specific values from the field. It is piped with various cmdlets and used in the “Where” , “Where-Object“, and “ForEach-Object” clauses of the PowerShell.
To split long command into multiple lines, use the backtick (`) character in the command where you want to split it into multiple lines.
Firmware = ($Status | Select-String -Pattern '\d{1}\.\d{1,2}\.\d{1,2}' -AllMatches | % { $_.Matches } | % { $_.Value }
$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).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With