source/public/Write-ExCmdReport.ps1

Function Write-ExCmdReport {
    [CmdletBinding()]
    param (
        [parameter(
            Mandatory,
            Position = 0,
            ValueFromPipeline
        )]
        [ValidateNotNullOrEmpty()]
        $InputObject,

        [parameter()]
        [string]
        $Organization,

        [parameter()]
        [int]
        $TruncateLongValue,

        [parameter()]
        [string]
        $ReportFile = "$($env:windir)\temp\ExCmdReport_$($(Get-Date -Format ""MM-dd-yyyy"")).html",

        [parameter()]
        [switch]
        $SendEmail,

        [parameter()]
        [mailaddress]
        $From,

        [parameter()]
        [mailaddress[]]
        $To,

        [parameter()]
        [string]
        $Subject = "Exchange Admin Audit Log Report",

        [parameter()]
        [string]
        $SmtpServer,

        [parameter()]
        [int]
        $Port = 25,

        [parameter()]
        [switch]
        $UseSSL,

        [parameter()]
        [pscredential]
        $Credential
    )
    Begin {
        $SendEmailParameterCheckPassed = $true
        if ($SendEmail) {
            if (!$From) {
                Write-Verbose '"From" parameter value is required.'
                $SendEmailParameterCheckPassed = $false
            }

            if (!$To) {
                Write-Verbose '"To" parameter value is required.'
                $SendEmailParameterCheckPassed = $false
            }

            if (!$SmtpServer) {
                Write-Verbose '"SmtpServer" parameter value is required.'
                $SendEmailParameterCheckPassed = $false
            }

            if (!$Port) {
                Write-Verbose '"Port" parameter value is required.'
                $SendEmailParameterCheckPassed = $false
            }
        }

        if ($SendEmailParameterCheckPassed -eq $false) {
            throw "SendEmail is used but the other required parameters are not specified."
        }

        # Pre-create the report file
        New-Item -ItemType File -Path $ReportFile -Force | Out-Null

        $dateCollection = @() # For use later to determine the oldest and newest entry

        if (!$Organization) {
            try {
                $Organization = (Get-OrganizationConfig -ErrorAction STOP).DisplayName
            }
            catch {
                $Organization = "[OrganizationName]"
            }
        }

        $ModuleInfo = Get-Module ExCmdReport
        $tz = ([System.TimeZoneInfo]::Local).DisplayName.ToString().Split(" ")[0]
        $today = Get-Date -Format "MMMM dd, yyyy hh:mm tt"
        $css = Get-Content (($ModuleInfo.ModuleBase.ToString()) + '\source\public\style.css') -Raw
        $title = "$($Subject) - $($Organization) - $($today)"

        $i = 1
    }

    Process {
        foreach ($item in $InputObject) {
            if ($item.CallerAdminName) {
                $Caller = $item.CallerAdminName
            }
            else {
                $Caller = $item.Caller
            }
            $dateCollection += $item.RunDate
            $html2 += '<tr><td>' + $i + '<td><b>Date: </b>' + (Get-Date $item.RunDate -Format "MMM-dd-yyyy hh:mm:ss tt") + '<br><b>Caller: </b>' + $Caller + '<br><b>Target: </b>' + $item.ObjectModified + '<br><b>Succeeded: </b>' + $item.Succeeded + '</td>'
            # $html2 += '<tr><td><b>Date: </b>' + (Get-Date $item.RunDate -Format "MMM-dd-yyyy hh:mm:ss tt") + '<br><b>Caller: </b>' + $Caller + '<br><b>Target: </b>' + $item.ObjectModified + '<br><b>Succeeded: </b>' + $item.Succeeded + '</td>'
            $html2 += '<td><b>' + $item.CmdLetName + '</b><br><br>'
            foreach ($param in $item.CmdletParameters) {
                if ($TruncateLongValue) {
                    if ($param.Value.length -gt $TruncateLongValue) {
                        $paramValue = ((($param.Value).ToString().SubString(0, $TruncateLongValue)) + "...")
                    }
                    else {
                        $paramValue = $param.Value
                    }
                }
                else {
                    $paramValue = $param.Value
                }
                $html2 += ('<b>' + $param.Name + '</b>' + ' = ' + $paramValue + '<br>')
            }
            $html2 += '</td></tr>'
            $i = $i+1
        }
    }
    End {
        if ($null -ne $InputObject) {
            $dateCollection = $dateCollection | Sort-Object
            $startDate = $dateCollection[0]
            $endDate = $dateCollection[-1]
            Write-Verbose "$($startDate) - $($endDate)"

            #$html1 = @()
            $html1 += '<html><head><title>' + $title + '</title>'
            $html1 += '<style type="text/css">'
            $html1 += $css
            $html1 += '</style></head>'
            $html1 += '<body>'
            $html1 += '<table id="tbl">'
            $html1 += '<tr><td class="head"> </td></tr>'
            $html1 += '<tr><th class="section">' + $Subject + '</th></tr>'
            $html1 += '<tr><td class="head"><b>' + $Organization + '</b><br>' + $today + ' ' + $tz + '</td></tr>'
            $html1 += '<tr><td class="head"> </td></tr>'
            $html1 += '</table>'
            $html1 += '<table id="tbl">'
            $html1 += '<tr><td></td><td>Run Details: (' + "$( Get-Date $startDate -Format "MMM-dd-yyyy hh:mm:ss tt") - $( Get-Date $endDate -Format "MMM-dd-yyyy hh:mm:ss tt")" + ')</td><td>Command and Parameters</td></tr>'

            $html3 += '</table>'
            $html3 += '<table id="tbl">'
            $html3 += '<tr><td class="head"> </td></tr>'
            $html3 += '<tr><td class="head"> </td></tr>'
            $html3 += '<tr><td class="head"><b>Source: </b><i>' + $env:COMPUTERNAME + '</i><br>'
            $html3 += '<b>Report File: </b><i>' + (Resolve-Path $ReportFile).Path + '</i><br>'
            $html3 += '<a href="' + $ModuleInfo.ProjectURI.ToString() + '" target="_blank">' + $ModuleInfo.Name.ToString() + ', version ' + $ModuleInfo.Version.ToString() + ' </a><br>'
            $html3 += '<tr><td class="head"> </td></tr>'
            $html3 += '</body></html>'

            $htmlBody = ($html1 + $html2 + $html3) -join "`n"
            try {
                $htmlBody | Out-File $ReportFile -Encoding UTF8
                Write-Verbose "Report saved in $ReportFile."
            }
            catch {
                Write-Verbose $_.Exception.Message
            }

            # Email parameter check
            if ($SendEmail) {

                #Build email parameters
                $mailParams = @{
                    From       = $From
                    To         = $To
                    Subject    = $Subject
                    Body       = $htmlBody
                    SMTPServer = $SmtpServer
                    Port       = $Port
                    BodyAsHTML = $true
                }
                if ($UseSSL) {
                    $mailParams += @{useSSL = $UseSSL }
                }
                if ($Credential) {
                    $mailParams += @{Credential = $Credential }
                }

                #Send email
                try {
                    Write-Verbose "Attempt to send email using the specified mail parameters."
                    Send-MailMessage @mailParams -ErrorAction STOP
                    Write-Verbose "Send Email - Successful."
                }
                catch {
                    Write-Verbose "Send Email - Failed."
                    throw $_.Exception.Message
                }
            }
        }


    }
}