
close
close
In a previous PowerShell Problem Solver article, I demonstrated how to use regular expressions to take text output and turn it into objects. Once you have objects, you can then take full advantage of PowerShell. I’ll admit that using regular expressions can be a bit vertigo-inducing, so let’s look at another approach.
Again, the assumption is that the text output is in a predictable and known format, where you don’t have any null or empty values. I’m going to use the same text file from my previous article that has RAID and disk information. See the previous article to see what it looks like.
$file = "c:\work\raidreport.txt"
I only want the last part of the file turned into objects.
Figure 1: Text output to convert. (Image Credit: Jeff Hicks)
$h = Get-content $file | select-string "^ID\s+Chassis"
Figure 2: Captured headings. (Image Credit: Jeff Hicks)
$h = $h.ToString() -replace "\(|\)|<|>", ""
Note that because the parentheses characters are special regular expression characters, I need to escape them with a backslash.
If I wanted to cover more possibilities, then I could use this type of pattern:
$h = $h.tostring() -replace "[^\s+|\w]",""
The pattern says to find anything that isn’t a space and isn’t a word character, and replace it with nothing. In either event, $h is now one step cleaner.
Figure 3: Removing extra characters. (Image Credit: Jeff Hicks)
$h = $h.tostring() -replace "(?<=\S)\s{1}(?=\S)", "_"
This is tricky, because I want to leave the spaces between ID and Chassis, but remove them between RAID and ID. So I have to use something called a lookahead and lookbehind. The regular expression pattern is saying, if the current location is a single space, then look behind and see if it is a single non-space character and look ahead for another non-space character. If this is true, then replace the match with an underscore.
Figure 4: Removing spaces within property names. (Image Credit: Jeff Hicks)
$names = $h -split "\s+"
Figure 5: The array of refined property names. (Image Credit: Jeff Hicks)
$d = Get-content $file | select-string "^c0d"
In much the same way as before, I’m going to turn each line into a separate object. To do that, I need to split each line into an array using the spaces as a delimiter. Next, I can loop through the list of property names and create a hashtable using the corresponding value from the split line. The hashtable is then easily turned into a custom object.
$data = foreach ($line in $d) { $info = $line -split "\s+" $hash = [ordered]@{} for ($i=0;$i -lt $names.count;$i++) { $hash.add($names[$i],$Info[$i]) } #end For [pscustomobject]$hash } #end Foreach
The end result is a collection of objects.
Figure 6: New objects displayed in a table. (Image Credit: Jeff Hicks)
Figure 7: Converted object properties are strings. (Image Credit: Jeff Hicks)
$typehash = @{}
foreach ($name in $names) {
$typeHash.Add($Name,(Read-Host "What type is $name, i.e. string or datetime"))
}
Figure 8: Creating a Typename map. (Image Credit: Jeff Hicks)
$data = foreach ($line in $d) { $info = $line -split "\s+" $hash = [ordered]@{} for ($i=0;$i -lt $names.count;$i++) { Switch ($typehash.item($names[$i])) { "string" { $Value = [convert]::ToString($info[$i]) } "int" { $Value = [convert]::ToInt16($info[$i]) } "int32" { $Value = [convert]::ToInt32($info[$i]) } "int64" { $Value = [convert]::ToInt64($info[$i]) } "datetime" { $Value = [convert]::ToDateTime($info[$i]) } "double" { $Value = [convert]::ToDouble($info[$i]) } "boolean" { $Value = [convert]::ToBoolean($info[$i]) } } $hash.add($names[$i],$Value) } #end For [pscustomobject]$hash } #end ForEach
I’ve inserted a switch construct based on the corresponding typehash entry. So if $i is 1, then $names[$i] is ‘Chassis’, which has a corresponding value of ‘int’.
Figure 9: Testing the type hashtable. (Image Credit: Jeff Hicks)
Figure 10: Verifying property types. (Image Credit: Jeff Hicks)
$data | Sort Raid_ID,Slot -Descending | format-table -GroupBy RAID_ID -Property ID,Status,Media,Slot,Size* -AutoSize
Figure 11: Sorted and formatted results. (Image Credit: Jeff Hicks)
Figure 12: A clean text file. (Image Credit: Jeff Hicks)
(get-content C:\work\raidreport3.txt) -replace "\s+","," | convertfrom-csv
Figure 13: Using ConvertFrom-CSV. (Image Credit: Jeff Hicks)
More in PowerShell
Microsoft’s New PowerShell Crescendo Tool Facilitates Native Command-Line Wraps
Mar 21, 2022 | Rabia Noureen
Most popular on petri