Reputation: 3
I have a situation that I have to read a log file with many dumped user attributes generated in the past with out-file command.
The format of the text is:
Num : 1
Property2 : Some Char
Property3 : Some Text
Property4 : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC=Some Text,DC=net
Property5 : Some Text
Property6 : Some Text@Some Text.Some Text.Some Text.net
Property7 : Some Text
Property8 : Multiple line text
Multiple line text
Multiple line text
Multiple line text
Property9 : Some Char
Num : 2
Property2 : Some Char
Property3 : Some Text
Property4 : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC=Some Text,DC=net
Property5 : Some Text
Property6 : Some Text@Some Text.Some Text.Some Text.net
Property7 : Some Text
Property8 : Multiple line text
Multiple line text
Multiple line text
Multiple line text
Property9 : Some Char
Is there a way to import this and to have a structure property - value. Something like PSobject? I have to do a search in for each user in his multiline property (Property 8) based on criteria and to extract only dose users that match this criteria.
Upvotes: 0
Views: 306
Reputation: 61253
To parse this and format the way you want in a CSV file, I'd suggest using an odered Hashtable to parse the content of the file and afterwards convert this into an array of PsCustomObjects for outputting the file with headers
# create an ordered Hashtable to store the results
$hash = [ordered]@{}
foreach ($line in (Get-Content -Path 'D:\Test\TheInputLOgFile.txt')) {
if ($line.IndexOf(':') -gt 0) {
$name, $value = $line -split '\s*:\s*', 2
$hash[$name] = $value
}
else {
$hash[$name] += [Environment]::NewLine + $line.Trim()
}
}
If you output the hash straight away you'll get
$hash | Format-List
Name : Property1 Value : Some Char Name : Property2 Value : Some Char Name : Property3 Value : Some Text Name : Property4 Value : CN=Some Text,OU=Some Text,DC=Some Text,DC=Some Text,DC=Some Text,DC=net Name : Property5 Value : Some Text Name : Property6 Value : Some Text@Some Text.Some Text.Some Text.net Name : Property7 Value : Some Text Name : Property8 Value : Multiple line text Multiple line text Multiple line text Multiple line text Name : Property9 Value : Some Char
To turn this into a CSV with headers Attribute
and Value
, you can do this:
$hash.GetEnumerator() | Foreach-Object {
[PsCustomObject]@{
'Attribute' = $_.Name
'Value' = $_.Value
}
} | Export-Csv -Path 'D:\Test\LogResult.csv' -UseCulture -NoTypeInformation
When you double-click this file to open in Excel (and set the cell alignment to Wrap text), it will look like this:
EDIT
If you have more items in the input file like in your new example, you will need an extra loop for every block of data in there.
This can be done like below:
# split the content of the file in text blocks on the double NewLine
$blocks = (Get-Content -Path 'D:\Test\TheInputLogFile.txt' -Raw) -split '(\r?\n){2,}'
# loop through each textblock, split the lines, build and convert
# the the Hashtable and capture the results in variable $result
$result = $blocks | ForEach-Object {
# create an ordered Hashtable to store the results
$hash = [ordered]@{}
foreach($line in ($_ -split '\r?\n')) {
if ($line.IndexOf(':') -gt 0) {
$name, $value = $line -split '\s*:\s*', 2
$hash[$name] = $value
}
elseif ($line -match '\S') {
$hash[$name] += [Environment]::NewLine + $line.Trim()
}
}
$hash.GetEnumerator() | Foreach-Object {
[PsCustomObject]@{
'Attribute' = $_.Name
'Value' = $_.Value
}
}
}
$result | Export-Csv -Path 'D:\Test\LogResult.csv' -UseCulture -NoTypeInformation
The output when opened in Excel will now show:
Upvotes: 1