1

I have log file created from a batch process in the below format.

Step DateTime            Description

#0   09/12/2016 17:02:20 TestTableCount.ps1 started from step 1
#1   09/12/2016 17:02:21 The table etl.ProcessLog is Empty . Failed

I want to add this to the body of the email using Send-MailMessage in PowerShell.

I wrote a code that converts the text file to HTML and adds it as a table in the body of the mail.

Code:

$body = Get-Content $LogFile | out-String

$body = $body -replace '^(\S+)\s+(\S+)\s+(\S+)', '<tr><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$1</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$2</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$3</th></tr>'
$body = $body -replace '\n(\S+)\s+(\S+)\s+(\S+)', '<tr><td style = "border: 1px solid black; padding: 5px;">$1</td><td style = "border: 1px solid black; padding: 5px;">$2</td><td style = "border: 1px solid black; padding: 5px;">$3</td></tr>'
$body = '<body><table style = "border: 1px solid black; border-collapse: collapse;">' + $body + '</table></body>'

But that is resulting in the below format:

This is the result from my code

I want the sate and time to come under the DateTime column, but from the code I have written I am getting the time under Description.

How to correct this and get the proper format?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
HadoopAddict
  • 225
  • 6
  • 18
  • Since you are generating this log file, why not generate it as a .csv and get much of what you are doing for free? Then you can use a style for your table as well and not embed this into a complicated replace. – Kory Gill Sep 12 '16 at 21:35

2 Answers2

0

Date and time are separated by a space, which is matched by the second \s+ in your second regular expression.

Change

$body = $body -replace '\n(\S+)\s+(\S+)\s+(\S+)', '<tr><td ...'

to

$body = $body -replace '\n(\S+)\s+(\S+ \S+)\s+(\S+)', '<tr><td ...'

and the replacement should do what you expect.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

PowerShell works better with objects so I am going to suggest something other than building a html file from strings and regex.

While the code I am going to present might seem tedious is works more efficiently and can be easily tailored for other tasks. The first part of this code comes from my answer to another question about parsing fixed width data from a test file. The second is a simple showing of how ConvertTo-HTML works. The former is required to take advantage of the latter. Assume that the file "C:\temp\Test.txt" is your log file and replace as needed. Same for output file path at the end of this snippet.

# Convert the fixed width left aligned file into a collection of psobjects
$data = Get-Content C:\temp\Test.txt | Where-Object{![string]::IsNullOrWhiteSpace($_)}

$headerString = $data[0]
$headerElements = $headerString -split "\s+" | Where-Object{$_}
$headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}

$results = $data | Select-Object -Skip 1  | ForEach-Object{
    $props = @{}
    $line = $_
    For($indexStep = 0; $indexStep -le $headerIndexes.Count - 1; $indexStep++){
        $value = $null            # Assume a null value 
        $valueLength = $headerIndexes[$indexStep + 1] - $headerIndexes[$indexStep]
        $valueStart = $headerIndexes[$indexStep]
        If(($valueLength -gt 0) -and (($valueStart + $valueLength) -lt $line.Length)){
            $value = ($line.Substring($valueStart,$valueLength)).Trim()
        } ElseIf ($valueStart -lt $line.Length){
            $value = ($line.Substring($valueStart)).Trim()
        }
        $props.($headerElements[$indexStep]) = $value    
    }
    [pscustomobject]$props
} 

# Build the html from the $result
$style = @"
<style>
    body{border: 1px solid black; border-collapse: collapse}
    th{border: 1px solid black; background: #dddddd; padding: 5px}
    td{border: 1px solid black; padding: 5px}
</style>
"@

$results | Select-Object $headerElements | ConvertTo-Html -Head $style | Set-Content c:\temp\test.html

Notice that I converted your style in the code above. The resulting file would look like this as html:

rendered table

The columns are out of order but it is nothing a simple Select-Object could not fix.

Community
  • 1
  • 1
Matt
  • 45,022
  • 8
  • 78
  • 119