Chapters/scripting-at-scale/geteventlogs.ps1

#Requires -version 5.0

[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[ValidateNotNullorEmpty()]
[string[]]$Computername,

[ValidateSet("Error","Warning","Information","SuccessAudit","FailureAudit")]
[string[]]$EntryType = @("Error","Warning"),

[ValidateSet("System","Application","Security",
"Active Directory Web Services","DNS Server")]
[string]$Logname = "System",

[datetime]$After = (Get-Date).AddHours(-24),

[Alias("path")]
[string]$OutputPath = "c:\work"
)

#define a hashtable of parameters for Write-Progress

$progParam = @{
    Activity = $MyInvocation.MyCommand
    Status = "Gathering $($EntryType -join ",") entries from $logname after $after."
    currentOperation = $null
}

Write-Progress @progParam

#invoke the command remotely as a job
$jobs=@()
foreach ($computer in $computername) {
    $progParam.CurrentOperation = "Querying: $computer"
    Write-progress @progParam
    $jobs+=Invoke-Command {
        Get-EventLog -LogName $using:logname -After $using:after -EntryType $using:entrytype
} -ComputerName $Computer -AsJob
} #foreach

do {
    $count = ($jobs | get-job | where state -eq 'Running').count
    $progParam.CurrentOperation = "Waiting for $count remote commands to complete"
    Write-progress @progParam
} while ($count -gt 0)

$progParam.CurrentOperation =  "Receiving job results"
Write-Progress @progParam
$data = $jobs | Receive-job

if ($data) { 
    $progParam.CurrentOperation = "Creating HTML report"
    Write-Progress @progparam

    #create html report
    $fragments = @()
    $fragments += "<H1>Summary from $After</H1>"
    $fragments += "<H2>Count by server</H2>"
    $fragments += $data | group -Property Machinename  | 
    Sort Count -Descending | Select Count,Name |
    ConvertTo-HTML -As table -Fragment
    $fragments += "<H2>Count by source</H2>"
    $fragments += $data | group -Property source  | 
    Sort Count -Descending | Select Count,Name |
    ConvertTo-HTML -As table -Fragment

    $fragments += "<H2>Detail</H2>"
    $fragments += $data | Select Machinename,TimeGenerated,Source,EntryType,Message |
     ConvertTo-html -as Table -Fragment

# the here string needs to be left justified
$head = @"
<Title>Event Log Summary</Title>
<style>
h2 {
width:95%;
background-color:#7BA7C7;
font-family:Tahoma;
font-size:10pt;
font-color:Black;
}
body { background-color:#FFFFFF;
       font-family:Tahoma;
       font-size:10pt; }
td, th { border:1px solid black;
         border-collapse:collapse; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px;}
</style>
"@


    $html = ConvertTo-Html -Body $fragments -PostContent "<h6>$(Get-Date)</h6>" -Head $head

    #save results to a file
    $filename = Join-path -Path $OutputPath -ChildPath "$(Get-Date -UFormat '%Y%m%d_%H%M')_EventlogReport.htm"
    $progparam.CurrentOperation = "Saving file to $filename"
    Write-Progress @progParam
    start-sleep -Seconds 1

    Set-content -Path $filename -Value $html -Encoding Ascii 
    #write the result file to the pipeline
    Get-item -Path $filename

} #if data
else {
    Write-Host "No matching event entries found." -ForegroundColor Magenta
}

#clean up jobs if any
if ($jobs) {
    $jobs | Remove-Job
}