Resources/WebsiteFailedLogins.alert.psm1
Function Submit-Alert { <# .SYNOPSIS Submits alert to Windows Event Log or via SMTP. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # INI Configuration. $IniConfig , [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # Alert data. $AlertData , [Parameter(Mandatory=$false)] [switch] # Signifies terminating error. $TerminatingError ) Write-Verbose -Message '[Submit-Alert] Processing alert.' $alertSplat = @{ 'IniConfig' = $IniConfig 'AlertData' = $AlertData } if ($TerminatingError -eq $true) { $alertSplat.Add('TerminatingError',$true) } if ($IniConfig.Alert.Method -imatch 'WinEvent') { Write-EventAlert @alertSplat } if ($IniConfig.Alert.Method -imatch 'Smtp') { Send-SmtpAlert @alertSplat } } # End Function Submit-Alert Function Write-EventAlert { <# .SYNOPSIS Writes alert to windows event log. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # INI Configuration. $IniConfig , [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # Alert Data. $AlertData , [Parameter(Mandatory=$false)] [switch] # Signifies terminating error. $TerminatingError ) Write-Verbose -Message '[Write-EventAlert] Writing alert to Event Log.' $formattedAlertData = Get-FormattedAlertData -DataType $IniConfig.Alert.DataType ` -AlertData $AlertData $eventProperties = @{ 'LogName' = $IniConfig.WinEvent.Logname 'Source' = $IniConfig.WinEvent.Source 'EntryType' = $IniConfig.WinEvent.EntryType 'EventId' = $IniConfig.WinEvent.FailedLoginsPerIPEventId 'ErrorAction' = 'Stop' 'Message' = $formattedAlertData } if ($AlertData.ContainsKey('TotalFailedLogins')) { $eventProperties.EventId = $IniConfig.WinEvent.TotalFailedLoginsEventId } if ($TerminatingError) { $eventProperties.EntryType = 'Error' $eventProperties.EventId = 200 $eventProperties.Message = Get-FormattedAlertData -DataType 'json' -AlertData $AlertData } try { Write-EventLog @eventProperties } catch { $e = $_ Write-Error -Message '[Error][Script][Alert] Event log write failed.' Write-Error -Message $('[Error][Script][Alert] Exception: {0}' -f $e.Exception.Message) } } # End Function Write-EventAlert Function Send-SmtpAlert { <# .SYNOPSIS Sends alert via SMTP. #> [CmdletBinding()] param( [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # INI Configuration. $IniConfig , [Parameter(Mandatory=$true)] [System.Collections.Hashtable] # Alert Data. $AlertData , [Parameter(Mandatory=$false)] [switch] # Signifies terminating error $TerminatingError ) Write-Verbose -Message '[Send-SmtpAlert] Sending alert via SMTP.' $formattedAlertData = Get-FormattedAlertData -DataType $IniConfig.Alert.DataType ` -AlertData $AlertData $emailSplat = @{ 'To' = $IniConfig.Smtp.To 'From' = $IniConfig.Smtp.From 'Subject' = $IniConfig.Smtp.Subject 'SmtpServer' = $IniConfig.Smtp.Server 'Port' = $IniConfig.Smtp.Port 'Body' = $formattedAlertData 'UseSsl' = $true 'ErrorAction' = 'Stop' } if ($AlertData.ContainsKey('TotalFailedLogins')) { $emailSplat.Subject = '[TotalFailedLogins] {0}' -f $IniConfig.Smtp.Subject } if ($AlertData.ContainsKey('ClientIP')) { $emailSplat.Subject = '[FailedLoginsPerIP][{0}] {1}' -f $AlertData.ClientIP,$IniConfig.Smtp.Subject } if ($TerminatingError) { $emailSplat.Subject = '[TerminatingError] {0}' -f $IniConfig.Smtp.Subject $emailSplat.Body = Get-FormattedAlertData -DataType 'json' -AlertData $AlertData } if ([System.String]::IsNullOrEmpty($IniConfig.Smtp.CredentialXml) -eq $false) { $emailSplat.Add('Credential', $(Import-Clixml -LiteralPath $IniConfig.Smtp.CredentialXml)) } try { Send-MailMessage @emailSplat } catch { $e = $_ Write-Error -Message '[Error][Script][Alert] Smtp send failed.' Write-Error -Message $('[Error][Script][Alert] Exception: {0}' -f $e.Exception.Message) } } # End Function Send-SmtpAlert Function Get-FormattedAlertData { <# .SYNOPSIS Formats the alert data into desired format. #> [CmdletBinding()] [OutputType('System.String')] param( [Parameter(Mandatory=$true)] [System.String] # Data type format. $DataType , [Parameter(Mandatory=$true)] # Alert Data. $AlertData ) Write-Verbose -Message "[Get-FormattedAlertData] formatting data as $($DataType.ToUpper())." switch ($DataType.ToUpper()) { 'XML' { return [System.Management.Automation.PSSerializer]::Serialize($AlertData,2) } 'JSON' { return $($AlertData | ConvertTo-Json) } default { # Text [string[]] $stringData = $AlertData.Keys | ForEach-Object{ "$($_) = $($AlertData[$($_)])" } return $($stringData -Join [System.Environment]::NewLine) } } } # End Function Get-FormattedAlertData Export-ModuleMember -Function 'Submit-Alert' |