Powershell – Email results of PowerShell Script

certificate-authoritypowershellwindows-server-2008-r2

I have a powershell script that check the certificate store for expiring certificates. It will display these results within the CLI. I want to modify this script to email the results of the output in the body of the email. I know how to send an email through PowerShell using the send-mailmessage CmdLet but I am uncertain how to take the results of the script and send it in an email…

Here is the script:

param([int]$InNumberOfDays=180,[switch]$ExcludeAutoEnroll)

function WriteCertInfo($cert)
{
    #just a lot of code to get the fields into an object
    $certObj = "" | Select RequesterName,RequestType,ExpirationDate,CommonName,EnrollmentFlags

    $RequesterName=$cert -match "Requester Name:.*Request Type:"
    $startLength="Requester Name:".Length
    $lineLength=$matches[0].Length -("Request Type:".Length + $startLength)
    $OutRequesterName=$matches[0].SubString($startLength,$lineLength)
    $certObj.RequesterName=$OutRequesterName    

    $RequestType=$cert -match "Request Type:.*Certificate Expiration Date:"
    $startLength="Request Type:".Length
    $lineLength=$matches[0].Length - ("Certificate Expiration Date:".Length + $startLength)
    $OutRequestType=$matches[0].SubString($startLength,$lineLength)
    $certObj.RequestType=$OutRequestType    

    $ExpirationDate = $cert -match "Certificate Expiration Date:.*Issued Common Name:"
    $startLength="Certificate Expiration Date:".Length
    $lineLength=$matches[0].Length - ("Issued Common Name:".Length + $startLength)
    $OutExpirationDate=$matches[0].SubString($startLength,$lineLength)
    $certObj.ExpirationDate=$OutExpirationDate

    $IssuedCommonName= $cert -match "Issued Common Name:.*Template Enrollment Flags:"
    $startLength="Issued Common Name:".Length
    $lineLength=$matches[0].Length - ("Template Enrollment Flags:".Length + $startLength)
    $OutCommonName=$matches[0].SubString($startLength,$lineLength)
    $certObj.CommonName=$OutCommonName

    $EnrollmentFlags= $cert -match "Template Enrollment Flags:.*"
    $startLength="Template Enrollment Flags:".Length
    $lineLength=$matches[0].Length - ($startLength)
    $OutEnrollmentFlags=$matches[0].SubString($startLength,$lineLength)
    $certObj.EnrollmentFlags=$OutEnrollmentFlags

    if($ExcludeAutoEnroll)
    {

        if(($OutEnrollmentFlags -match "CT_FLAG_AUTO_ENROLLMENT") -eq $false)
        {
            $script:CertToList+=$certObj    
        }
    }
    else
    {

        $script:CertToList+=$certObj

    }
}


$CertToList=@()
$today=Get-Date
$endperiod=$today.AddDays($InNumberOfDays)

$tester=certutil -view -restrict "NotAfter>=$today,NotAfter<=$endperiod" -out 

"RequestID,RequesterName,RequestType,NotAfter,CommonName,EnrollmentFlags"
$arr=$tester -match "Row \d*:"

$numberOfCerts=$arr.length

$line=[string]::join(" ",$tester)

for($certNo=0;$certNo -lt $numberOfCerts;$certNo=$certNo+1)
{

    $r1=$arr[$certNo] 
    if($certNo -ne ($numberOfCerts-1))
    {
        $r2=$arr[$certNo+1]
    }
    else
    {
        $r2="Maximum Row Index"
    }   
    $isFound=$line -match "$r1 .* $r2"
    $NumberOfChars=$matches[0].Length - $r2.Length
    $thisCert=$matches[0].SubString(0,$NumberOfChars)
    WriteCertInfo($thisCert)

}
$CertToList

Best Answer

Since the output formatting in the PowerShell prompt happens when you actually output $CertToList, and you're not interested in that here, you might want to construct a HTML structure to present the output in the mail message.

Update Since you want to embed an inline attachment in the form of an image, we'll have to do the work of creating and sending the email ourselves, instead of relying on Send-MailMessage:

# Smtp details as outlined by Colyn1337
$smtpServer = "server.domain.com"
$smtpFrom = "emailfrom@address.com"
$smtpTo = "emailto@address.com"
$messageSubject = "The subject line of the email"

# Set up an SmtpClient for sending the message
$smtpClient = New-Object Net.Mail.SmtpClient
$smtpClient.Host = $smtpServer

# Create the MailMessage you want to send
$mailMessage = New-Object Net.Mail.MailMessage
$mailMessage.From = $smtpFrom
$mailMessage.To.Add($smtpTo)
$mailMessage.Subject = $messageSubject

# Create the html content for the mail
# Add embedded image resource to HTML
$htmlReport  = "<image src=cid:DangeRussLogo>"

# And then the table with your data
$htmlReport += "<table>"
$htmlReport += "`n"
$htmlReport += "<tr>"
$htmlReport += "<th>RequestID</th>"
$htmlReport += "<th>RequesterName</th>"
$htmlReport += "<th>RequestType</th>"
$htmlReport += "<th>NotAfter</th>"
$htmlReport += "<th>CommonName</th>"
$htmlReport += "<th>EnrollmentFlags</th>"
$htmlReport += "</tr>"
$htmlReport += "`n"
foreach($cert in $CertToList)
{
    $htmlReport += "<tr>"
    $htmlReport += "<td>$($cert.RequestID)</td>"
    $htmlReport += "<td>$($cert.RequesterName)</td>"
    $htmlReport += "<td>$($cert.RequestType)</td>"
    $htmlReport += "<td>$($cert.NotAfter)</td>"
    $htmlReport += "<td>$($cert.CommonName)</td>"
    $htmlReport += "<td>$($cert.EnrollmentFlags)</td>"
    $htmlReport += "</tr>"
    $htmlReport += "`n"
}

$htmlReport += "</table>"

# Now create an AlternateView from the HTML contents
$messageBody = [Net.Mail.AlternateView]::CreateAlternateViewFromString($htmlReport, 'text/html')

# Create a Linked Resource from the logo image
$imageMimeType = New-Object System.Net.Mime.ContentType("image/png")
$embeddedImage = New-Object Net.Mail.LinkedResource("C:\Users\DangeRuss\logo.png", $imageMimeType)
$embeddedImage.ContentId = "DangeRussLogo"

# Add the resource to the HTML view
$messageBody.LinkedResources.Add($embeddedImage)

# Add the HTML view to the MailMessage
$mailMessage.AlternateViews.Add($messageBody)

# And finally send the message
$smtpClient.Send($mailMessage)

If you want to use a .jpeg or .jpg file instead on PNG, change the MimeType from "image/png" to "image/jpeg"