Reputation: 73
I am currently working on a PowerShell script that converts text file reports into a series of tables in a HTML
file using the ConvertTo-Html
cmdlet. A section in the text file look something like this:
+-------------------------------------------------------------------------+ ¦Operating System Info: ¦ +-------------------------------------------------------------------------+ Operating System: Microsoft Windows Server 2008 R2 Standard Service Pack: Service Pack 1 Product Type: Server Product ID: 55041-266-0358183-84672 Architecture: 64-bit Install Date: 2013-04-11 11:58:26 Encryption Level: 256 bit Local Time: 2016-02-18 08:06:58 Last Bootup Time: 2015-08-13 07:10:00 Total Physical Memory: 18863924 KB Free Physical Memory: 14811704 KB Total Virtual Memory: 37725992 KB Free Virtual Memory: 33103616 KB Data Execution Prev: DEP is enabled for Windows services only (OptIn - Windows Default) +-------------------------------------------------------------------------+ ¦Computer Info: ¦ +-------------------------------------------------------------------------+ Computer Name: COMPNAME DNSHostName: COMPNAME Pinging aaccms2 [172.20.78.132] with 32 bytes of data: Reply from 172.20.78.132: bytes=32 time
Instead of keeping the spacing it had earlier.
So my questions is, is there any way I can get the table to split into a new column after a certain character or set of characters, like say ": "? I have also made a few tests that append things to the file before it is written to HTML
resulting in things like:
Total Physical Memory: 16000000 KB: PASS
So if I could split it into three columns, one for the title, one for the value, and one for the pass fail that would be even better. My PowerShell conversion looks like this:
foreach ($Line in $Table) {
# Converts each line to HTML output, does not include lines that have
# text file spacers, blank lines, or titles in the line (titles added
# later)
if ($Line -ne "+-------------------------------------------------------------------------+" `
-and $Line -ne "+-----------------------------------------------------------------------------------+" `
-and $Line -ne "" `
-and $Line -ne $Titles[$count]) {
$Object = New-Object -TypeName PSObject
Add-Member -InputObject $Object -Type NoteProperty -Name AACC -Value $Line
$Document += $Object
}
}
$CurrentTitle = $Titles[$count]
$Frag += $Document |
ConvertTo-Html -As TABLE -Fragment -PreContent "<h2 align = center id = $CurrentTitle;> $CurrentTitle </h2>" |
Out-String # Adds the new HTML fragment (table) to the frag array
ConvertTo-Html -Title $FileName -Head $head -PostContent $Frag -Property AACC -Body $Body |
Out-File $TargetFile # Outputs the new HTML file
The $head
variable where I set up the table layout looks like
$Title = "<title> $Filename Report</title>"
$CSSStyle = @'
<style>
ul {
padding-left: 0px;
}
body { background-color:White;
font-family:Tahoma;
font-size:12pt;
}
td, th {border:1px solid black;}
th {
color: black;
background-color:#C11B17;
}
td { border-width: 1px;padding: 0px;border-style: solid;border-color: black; }
TR:Hover TD { Background-Color: #C1D5F8; }
table, tr, td, th { align:left; padding: 2px; margin: 0px; }
table { width:100% }
table { margin-left:0px; }
</style>
'@
$Head = $Title + $CSSStyle
Upvotes: 3
Views: 2859
Reputation: 58991
I would start to filter all unecessary lines using a simple regex:
Get-Content 'your_file' | Where { $_.Trim() -notmatch '[+¦]|^$' }
Ouput:
Operating System: Microsoft Windows Server 2008 R2 Standard
Service Pack: Service Pack 1
Product Type: Server
Product ID: 1234-5678
Architecture: 64-bit
Install Date: 2013-01-01 01:01:01
Encryption Level: 256 bit`
Total Physical Memory: 16000000 KB
Then use another regex to capture the keys and values and create a PSCustomObject
from it:
Get-Content 'your_file' | Where { $_.Trim() -notmatch '[+¦]|^$' } | foreach {
$regexMatch = [regex]::Match($_.Trim(), '(?<Key>[^:]+):\s+(?<Value>.+)')
[PSCustomObject]@{
Key = $regexMatch.Groups['Key'].Value
Value = $regexMatch.Groups['Value'].Value
}
}
Output:
Key Value
--- -----
Operating System Microsoft Windows Server 2008 R2 Standard
Service Pack Service Pack 1
Product Type Server
Product ID 1234-5678
Architecture 64-bit
Install Date 2013-01-01 01:01:01
Encryption Level 256 bit`
Total Physical Memory 16000000 KB
Now you can pipe the output to the ConvertTo-Html cmdlet:
Get-Content 'your_file' | Where { $_.Trim() -notmatch '[+¦]|^$' } | foreach {
$regexMatch = [regex]::Match($_.Trim(), '(?<Key>[^:]+):\s+(?<Value>.+)')
[PSCustomObject]@{
Key = $regexMatch.Groups['Key'].Value
Value = $regexMatch.Groups['Value'].Value
}
} | ConvertTo-Html -Title $FileName -Head $head | out-file $TargetFile
Edit to your comment:
I would start to seperate the sections:
$content = Get-Content 'your_file'
$headings = $content | sls '\s*¦' |
select LineNumber, @{l="heading"; e={[regex]::Match($_.Line, '¦([^:]+)').Groups[1].Value}}, Content
for ($i = 0; $i -lt $headings.Count; $i++)
{
if ($i +1 -lt $headings.Count)
{
$headings[$i].Content = ($content[$headings[$i].LineNumber .. $headings[$i +1].LineNumber]).Trim() -notmatch '[+¦]|^$'
}
else # last entry
{
$headings[$i].Content = ($content | select -skip $headings[$i].LineNumber).Trim() -notmatch '[+¦]|^$'
}
}
Which will give you the heading and the content of the section ($headings | select heading, Content
):
heading Content
------- -------
Operating System Info {Operating System: Microsoft Windows Server 2008 R2 Standard, Service Pack: Service Pack 1, Product Type: Server, Product ID: 55041-266-035...
Computer Info {Computer Name: COMPNAME, DNSHostName: COMPNAME, Pinging aaccms2 [172.20.78.132] with 32 bytes of data:, Reply from 172.20.78.132: bytes=32 time}
Now all you have to do is to combine the two scripts.
Upvotes: 4
Reputation: 13176
A custom object with all the needed properties will be easier to manipulate and export. This should help you get the columns you want:
$inputLines = Get-Content "input.txt"
#create custom object
$result = New-Object -TypeName PSCustomObject
$inputLines |
#skip lines containing ¦ or -----
Where-Object { $_ -NotMatch "\¦|-----" } | ForEach-Object {
$lineArray = $_.Split(":")
#add property to custom object
if($lineArray[0]) {
$result | Add-Member -MemberType NoteProperty `
-Name $lineArray[0].Trim() `
-Value (($lineArray | Select-Object -Skip 1) -join ":").Trim()
}
}
#export to HTML file
$result | ConvertTo-Html -As List | Out-File "output.html"
Note: the ;
after $CurrentTitle
is not needed (it will be output in the HTML code).
Note 2: final credits go to Martin Brandl who kindly pointed out a bug ... and then helped me fix it.
Upvotes: 2