d00mReport.psm1

<#
.SYNOPSIS
    Generates system inventory HTML report
 
.DESCRIPTION
    Queries useful properties from different WMI classes
    via CIM and generates an HTML report saved to the
    file system
 
.EXAMPLE
    Get-d00mHardwareReport
 
    This example generates a system inventory HTML report
    saved to the current file system location using the
    default credentials.
 
.EXAMPLE
    Computer1, Computer2 | Get-d00mHardwareReport
 
    This example generates a system inventory HTML report
    for the computer names piped in to the cmdlet saved
    to the current file system location using the default
    credentials.
 
.EXAMPLE
    Get-d00mHardwareReport -ComputerName Computer1 -Credential (Get-Credential)
 
    This example generates a systme inventory HTML report
    for Computer1 using the credentials suppied saved to
    the current file system location.
 
.EXAMPLE
    Get-d00mHardwareReport -FilePath c:\path\to\report
 
    This example generates a system inventory HTML report
    for the local machine using default credentials and saved
    to the file system path specified.
#>

function Get-d00mHardwareReport
{
    [CmdletBinding()]
    param
    (
        #Computer names to create a systems inventory report
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        #File system path to save the report
        [parameter()]
        [string]$FilePath = $(Get-Location),

        #Credentials to use for querying WMI
        [parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.Stopwatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)
            $html = New-Object -TypeName System.Text.StringBuilder
            $html.AppendLine("<html>
                                <head>
                                    <title>$($computer) Hardware Inventory</title>
                                    <style>
                                        table, tr, td {
                                            border: 1px solid green;
                                            border-collapse: collapse;
                                        }
 
                                        tr.alt td {
                                            background-color: `#171717;
                                        }
 
                                        tr.heading td {
                                            font-weight: bold;
                                            text-align: center;
                                            font-size: larger;
                                            color: white;
                                            background-color: `#333333;
                                        }
 
                                        body {
                                            background-color: black;
                                            color: `#bdbdbd;
                                            font-family: lucida consolas, monospace;
                                        }
                                    </style>
                                </head>
                                <body>
                                    <table>
                                        <tr class=`"heading`">
                                            <td colspan=`"2`">$($computer)</td>
                                        </tr>
                                        <tr>
                                            <td>Report</td>
                                            <td>Date</td>
                                        </tr>
                                        <tr>
                                            <td>$($cmdletName)</td>
                                            <td>$(Get-Date)</td>
                                        </tr>
                                    </table>
                                </br>"
) | Out-Null
            try
            {
                $sessionParams = @{ComputerName = $computer
                                   ErrorAction  = 'Stop'}
                if ($Credential -ne $null)
                {
                    $sessionParams.Add('Credential', $Credential)
                    Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
                }
                else
                {
                    Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
                }

                $session = New-CimSession @sessionParams

                $cimParams = @{CimSession  = $session
                               ErrorAction = 'SilentlyContinue'}

                Write-Verbose -Message ('{0} : {1} : Getting Win32_Baseboard...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_BaseBoard @cimParams
                if ($cim)
                {
                    $html.AppendLine(('
                                    <table>
                                        <tr class="heading">
                                            <td colspan="2">
                                                Win32_BaseBoard
                                            </td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Name</td>
                                            <td>{0}</td>
                                        </tr>
                                        <tr>
                                            <td>Manufacturer</td>
                                            <td>{1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Product</td>
                                            <td>{2}</td>
                                        </tr>
                                        <tr>
                                            <td>SerialNumber</td>
                                            <td>{3}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Status</td>
                                            <td>{4}</td>
                                        </tr>
                                    </table>
                                </br>'
 -f $cim.Name,
                                          $cim.Manufacturer,
                                          $cim.Product,
                                          $cim.SerialNumber,
                                          $cim.Status)) | Out-Null
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_Bios...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_Bios @cimParams
                if ($cim)
                {
                    $html.AppendLine(('
                                    <table>
                                        <tr class="heading">
                                            <td colspan="2">Win32_Bios</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>SerialNumber</td>
                                            <td>{0}</td>
                                        </tr>
                                        <tr>
                                            <td>Manufacturer</td>
                                            <td>{1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Name</td>
                                            <td>{2}</td>
                                        </tr>
                                        <tr>
                                            <td>PrimaryBios</td>
                                            <td>{3}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>ReleaseDate</td>
                                            <td>{4}</td>
                                        </tr>
                                        <tr>
                                            <td>Version</td>
                                            <td>{5}</td>
                                        </tr>
                                    </table>
                                </br>'
 -f $cim.SerialNumber,
                                          $cim.Manufacturer,
                                          $cim.Name,
                                          $cim.PrimaryBIOS,
                                          $cim.ReleaseDate,
                                          $cim.Version)) | Out-Null
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_CdRomDrive...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_CDROMDrive @cimParams
                if ($cim)
                {
                    foreach ($cd in $cim)
                    {
                        $html.AppendLine(('
                                    <table>
                                        <tr class="heading">
                                            <td colspan="2">Win32_CDROMDrive {1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Name</td>
                                            <td>{0}</td>
                                        </tr>
                                        <tr>
                                            <td>Drive</td>
                                            <td>{1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>MediaLoaded</td>
                                            <td>{2}</td>
                                        </tr>
                                    </table>
                                </br>'
 -f $cd.Name,
                                          $cd.Drive,
                                          $cd.MediaLoaded)) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_ComputerSystem...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_ComputerSystem @cimParams
                if ($cim)
                {
                    $html.AppendLine(('
                                    <table>
                                        <tr class="heading">
                                            <td colspan="2">Win32_ComputerSystem</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Caption</td>
                                            <td>{0}</td>
                                        </tr>
                                        <tr>
                                            <td>UserName</td>
                                            <td>{1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Manufacturer</td>
                                            <td>{2}</td>
                                        </tr>
                                        <tr>
                                            <td>Model</td>
                                            <td>{3}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>SystemType</td>
                                            <td>{4}</td>
                                        </tr>
                                        <tr>
                                            <td>PrimaryOwnerName</td>
                                            <td>{5}</td>
                                        </tr>
                                    </table>
                                </br>'
 -f $cim.Caption,
                                          $cim.UserName,
                                          $cim.Manufacturer,
                                          $cim.Model,
                                          $cim.SystemType,
                                          $cim.PrimaryOwnerName)) | Out-Null
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_DiskDrive...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_DiskDrive @cimParams
                if ($cim)
                {
                    foreach ($disk in $cim)
                    {
                        $html.AppendLine(('
                                    <table>
                                        <tr class="heading">
                                            <td colspan="2">Win32_DiskDrive : {0}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Index</td>
                                            <td>{0}</td>
                                        </tr>
                                        <tr>
                                            <td>DeviceID</td>
                                            <td>{1}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Model</td>
                                            <td>{2}</td>
                                        </tr>
                                        <tr>
                                            <td>SerialNumber</td>
                                            <td>{3}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>InterfaceType</td>
                                            <td>{4}</td>
                                        </tr>
                                        <tr>
                                            <td>Size</td>
                                            <td>{5}</td>
                                        </tr>
                                        <tr class="alt">
                                            <td>Partitions</td>
                                            <td>{6}</td>
                                        </tr>
                                    </table>
                                </br>'
 -f $disk.Index,
                                          $disk.DeviceID,
                                          $disk.Model,
                                          $disk.SerialNumber,
                                          $disk.InterfaceType,
                                          $([int]$(($disk.Size)/1GB)),
                                          $disk.Partitions)) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_LogicalDisk...' -f $cmdletName, $computer) 
                $cim = Get-CimInstance -ClassName Win32_LogicalDisk @cimParams
                if ($cim)
                {
                    foreach ($drive in $cim)
                    {
                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_LogicalDisk : {0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>DeviceID</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr>
                                                <td>Description</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>DriveType</td>
                                                <td>{2}</td>
                                            </tr>'
 -f $drive.DeviceID,
                                                      $drive.Description,
                                                      $drive.DriveType)) | Out-Null
                        if ($drive.DriveType -ne 5)
                        {
                            $percentFree = [math]::Round((($drive.Freespace)/($drive.Size))*100)
                            $status = switch ($percentFree)
                            {
                                {$_ -le 10} {'CRITICAL'}
                                {($_ -gt 10) -and ($_ -le 25)} {'WARNING'}
                                default {'OK'}
                            }
                            $html.AppendLine(('
                                            <tr>
                                                <td>VolumeName</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>FileSystem</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr>
                                                <td>FreeSpace</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>UsedSpace</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr>
                                                <td>Size</td>
                                                <td>{4}</td>
                                            <tr class="alt">
                                                <td>PercentFree</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr>
                                                <td>Status</td>
                                                <td>{6}</td>
                                            </tr>'
 -f $drive.VolumeName,
                                                      $drive.FileSystem,
                                                      $([int]$($($drive.FreeSpace)/1GB)),
                                                      $([int]$($($drive.Size - $drive.FreeSpace)/1GB)),
                                                      $([int]$($($drive.Size)/1GB)),
                                                      $percentFree,
                                                      $status)) | Out-Null
                        }
                        $html.AppendLine('</table>
                                        </br>'
) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_NetworkAdapter...' -f $cmdletName, $computer) 
                $cim = Get-CimInstance -ClassName Win32_NetworkAdapter @cimParams -Filter "NetEnabled='True'"
                if ($cim)
                {
                    foreach ($adapter in $cim)
                    {
                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_NetworkAdapter {0} </td>
                                            </tr>
                                            <tr>
                                                <td>Index</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Name</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr>
                                                <td>Connection</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>DeviceID</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr>
                                                <td>MACAddress</td>
                                                <td>{4}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Manufacturer</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr>
                                                <td>AdapterType</td>
                                                <td>{6}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Speed</td>
                                                <td>{7}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $adapter.InterfaceIndex,
                                              $adapter.ProductName,
                                              $adapter.NetConnectionID,
                                              $adapter.DeviceID,
                                              $adapter.MACAddress,
                                              $adapter.Manufacturer,
                                              $adapter.AdapterType,
                                              $adapter.Speed)) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_NetworkAdapterConfiguration...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration @cimParams -Filter "IPEnabled='True'"
                if ($cim)
                {
                    foreach ($adapter in $cim)
                    {
                        $ip = ''
                        if ($adapter.IPAddress.Count -gt 1)
                        {
                            foreach ($address in $adapter.IPAddress)
                            {
                                $ip += $address + '; '
                            }
                        }
                        else
                        {
                            $ip = $adapter.IPAddress[0]
                        }
                        
                        $gateway = ''
                        if ($adapter.DefaultIPGateway.Count -gt 1)
                        {
                            $counter = 0
                            foreach ($g in $adapter.DefaultIPGateway)
                            {
                                $gateway += $g + '; '
                            }
                        }
                        else
                        {
                            if ($adapter.DefaultIPGateway -ne $null)
                            {
                                $gateway = $adapter.DefaultIPGateway[0]
                            }
                            else
                            {
                                $gateway = 'null'
                            }
                        }

                        $dnsserverorder = ''
                        if ($adapter.DnsServerSearchOrder.Count -gt 1)
                        {
                            foreach ($dns in $adapter.DnsServerSearchOrder)
                            {
                                $dnsserverorder += $dns + '; '
                            }
                        }
                        else
                        {
                            if ($adapter.DnsServerSearchOrder -ne $null)
                            {
                                $dnsserverorder = $adapter.DnsServerSearchOrder[0]
                            }
                            else
                            {
                                $dnsserverorder = 'null'
                            }
                        }

                        $subnet = ''
                        if ($adapter.IPSubnet.Count -gt 1)
                        {
                            foreach ($subnet in $adapter.IPSubnet)
                            {
                                $subnet += $subnet + '; '
                            }
                        }
                        else
                        {
                            if ($adapter.IPSubnet -ne $null)
                            {
                                $subnet = $adapter.IPSubnet[0]
                            }
                            else
                            {
                                $subnet = 'null'
                            }
                        }

                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_NetworkAdapterConfiguration {0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>InterfaceIndex</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr>
                                                <td>ServiceName</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>IPAddress</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr>
                                                <td>DHCPEnabled</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>DHCPServer</td>
                                                <td>{4}</td>
                                            </tr>
                                            <tr>
                                                <td>DefaultIPGateway</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>DNSServerSearchOrder</td>
                                                <td>{6}</td>
                                            </tr>
                                            <tr>
                                                <td>WINSPrimaryServer</td>
                                                <td>{7}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>IPSubnet</td>
                                                <td>{8}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $adapter.InterfaceIndex,
                                              $adapter.ServiceName,
                                              $ip,
                                              $adapter.DHCPEnabled,
                                              $adapter.DHCPServer,
                                              $gateway,
                                              $dnsserverorder,
                                              $adapter.WINSPrimaryServer,
                                              $subnet)) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_OperatingSystem...' -f $cmdletName, $computer)
                $cim = Get-CimInstance -ClassName Win32_OperatingSystem @cimParams
                if ($cim)
                {
                    $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_OperatingSystem</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>BuildNumber</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr>
                                                <td>Caption</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Manufacturer</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr>
                                                <td>OSArchitecture</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>RegisteredUser</td>
                                                <td>{4}</td>
                                            </tr>
                                            <tr>
                                                <td>SerialNumber</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Version</td>
                                                <td>{6}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $cim.BuildNumber,
                                              $cim.Caption,
                                              $cim.Manufacturer,
                                              $cim.OSArchitecture,
                                              $cim.RegisteredUser,
                                              $cim.SerialNumber,
                                              $cim.Version)) | Out-Null
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_PhysicalMemory...' -f $cmdletName, $computer) 
                $cim = Get-CimInstance -ClassName Win32_PhysicalMemory @cimParams
                if ($cim)
                {
                    foreach ($mem in $cim)
                    {
                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_PhysicalMemory {0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>BankLabel</td>
                                                <td>{0}</td>
                                            <tr>
                                                <td>DeviceLocator</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Capacity</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr>
                                                <td>Manufacturer</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>PartNumber</td>
                                                <td>{4}</td>
                                            </tr>
                                            <tr>
                                                <td>SerialNumber</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Speed</td>
                                                <td>{6}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $mem.BankLabel,
                                              $mem.DeviceLocator,
                                              $($mem.Capacity/1GB),
                                              $mem.Manufacturer,
                                              $mem.PartNumber,
                                              $mem.SerialNumber,
                                              $mem.Speed)) | Out-Null
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting WMIMonitorID...' -f $cmdletName, $computer) 
                $cim = Get-CimInstance -ClassName WMIMonitorID -Namespace root\wmi @cimParams
                if ($cim)
                {
                    $count = 0
                    foreach ($mon in $cim)
                    {
                        # check for null values
                        if (!([string]::IsNullOrEmpty($mon.ManufacturerName)))
                        {
                            $man = [System.Text.Encoding]::ASCII.GetString($mon.ManufacturerName)
                        }
                        else
                        {
                            $man = 'null'
                        }

                        if (!([string]::IsNullOrEmpty($mon.UserFriendlyName)))
                        {
                            $name = [System.Text.Encoding]::ASCII.GetString($mon.UserFriendlyName)
                        }
                        else
                        {
                            $name = 'null'
                        }

                        if (!([string]::IsNullOrEmpty($mon.SerialNumberID)))
                        {
                            $id = $mon.SerialNumberID -join ''
                        }
                        else
                        {
                            $id = 'null'
                        }

                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">WMIMonitorID {0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>ManufacturerName</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr>
                                                <td>UserFriendlyName</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>SerialNumberID</td>
                                                <td>{3}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $count,
                                              $man,
                                              $name,
                                              $id)) | Out-Null
                        $count++
                    }
                }
                $cim = $null

                Write-Verbose -Message ('{0} : {1} : Getting Win32_Processor...' -f $cmdletName, $computer) 
                $cim = Get-CimInstance -ClassName Win32_Processor @cimParams
                if ($cim)
                {
                    $count = 0
                    foreach ($proc in $cim)
                    {
                        $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">Win32_Processor {0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Name</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr>
                                                <td>Manufacturer</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Caption</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr>
                                                <td>DeviceID</td>
                                                <td>{4}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>CurrentClockSpeed</td>
                                                <td>{5}</td>
                                            </tr>
                                            <tr>
                                                <td>NumberOfCores</td>
                                                <td>{6}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>ProcessorID</td>
                                                <td>{7}</td>
                                            </tr>
                                            <tr>
                                                <td>Status</td>
                                                <td>{8}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $count,
                                              $proc.Name,
                                              $proc.Manufacturer,
                                              $proc.Caption,
                                              $proc.DeviceID,
                                              $proc.CurrentClockSpeed,
                                              $proc.NumberOfCores,
                                              $proc.ProcessorID,
                                              $proc.Status)) | Out-Null
                        $count++
                    }
                }
                $cim = $null

                $html.ToString() | 
                    Out-File -FilePath ('{0}\{1}_HardwareReport_{2}.html' -f $FilePath, 
                                                                             $computer, 
                                                                             $(Get-Date -Format 'yyyyMMdd'))
            }
            
            catch
            {
                throw
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Generates installed software HTML report
 
.DESCRIPTION
    Gets registry values for installed programs and
    generates an HTML report saved to the current
    file path location by default
 
.EXAMPLE
    Get-d00mSoftwareReport
 
    This example generates an installed software HTML report
    for the local computer and saved to the current file path
    location.
     
.EXAMPLE
    Get-d00mSoftwareReport -ComputerName Computer1, Computer2
 
    This example generates an installed software HTML report
    for the remote computers, Computer1 and Computer2, and saves
    them to the current file path location
 
.EXAMPLE
    'Computer1' | Get-d00mSoftwareReport -Credential (Get-Credential)
 
    This example generates an installed software HTML report
    for the piped in computer name using the credentials supplied and
    saves to the current file path location
 
.EXAMPLE
    (Get-AdComputer -Filter {(Enabled -eq 'true')}).Name | Get-d00mSoftwareReport -FilePath C:\path
 
    This example generates an installed software HTML report for each
    of the computer names returned from the Get-AdComputer cmdlet and saves
    them to the file path specifed
#>

function Get-d00mSoftwareReport
{
    [CmdletBinding()]
    param
    (
        #Computer names to create an installed software inventory report
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        #File system path to save the report
        [parameter()]
        [string]$FilePath = $(Get-Location),

        #Credentials to use for accessing remote computer
        [parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.Stopwatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            $html = New-Object -TypeName System.Text.StringBuilder
            $html.AppendLine("<html>
                                <head>
                                    <title>$($computer) Software Inventory</title>
                                    <style>
                                        table, tr, td {
                                            border: 1px solid green;
                                            border-collapse: collapse;
                                        }
 
                                        tr.alt td {
                                            background-color: `#171717;
                                        }
 
                                        tr.heading td {
                                            font-weight: bold;
                                            text-align: center;
                                            font-size: larger;
                                            color: white;
                                            background-color: `#333333;
                                        }
 
                                        body {
                                            background-color: black;
                                            color: `#bdbdbd;
                                            font-family: lucida consolas, monospace;
                                        }
                                    </style>
                                </head>
                                <body>
                                    <table>
                                        <tr class=`"heading`">
                                            <td colspan=`"2`">$($computer)</td>
                                        </tr>
                                        <tr>
                                            <td>Report</td>
                                            <td>Date</td>
                                        </tr>
                                        <tr>
                                            <td>$($cmdletName)</td>
                                            <td>$(Get-Date)</td>
                                        </tr>
                                    </table>
                                </br>"
) | Out-Null

            try
            {
                Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)
                $sessionParams = @{ComputerName = $computer
                                   ErrorAction  = 'Stop'}
                if ($Credential -ne $null)
                {
                    $sessionParams.Add('Credential', $Credential)
                    Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
                }
                else
                {
                    Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
                }
                $session = New-PSSession @sessionParams

                Invoke-Command -Session $session -ScriptBlock {
                    $keys    = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
                    $reg     = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', [Microsoft.Win32.RegistryView]::Default)
                    $regKey  = $reg.OpenSubKey($keys)
                    $subKeys = $regKey.GetSubKeyNames()
                    foreach ($key in $subKeys)
                    {
                        $thisKey    = ('{0}\\{1}' -f $keys, $key)
                        $thisSubKey = $reg.OpenSubKey($thisKey)
                        
                        $name = $null
                        $name = $thisSubKey.GetValue('DisplayName')
                        if ([System.String]::IsNullOrEmpty($name))
                        {
                            $name = 'No DisplayName'
                        }

                        $version = $null
                        $version = $thisSubKey.GetValue('DisplayVersion')
                        if ([system.String]::IsNullOrEmpty($version))
                        {
                            $version = 'No DisplayVersion'
                        }

                        $location = $null
                        $location = $thisSubKey.GetValue('InstallLocation')
                        if ([System.String]::IsNullOrEmpty($location))
                        {
                            $location = 'No InstallLocation'
                        }

                        $publisher = $null
                        $publisher = $thisSubKey.GetValue('Publisher')
                        if ([System.String]::IsNullOrEmpty($publisher))
                        {
                            $publisher = 'No Publisher'
                        }

                        $comments = $null
                        $comments = $thisSubKey.GetValue('Comments')
                        if ([System.String]::IsNullOrEmpty($comments))
                        {
                            $comments = 'No Comments'
                        }
                        $props = @{DisplayName     = $name
                                   DisplayVersion  = $version
                                   InstallLocation = $location
                                   Publisher       = $publisher
                                   Comments        = $comments
                                   KeyName         = $key.ToString().Replace('{','').Replace('}','')}
                        New-Object -TypeName psobject -Property $props | 
                            Write-Output
                    }
                } | ForEach-Object {
                        $html.AppendLine(('
                            <table>
                                <tr class="heading">
                                    <td colspan="2">{0}</td>
                                </tr>
                                <tr class="alt">
                                    <td>DisplayName</td>
                                    <td>{0}</td>
                                </tr>
                                <tr>
                                    <td>DisplayVersion</td>
                                    <td>{1}</td>
                                </tr>
                                <tr class="alt">
                                    <td>InstallLocation</td>
                                    <td>{2}</td>
                                </tr>
                                <tr>
                                    <td>Publisher</td>
                                    <td>{3}</td>
                                </tr>
                                <tr class="alt">
                                    <td>Comments</td>
                                    <td>{4}</td>
                                </tr>
                                <tr>
                                    <td>KeyName</td>
                                    <td>{5}</td>
                                </tr>
                            </table>
                        </br>'
 -f $_.DisplayName,
                                  $_.DisplayVersion,
                                  $_.InstallLocation,
                                  $_.Publisher,
                                  $_.Comments,
                                  $_.KeyName)) | Out-Null
                    }
                $html.ToString() | 
                    Out-File -FilePath ('{0}\{1}_SoftwareReport_{2}.html' -f $FilePath, 
                                                                             $computer, 
                                                                             $(Get-Date -Format 'yyyyMMdd'))
                Remove-PSSession -Session $session
            }
            catch
            {
                throw
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Generates services HTML report
 
.DESCRIPTION
    Executes Get-Service on computers and gets the Name, DisplayName, ServiceName, Status,
    and StartType and generates an HTML report in the current file system location by default.
 
.EXAMPLE
    Get-d00mServiceReport
 
    This example gets the services on the local machine using the default credentials
    and generates an HTML report in the current file system location.
 
.EXAMPLE
    Get-d00mServiceReport -ComputerName Computer1, Computer2
 
    This example gets the services on the remote computers, Computer1 and Computer2, and generates
    an HTML report for each in the current file system location.
 
.EXAMPLE
    'Computer1' | Get-d00mServiceReport -Credential (Get-Credential)
 
    This example gets the services on the piped in computername, Computer1, using the specified
    credentials and generates an HTML report in the current file system location.
 
.EXAMPLe
    Get-d00mServiceReport -FilePath c:\path
 
    This example gets the services for the local computer using the default credentials and
    generates an HTML report saved to the specified file system path.
#>

function Get-d00mServiceReport
{
    [CmdletBinding()]
    param
    (
        #Computer names to create a services report
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        #File system path to save the report
        [parameter()]
        [string]$FilePath = $(Get-Location),

        #Credentials to use for accessing remote computer
        [parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.Stopwatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            try
            {
                $html = New-Object -TypeName System.Text.StringBuilder
                $html.AppendLine("<html>
                                <head>
                                    <title>$($computer) Service Inventory</title>
                                    <style>
                                        table, tr, td {
                                            border: 1px solid green;
                                            border-collapse: collapse;
                                        }
 
                                        tr.alt td {
                                            background-color: `#171717;
                                        }
 
                                        tr.heading td {
                                            font-weight: bold;
                                            text-align: center;
                                            font-size: larger;
                                            color: white;
                                            background-color: `#333333;
                                        }
 
                                        body {
                                            background-color: black;
                                            color: `#bdbdbd;
                                            font-family: lucida consolas, monospace;
                                        }
                                    </style>
                                </head>
                                <body>
                                    <table>
                                        <tr class=`"heading`">
                                            <td colspan=`"2`">$($computer)</td>
                                        </tr>
                                        <tr>
                                            <td>Report</td>
                                            <td>Date</td>
                                        </tr>
                                        <tr>
                                            <td>$($cmdletName)</td>
                                            <td>$(Get-Date)</td>
                                        </tr>
                                    </table>
                                </br>"
) | Out-Null
                $params = @{ComputerName = $computer
                            ErrorAction  = 'Stop'}
                if ($Credential -ne $null)
                {
                    Write-Verbose -Message ('{0} : {1} : Using specified credentials' -f $cmdletName, $computer)
                    $params.Add('Credential', $Credential)
                }
                else
                {
                    Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
                }
                $session = New-PSSession @params

                Invoke-Command $session -ErrorAction Stop -ScriptBlock {
                    Get-Service | 
                        Sort-Object -Property Name | 
                        ForEach-Object {
                            $svcProps = @{Name        = $_.Name
                                          DisplayName = $_.DisplayName
                                          ServiceName = $_.ServiceName
                                          Status      = $_.Status
                                          StartType   = $_.StartType}
                            New-Object -TypeName psobject -Property $svcProps |
                                Write-Output
                        }
                } | ForEach-Object {
                    $html.AppendLine(('
                                        <table>
                                            <tr class="heading">
                                                <td colspan="2">{0}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>Name</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr>
                                                <td>DisplayName</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>ServiceName</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr>
                                                <td>Status</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr class="alt">
                                                <td>StartType</td>
                                                <td>{4}</td>
                                            </tr>
                                        </table>
                                    </br>'
 -f $_.Name,
                                              $_.DisplayName,
                                              $_.ServiceName,
                                              $_.Status,
                                              $_.StartType)) | Out-Null
                    }
                $html.ToString() | 
                    Out-File -FilePath ('{0}\{1}_SoftwareReport_{2}.html' -f $FilePath, 
                                                                             $computer, 
                                                                             $(Get-Date -Format 'yyyyMMdd'))
                Remove-PSSession -Session $session
            }
            catch
            {
                throw
            }
        }
    }


    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Get disk space statistics
 
.DESCRIPTION
    Query hard drives in Win32_LogicalDisk for size and freespace
    in GB and percent of diskspace still free using a CIM session
 
.EXAMPLE
    Get-d00mDiskSpace
 
    This example queries Win32_LogicalDisk on the local machine
    and gets freespace (GB), size (GB), and percent free for each
    disk using default credentials through a CIM session
 
.EXAMPLE
    Get-d00mDiskSpace -ComputerName Computer1, Computer2
 
    This example queries Win32_LogicalDisk on the remote computers,
    Computer1 and Computer2, and gets freespace (GB), size (GB), and
    percent free for each disk using default credentials through CIM
    sessions
 
.EXAMPLE
    'Computer1' | Get-d00mDiskSpace -Credential (Get-Credential)
 
    This example queries Win32_LogicalDisk on the piped in computer
    name, Computer1, and gets freespace (GB), size (GB), and percent
    free for each disk using specified credentials through a CIM
    session
 
#>

function Get-d00mDiskSpaceReport
{
    [CmdletBinding()]
    param
    (
        #Computers to query disk space
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        #Credentials to use for accessing computer
        [parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.Stopwatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)
            try
            {
                $sessionParams = @{ComputerName = $computer
                                   ErrorAction  = 'Stop'}
                if ($Credential -ne $null)
                {
                    $sessionParams.Add('Credential', $Credential)
                    Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
                }
                else
                {
                    Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
                }
                $cimSession = New-CimSession @sessionParams

                $cimParams = @{ClassName  = 'Win32_LogicalDisk'
                               CimSession = $cimSession
                               Filter     = 'DriveType<>5'}
                Get-CimInstance @cimParams | ForEach-Object {
                    New-Object -TypeName psobject -Property @{ComputerName = $computer
                                                              DeviceId     = $_.DeviceID
                                                              VolumeName   = $_.VolumeName
                                                              Size         = [math]::Round($_.Size/1GB)
                                                              FreeSpace    = [math]::Round($_.FreeSpace/1GB)
                                                              PercentFree  = [math]::Round(($_.FreeSpace/$_.Size)*100)}
                } | Write-Output
            }

            catch
            {
                throw
            }

            Write-Verbose -Message ('{0} : {1} : End execution' -f $cmdletName, $computer)
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Retrieve OS and processor architecture (32 or 64)
 
.DESCRIPTION
    Query Win32_Processor.DataWidth and Win32_OperatingSystem.OSArchitecture for
    32 or 64-bit
 
.EXAMPLE
    Get-d00mArchitecture
 
    This example queries Win32_Processor.DataWidth and Win32_OperatingSystem.OSArchitecture
    for 32 or 64-bit on the local computer using default credentials
 
.EXAMPLE
    Get-d00mArchitecture -ComputerName computer1, computer2 -Credential (Get-Credential)
 
    This example queries Win32_Processor.DataWidth and Win32_OperatingSystem.OSArchitecture
    on the remote computers, computer1 and computer2, for 32 or 64-bit using the supplied
    credentials
#>

function Get-d00mArchitectureReport
{
    [CmdletBinding()]
    param
    (
        [parameter(ValueFromPipeline,
                   ValueFromPipelineByPropertyName,
                   Position=0)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        [parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            Write-Verbose -Message ('{0} : {1} : Begin processing' -f $cmdletName, $computer)
            $sessionParams = @{ComputerName = $computer
                               ErrorAction  = 'Stop'}
            if ($Credential -ne $null)
            {
                $sessionParams.Add('Credential', $Credential)
                Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
            }
            else
            {
                Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
            }
            
            $session = New-CimSession @sessionParams

            Write-Verbose -Message ('{0} : {1} : Getting Win32_Processor.DataWidth' -f $cmdletName, $computer)
            $procArch = Get-CimInstance -CimSession $session -ClassName Win32_Processor -Property DataWidth

            Write-Verbose -Message ('{0} : {1} : Getting Win32_OperatingSystem.OSArchitecture' -f $cmdletName, $computer)
            $osArch   = Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem -Property OSArchitecture
            
            Remove-CimSession -CimSession $session

            if ($procArch.Count -gt 1)
            {
                Write-Verbose -Message ('{0} : {1} : Detected more than 1 processor' -f $cmdletName, $computer)
                foreach ($p in $procArch)
                {
                    New-Object -TypeName psobject -Property @{ComputerName          = $computer
                                                              ProcessorArchitecture = ('{0} : {1}' -f $p.DeviceID, $p.DataWidth)
                                                              OSArchitecture        = $osArch.OSArchitecture} |
                        Write-Output
                }
            }
            else
            {
                Write-Verbose -Message ('{0} : {1} : Detected 1 processor' -f $cmdletName, $computer)
                New-Object -TypeName psobject -Property @{ComputerName          = $computer
                                                          ProcessorArchitecture = ('{0} : {1}' -f $procArch.DeviceID, $procArch.DataWidth)
                                                          OSArchitecture        = $osArch.OSArchitecture} |
                    Write-Output
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}



<#
.SYNOPSIS
    Generate Event Log HTML Report
 
.DESCRIPTION
    Iterate through available event logs for Error, Warning, or FailureAudit
    event entires generated in the past 24 hours and saves the report in the
    current directory using current credentials by default
     
.EXAMPLE
    Get-d00mEventLogReport -ComputerName Computer1
 
    This example iterates through available event logs on the remote computer
    Computer1 for Error, Warning, or FailureAudit event entries generated
    in the past 24 hours and saves the report in the current directory using
    current credentials
 
.EXAMPLE
    'Computer1', 'Computer2' | Get-d00mEventLogReport -Credential (Get-Credential)
 
    This example iterates through available event logs on the remote computers
    piped into the function for Error, Warning, or FailureAudit event entries
    generated in the past 24 hours and saves the report in the current directory
    using the specified credentials
 
.EXAMPLE
    Get-d00mEventLogReport -Credential (Get-Credential) -FilePath \\server1\share
 
    This example iterates through available event logs on the local computer
    for Error, Warning, or FailureAudit event entries generated in the past 24
    generated in the past 24 hours and saves the report in the specified directory
    using the specified credentials
#>

function Get-d00mEventLogReport
{
    [CmdletBinding()]
    param
    (
        [parameter(ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName,

        [parameter()]
        [pscredential]$Credential,

        [parameter()]
        [string]$FilePath = (Get-Location)
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        $start      = Get-Date
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            try
            {
                Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)

                $sessionParams = @{ComputerName = $computer
                                   ErrorAction  = 'Stop'}
                if ($Credential -ne $null)
                {
                    $sessionParams.Add('Credential', $Credential)
                    Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
                }
                else
                {
                    Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
                }

                $session = New-PSSession @sessionParams
                $html = New-Object -TypeName System.Text.StringBuilder
                $html.AppendLine("
                <html>
                    <head>
                        <title>$($computer) Event Log Report</title>
                        <style>
                            table, tr, td {
                                border: 1px solid green;
                                border-collapse: collapse;
                            }
 
                            tr.alt td {
                                background-color: `#171717;
                            }
 
                            tr.heading td {
                                font-weight: bold;
                                text-align: center;
                                font-size: larger;
                                color: white;
                                background-color: `#333333;
                            }
             
                            body {
                                background-color: black;
                                color: `#bdbdbd;
                                font-family: lucida consolas, monospace;
                            }
                        </style>
                    </head>
                    <body>
                        <table>
                            <tr class=`"heading`">
                                <td colspan=`"2`">$($computer)</td>
                            </tr>
                            <tr>
                                <td>Report</td>
                                <td>Event Log Report</td>
                            </tr>
                            <tr>
                                <td>Date Range</td>
                                <td>$((Get-Date).AddDays(-1)) - $(Get-Date)</td>
                            </tr>
                        </table>
                        </br>"
) | Out-Null

                $logs = Invoke-Command -Session $session -ScriptBlock {
                    Get-EventLog -List -AsString | Write-Output
                }

                Write-Verbose -Message ('{0} : {1} : Found {2} available event logs' -f $cmdletName, $computer, $logs.Count)

                foreach ($log in $logs)
                {
                    Write-Verbose -Message ('{0} : {1} : Getting {2} event log entries' -f $cmdletName, $computer, $log)
                    $events = Invoke-Command -Session $session -ScriptBlock {
                        $params = @{LogName     = $args[0]
                                    After       = $((Get-Date).AddDays(-1))
                                    EntryType   = 'Error', 'Warning', 'FailureAudit'
                                    ErrorAction = 'SilentlyContinue'}
                        Get-EventLog @params | Write-Output
                    } -ArgumentList $log
                    if ($events.Count -gt 0)
                    {
                        $html.AppendLine(('
                        <table>
                            <tr class="heading">
                                <td colspan="5"><center>{0}</center></td>
                            </tr>
                            <tr class="heading">
                                <td>TimeGenerated</td>
                                <td>EntryType</td>
                                <td>EventID</td>
                                <td>Source</td>
                                <td>Message</td>
                            </tr>'
 -f $log)) | Out-Null
                        $counter = 1
                        foreach ($event in $events)
                        {
                            if ([bool]!($counter%2))
                            {
                                $html.AppendLine('<tr>') | Out-Null
                            }
                            else
                            {
                                $html.AppendLine('<tr class="alt">') | Out-Null
                            }
                            $html.AppendLine(('
                                <td>{0}</td>
                                <td>{1}</td>
                                <td>{2}</td>
                                <td>{3}</td>
                                <td>{4}</td>
                            </tr>'
 -f $event.TimeGenerated,
                                      $event.EntryType,
                                      $event.EventID,
                                      $event.Source,
                                      $event.Message)) | Out-Null
                            $counter++
                        }
                        $html.AppendLine('</table></br>') | Out-Null
                    }
                    else
                    {
                        $html.AppendLine('
                        <table>
                            <tr class="heading">
                                <td colspan="5"><center>{0}</center>
                            </tr>
                            <tr>
                                <td>
                                    <center>
                                    No Error, Critical, Failure Audit events detected! :D
                                    </center>
                                </td>
                            </tr>
                        </table>
                        </br>'
 -f $log) | Out-Null
                    }
                }
                $html.AppendLine('
                    </body>
                </html>'
) | Out-Null

                $reportName = '{0}_EventLogReport_{1}.html' -f $computer, (Get-Date -Format 'yyyyMMdd')
                $html.ToString() | Out-File -FilePath (Join-Path -Path $FilePath -ChildPath $reportName) -Force

                Remove-PSSession -Session $session
            }

            catch
            {
                throw
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Generate WinSat scores
 
.DESCRIPTION
    Run winsat.exe prepop on computers and get Win32_WinSat scores
 
.EXAMPLE
    Get-d00mWinsatScore
 
    This runs winsat.exe prepop on the local computer and returns
    the Win32_WinSat scores using default credentials
 
.EXAMPLE
    Get-d00mWinsatScore -ComputerName Computer1, Computer2
 
    This runs winsat.exe prepop on the remote computers, Computer1
    and Computer2, and returns the Win32_WinSat scores using default
    credentials
 
.EXAMPLE
    Get-d00mWinsatScore -Credential (Get-Credential)
 
    This runs winsat.exe prepop on the local computer and returns
    the Win32_WinSat scores using the specified credentials
 
#>

function Get-d00mWinsatScoreReport
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        [Parameter()]
        [pscredential]$Credential
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        $start      = Get-Date
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            $sessionParams = @{ComputerName = $computer
                               ErrorAction  = 'Stop'}
            if ($Credential -ne $null)
            {
                $sessionParams.Add('Credential', $Credential)
                Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
            }
            else
            {
                Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
            }
            $session = New-PSSession @sessionParams
            $cimSession = New-CimSession @sessionParams

            Write-Verbose -Message ('{0} : {1} : Running winsat.exe prepop' -f $cmdletName, $computer)
            Invoke-Command -Session $session -ScriptBlock {
                Start-Process -FilePath winsat.exe -ArgumentList 'prepop' -NoNewWindow
            }
            Remove-PSSession -Session $session

            Write-Verbose -Message ('{0} : {1} : Getting Win32_Winsat' -f $cmdletName, $computer)
            $cimParams = @{ClassName   = 'Win32_WinSat'
                           CimSession  = $cimSession
                           ErrorAction = 'Stop'}
            $cim = Get-CimInstance @cimParams
            Remove-CimSession -CimSession $cimSession

            New-Object -TypeName psobject -Property @{ComputerName  = $computer
                                                      CPUScore      = $cim.CPUScore
                                                      D3DScore      = $cim.D3DScore
                                                      DiskScore     = $cim.DiskScore
                                                      GraphicsScore = $cim.GraphicsSCore
                                                      MemoryScore   = $cim.MemoryScore} |
                Write-Output
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}