PSBlackListChecker.psm1
[string[]] $Script:BlackLists = @( 'b.barracudacentral.org' 'spam.rbl.msrbl.net' 'zen.spamhaus.org' 'bl.deadbeef.com' 'bl.emailbasura.org' 'bl.spamcannibal.org' 'bl.spamcop.net' 'blackholes.five-ten-sg.com' 'blacklist.woody.ch' 'bogons.cymru.com' 'cbl.abuseat.org' 'cdl.anti-spam.org.cn' 'combined.abuse.ch' 'combined.rbl.msrbl.net' 'db.wpbl.info' 'dnsbl-1.uceprotect.net' 'dnsbl-2.uceprotect.net' 'dnsbl-3.uceprotect.net' # 'dnsbl.ahbl.org' # as per https://ahbl.org/ was terminated in 2015 'dnsbl.cyberlogic.net' 'dnsbl.inps.de' #'dnsbl.njabl.org' # supposedly doesn't work properly anymore 'dnsbl.sorbs.net' 'drone.abuse.ch' 'drone.abuse.ch' 'duinv.aupads.org' 'dul.dnsbl.sorbs.net' 'dul.ru' 'dyna.spamrats.com' 'dynip.rothen.com' 'http.dnsbl.sorbs.net' 'images.rbl.msrbl.net' 'ips.backscatterer.org' 'ix.dnsbl.manitu.net' 'korea.services.net' 'misc.dnsbl.sorbs.net' 'noptr.spamrats.com' 'ohps.dnsbl.net.au' 'omrs.dnsbl.net.au' 'orvedb.aupads.org' 'osps.dnsbl.net.au' 'osrs.dnsbl.net.au' 'owfs.dnsbl.net.au' 'owps.dnsbl.net.au' 'pbl.spamhaus.org' 'phishing.rbl.msrbl.net' 'probes.dnsbl.net.au' 'proxy.bl.gweep.ca' 'proxy.block.transip.nl' 'psbl.surriel.com' 'rbl.interserver.net' 'rdts.dnsbl.net.au' 'relays.bl.gweep.ca' 'relays.bl.kundenserver.de' 'relays.nether.net' 'residential.block.transip.nl' 'ricn.dnsbl.net.au' 'rmst.dnsbl.net.au' 'sbl.spamhaus.org' 'short.rbl.jp' 'smtp.dnsbl.sorbs.net' 'socks.dnsbl.sorbs.net' 'spam.abuse.ch' 'spam.dnsbl.sorbs.net' 'spam.spamrats.com' 'spamlist.or.kr' 'spamrbl.imp.ch' 't3direct.dnsbl.net.au' #'tor.ahbl.org' # as per https://ahbl.org/ was terminated in 2015 'tor.dnsbl.sectoor.de' 'torserver.tor.dnsbl.sectoor.de' 'ubl.lashback.com' 'ubl.unsubscore.com' 'virbl.bit.nl' 'virus.rbl.jp' 'virus.rbl.msrbl.net' 'web.dnsbl.sorbs.net' 'wormrbl.imp.ch' 'xbl.spamhaus.org' 'zombie.dnsbl.sorbs.net' ) $Script:ScriptBlockNetDNS = { param ( [string] $Server, [string] $IP, [bool] $QuickTimeout, [bool] $Verbose ) if ($Verbose) { $verbosepreference = 'continue' } $ReversedIP = ($IP -split '\.')[3..0] -join '.' $FQDN = "$ReversedIP.$Server" try { $DnsCheck = [Net.DNS]::GetHostAddresses($fqdn) } catch { $DnsCheck = $null } if ($null -ne $DnsCheck) { $ServerData = [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = if ($null -eq $DNSCheck.IPAddressToString) { $false } else { $true } Answer = $DnsCheck.IPAddressToString -join ', ' TTL = '' } } else { $ServerData = [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = $false Answer = "" TTL = '' } } return $ServerData } $Script:ScriptBlockNetDNSSlow = { param ( [string[]] $Servers, [string[]] $IPs, [bool] $QuickTimeout, [bool] $Verbose ) if ($Verbose) { $verbosepreference = 'continue' } $Blacklisted = foreach ($Server in $Servers) { foreach ($IP in $IPS) { [string] $ReversedIP = ($IP -split '\.')[3..0] -join '.' [string] $FQDN = "$ReversedIP.$Server" try { $DnsCheck = [Net.DNS]::GetHostAddresses($FQDN) } catch { $DnsCheck = $null } if ($null -ne $DnsCheck) { [PSCustomObject] @{ IP = $ip FQDN = $fqdn BlackList = $server IsListed = if ($null -eq $DNSCheck.IPAddressToString) { $false } else { $true } Answer = $DnsCheck.IPAddressToString -join ', ' TTL = '' } } else { [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = $false Answer = '' TTL = '' } } } } return $Blacklisted } $Script:ScriptBlockResolveDNS = { param ( [string] $Server, [string] $IP, [bool] $QuickTimeout, [bool] $Verbose, [string[]] $DNSServer = '' ) if ($Verbose) { $verbosepreference = 'continue' } [string] $ReversedIP = ($IP -split '\.')[3..0] -join '.' [string] $FQDN = "$ReversedIP.$Server" [int] $Count = 0 [bool] $Loaded = $false Do { try { Import-Module -Name 'DnsClient' -Verbose:$false $Loaded = $true } catch { Write-Warning "DNSClient Import Error ($Server / $FQDN / $IP): $_. Retrying." } $Count++ if ($Loaded -eq $false -and $Count -eq 5) { Write-Warning "DNSClient Import failed. Skipping check on $Server / $FQDN / $IP" } } until ($Loaded -eq $false -or $Count -eq 5) if ($DNSServer -ne '') { $DnsCheck = Resolve-DnsName -Name $fqdn -ErrorAction SilentlyContinue -NoHostsFile -QuickTimeout:$QuickTimeout -Server $DNSServer -DnsOnly # Impact of using -QuickTimeout unknown } else { $DnsCheck = Resolve-DnsName -Name $fqdn -ErrorAction SilentlyContinue -NoHostsFile -QuickTimeout:$QuickTimeout -DnsOnly } if ($null -ne $DnsCheck) { $ServerData = [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = if ($null -eq $DNSCheck.IpAddress) { $false } else { $true } Answer = $DnsCheck.IPAddress -join ', ' TTL = $DnsCheck.TTL -join ', ' } } else { $ServerData = [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = $false Answer = '' TTL = '' } } return $ServerData } $Script:ScriptBlockResolveDNSSlow = { param ( [string[]] $Servers, [string[]] $IPs, [bool] $QuickTimeout, [bool] $Verbose, [string[]] $DNSServer = '' ) if ($Verbose) { $verbosepreference = 'continue' } $Blacklisted = foreach ($Server in $Servers) { foreach ($IP in $IPS) { $ReversedIP = ($IP -split '\.')[3..0] -join '.' $FQDN = "$ReversedIP.$Server" if ($DNSServer -ne '') { $DnsCheck = Resolve-DnsName -Name $fqdn -ErrorAction SilentlyContinue -NoHostsFile -QuickTimeout:$QuickTimeout -Server $DNSServer -DnsOnly # Impact of using -QuickTimeout unknown } else { $DnsCheck = Resolve-DnsName -Name $fqdn -ErrorAction SilentlyContinue -NoHostsFile -QuickTimeout:$QuickTimeout -DnsOnly } if ($null -ne $DnsCheck) { [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = if ($null -eq $DNSCheck.IpAddress) { $false } else { $true } Answer = $DnsCheck.IPAddress -join ', ' TTL = $DnsCheck.TTL -join ', ' } } else { [PSCustomObject] @{ IP = $IP FQDN = $FQDN BlackList = $Server IsListed = $false Answer = '' TTL = '' } } } } return $Blacklisted } function Search-BlackList { <# .SYNOPSIS Search-Blacklist searches if particular IP is blacklisted on DNSBL Blacklists. .DESCRIPTION Long description .PARAMETER IPs Parameter description .PARAMETER BlacklistServers Parameter description .PARAMETER ReturnAll Parameter description .PARAMETER RunType Parameter description .PARAMETER SortBy Parameter description .PARAMETER SortDescending Parameter description .PARAMETER QuickTimeout Parameter description .PARAMETER MaxRunspaces Parameter description .PARAMETER ExtendedOutput Parameter description .EXAMPLE Search-BlackList -IP '89.25.253.1' | Format-Table .EXAMPLE Search-BlackList -IP '89.25.253.1' -SortBy Blacklist | Format-Table .EXAMPLE Search-BlackList -IP '89.25.253.1','195.55.55.55' -SortBy Ip -ReturnAll | Format-Table .NOTES General notes #> [cmdletbinding()] param ( [alias('IP')][string[]] $IPs, [string[]] $BlacklistServers = $Script:BlackLists, [switch] $ReturnAll, [ValidateSet('NoWorkflowAndRunSpaceNetDNS', 'NoWorkflowAndRunSpaceResolveDNS', 'RunSpaceWithResolveDNS', 'RunSpaceWithNetDNS', 'WorkflowResolveDNS', 'WorkflowWithNetDNS')] [string]$RunType, [ValidateSet('IP', 'BlackList', 'IsListed', 'Answer', 'FQDN')][string] $SortBy = 'IsListed', [switch] $SortDescending, [switch] $QuickTimeout, [int] $MaxRunspaces = 10, [string[]] $DNSServer = '', [switch] $ExtendedOutput ) if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { $Verbose = $true } else { $Verbose = $false } # will remove this after a while if ($RunType -eq 'WorkflowResolveDNS') { Write-Warning 'Worflows are not supported anymore due to PowerShell 6 complaining. Please use other modes.' Exit } elseif ($RunType -eq 'WorkflowWithNetDNS') { Write-Warning 'Worflows are not supported anymore due to PowerShell 6 complaining. Please use other modes.' Exit } # no parameter given (and it's expected) if ($RunType -eq '') { $RunType = 'RunSpaceWithNetDNS' <# if ($PSVersionTable.Platform -eq 'Unix') { $RunType = 'RunSpaceWithNetDNS' } else { $RunType = 'RunSpaceWithResolveDNS' } #> } # checks whether Runspaces are not set for use on Unix (usually forced by user) if ($PSVersionTable.Platform -eq 'Unix') { if ($RunType -eq 'RunSpaceWithResolveDNS') { $RunType = 'RunSpaceWithNetDNS' Write-Warning 'Search-BlackList - changing RunType to RunSpaceWithNetDNS since Resolve-DNSName is not available on Linux/MacOS' } elseif ($RunType -eq 'NoWorkflowAndRunSpaceResolveDNS') { $RunType = 'NoWorkflowAndRunSpaceNetDNS' Write-Warning 'Search-BlackList - changing RunType to RunSpaceWithNetDNS since Resolve-DNSName is not available on Linux/MacOS' } } if ($DNSServer -ne '' -and $RunType -like 'NetDNS') { Write-Warning 'Search-BlackList - Setting DNSServer is not supported for Net.DNS. Resetting to default values.' $DNSServer = '' } Write-Verbose "Search-Blacklist - Runtype: $RunType ReturnAll: $ReturnAll, SortBy: $SortBy MaxRunspaces: $MaxRunspaces SortDescending: $SortDescending" If ($RunType -eq 'NoWorkflowAndRunSpaceNetDNS') { $Table = Invoke-Command -ScriptBlock $Script:ScriptBlockNetDNSSlow -ArgumentList $BlacklistServers, $IPs, $QuickTimeout, $Verbose } elseif ($RunType -eq 'NoWorkflowAndRunSpaceResolveDNS') { $Table = Invoke-Command -ScriptBlock $Script:ScriptBlockResolveDNSSlow -ArgumentList $BlacklistServers, $IPs, $QuickTimeout, $Verbose, $DNSServer } elseif ($RunType -eq 'RunSpaceWithResolveDNS') { ### Define Runspace START $pool = New-Runspace -MaxRunspaces $maxRunspaces -Verbose:$Verbose ### Define Runspace END $runspaces = foreach ($Server in $BlacklistServers) { foreach ($IP in $IPs) { $Parameters = @{ Server = $Server IP = $IP QuickTimeout = $QuickTimeout Verbose = $Verbose DNSServer = $DNSServer } Start-Runspace -ScriptBlock $Script:ScriptBlockResolveDNS -Parameters $Parameters -RunspacePool $pool -Verbose:$Verbose } } ### End Runspaces START $Output = Stop-Runspace -Runspaces $runspaces -FunctionName 'Search-BlackList' -RunspacePool $pool -Verbose:$Verbose -ErrorAction Continue -ErrorVariable MyErrors -ExtendedOutput:$ExtendedOutput if ($ExtendedOutput) { $Output # returns hashtable of Errors and Output Exit } else { $Table = $Output } ### End Runspaces END } elseif ($RunType -eq 'RunSpaceWithNetDNS') { ### Define Runspace START $pool = New-Runspace -MaxRunspaces $maxRunspaces -Verbose:$Verbose ### Define Runspace END $runspaces = foreach ($server in $BlacklistServers) { foreach ($ip in $IPs) { $Parameters = @{ Server = $Server IP = $IP QuickTimeout = $QuickTimeout Verbose = $Verbose #DNSServer = $DNSServer } Start-Runspace -ScriptBlock $Script:ScriptBlockNetDNS -Parameters $Parameters -RunspacePool $pool -Verbose:$Verbose } } ### End Runspaces START $Output = Stop-Runspace -Runspaces $runspaces -FunctionName 'Search-BlackList' -RunspacePool $pool -Verbose:$Verbose -ExtendedOutput:$ExtendedOutput if ($ExtendedOutput) { $Output # returns hashtable of Errors and Output Exit } else { $Table = $Output } ### End Runspaces END } if ($SortDescending -eq $true) { $Table = $Table | Sort-Object $SortBy -Descending } else { $Table = $Table | Sort-Object $SortBy } if ($ReturnAll -eq $true) { return $Table | Select-Object IP, FQDN, BlackList, IsListed, Answer, TTL } else { return $Table | Where-Object { $_.IsListed -eq $true } | Select-Object IP, FQDN, BlackList, IsListed, Answer, TTL } } function Set-EmailBody($TableData, $TableWelcomeMessage) { $body = "<p><i>$TableWelcomeMessage</i>" if ($($TableData | Measure-Object).Count -gt 0) { $body += $TableData | ConvertTo-Html -Fragment | Out-String $body = $body -replace ' Added', "<font color=`"green`"><b> Added</b></font>" $body = $body -replace ' Removed', "<font color=`"red`"><b> Removed</b></font>" $body = $body -replace ' Deleted', "<font color=`"red`"><b> Deleted</b></font>" $body = $body -replace ' Changed', "<font color=`"blue`"><b> Changed</b></font>" $body = $body -replace ' Change', "<font color=`"blue`"><b> Change</b></font>" $body = $body -replace ' Disabled', "<font color=`"red`"><b> Disabled</b></font>" $body = $body -replace ' Enabled', "<font color=`"green`"><b> Enabled</b></font>" $body = $body -replace ' Locked out', "<font color=`"red`"><b> Locked out</b></font>" $body = $body -replace ' Lockouts', "<font color=`"red`"><b> Lockouts</b></font>" $body = $body -replace ' Unlocked', "<font color=`"green`"><b> Unlocked</b></font>" $body = $body -replace ' Reset', "<font color=`"blue`"><b> Reset</b></font>" $body += '</p>' } else { $body += '<br><i>No changes happend during that period.</i></p>' } return $body } function Set-EmailReportDetails { param( $FormattingOptions, $ReportOptions, $TimeToGenerate ) $DateReport = get-date # HTML Report settings $Report = "<p style=`"background-color:white;font-family:$($FormattingOptions.FontFamily);font-size:$($FormattingOptions.FontSize)`">" $Report += "<strong>Report Time:</strong> $DateReport <br>" $Report += "<strong>Time to generate:</strong> $($TimeToGenerate.Hours) hours, $($TimeToGenerate.Minutes) minutes, $($TimeToGenerate.Seconds) seconds, $($TimeToGenerate.Milliseconds) milliseconds <br>" if ($PSVersionTable.Platform -ne 'Unix') { $Report += "<strong>Account Executing Report :</strong> $env:userdomain\$($env:username.toupper()) on $($env:ComputerName.toUpper()) <br>" } else { # needs filling in. } $Report += '<strong>Checking for monitored IPs :</strong>' $Report += '<ul>' foreach ($ip in $ReportOptions.MonitoredIps.Values) { $Report += "<li>ip:</strong> $ip</li>" } $Report += '</ul>' $Report += '</p>' return $Report } function Start-ReportBlackLists { [cmdletbinding()] param( $EmailParameters, $FormattingParameters, $ReportOptions, [switch] $OutputErrors ) $Errors = @{ Teams = $false Slack = $false Discord = $false } $EmailBody = Set-EmailHead -FormattingOptions $FormattingParameters $EmailBody += Set-EmailReportBranding -FormattingOptions $FormattingParameters $TeamID = Format-FirstXChars -Text $ReportOptions.NotificationsTeams.TeamsID -NumberChars 25 $SlackID = Format-FirstXChars -Text $ReportOptions.NotificationsSlack.Uri -NumberChars 25 $DiscordID = Format-FirstXChars -Text $ReportOptions.NotificationsDiscord.Uri -NumberChars 25 Write-Verbose "Start-ReportBlackLists - TeamsID: $TeamID" Write-Verbose "Start-ReportBlackLists - SlackID: $SlackID" Write-Verbose "Start-ReportBlackLists - DiscordID: $DiscordID" $Ips = @() foreach ($ip in $ReportOptions.MonitoredIps.Values) { $Ips += $ip } $Time = Measure-Command -Expression { if ($null -eq $ReportOptions.SortBy) { $ReportOptions.SortBy = 'IsListed' } if ($null -eq $ReportOptions.SortDescending) { $ReportOptions.SortDescending = $true } if ($ReportOptions.NotificationsEmail.EmailAllResults) { $BlackListCheck = Search-BlackList -IP $Ips -SortBy $ReportOptions.SortBy -SortDescending:$ReportOptions.SortDescending -ReturnAll } else { $BlackListCheck = Search-BlackList -IP $Ips -SortBy $ReportOptions.SortBy -SortDescending:$ReportOptions.SortDescending } } $EmailBody += Set-EmailReportDetails -FormattingOptions $FormattingParameters -ReportOptions $ReportOptions -TimeToGenerate $Time $EmailBody += Set-EmailBody -TableData $BlackListCheck -TableWelcomeMessage 'Following blacklisted servers' if ($null -eq $ReportOptions.NotificationsEmail) { # Not upgraded config / Legacy config $ReportOptions.NotificationsEmail = @{ Use = $true EmailPriorityWhenBlacklisted = $ReportOptions.EmailPriorityWhenBlacklisted EmailPriorityStandard = $ReportOptions.EmailPriorityStandard EmailAllResults = $ReportOptions.EmailAllResults EmailAlways = $ReportOptions.EmailAlways } } if ($BlackListCheck.IsListed -contains $true) { $EmailParameters.EmailPriority = $ReportOptions.NotificationsEmail.EmailPriorityWhenBlacklisted } else { $EmailParameters.EmailPriority = $ReportOptions.NotificationsEmail.EmailPriorityStandard } if ($ReportOptions.NotificationsEmail.Use) { if ($ReportOptions.EmailAlways -eq $true -or $BlackListCheck.IsListed -contains $true) { if ($FormattingParameters.CompanyBranding.Inline) { $SendMail = Send-Email -EmailParameters $EmailParameters -Body $EmailBody -InlineAttachments @{logo = $FormattingParameters.CompanyBranding.Logo} -Verbose } else { $SendMail = Send-Email -EmailParameters $EmailParameters -Body $EmailBody } } } if ($BlackListCheck.IsListed -contains $true) { $BlackListLimited = $BlackListCheck | Where-Object { $_.IsListed -eq $true } if ($ReportOptions.NotificationsTeams.Use) { [string] $MessageTitle = $ReportOptions.NotificationsTeams.MessageTitle [string] $ActivityImageLink = $ReportOptions.NotificationsTeams.MessageImageLink [RGBColors] $Color = [RGBColors]::Red $Sections = @() foreach ($Server in $BlackListLimited) { [string] $ActivityTitle = "Blacklisted IP **$($Server.IP)**" if ($ReportOptions.NotificationsTeams.MessageButtons) { $Button1 = New-TeamsButton -Name "Check BlackList" -Link "https://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a$($Server.Ip)&run=toolpage" $Button2 = New-TeamsButton -Name "Check SMTP" -Link "https://mxtoolbox.com/SuperTool.aspx?action=smtp%3a$($Server.Ip)&run=toolpage" $Sections += New-TeamsSection ` -ActivityTitle $ActivityTitle ` -ActivitySubtitle "Found on blacklist **$($Server.Blacklist)**" ` -ActivityImageLink $ActivityImageLink ` -ActivityText "Everybody panic!" ` -Buttons $Button1, $Button2 } else { $Sections += New-TeamsSection ` -ActivityTitle $ActivityTitle ` -ActivitySubtitle "Found on blacklist **$($Server.Blacklist)**" ` -ActivityImageLink $ActivityImageLink ` -ActivityText "Responses: $($Server.Answer)" } } try { $TeamsOutput = Send-TeamsMessage ` -URI $ReportOptions.NotificationsTeams.TeamsID ` -MessageTitle $MessageTitle ` -Color $Color ` -Sections $Sections ` -Supress $false } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning "Couldn't send to Teams - Error occured: $ErrorMessage" $Errors.Teams = $true } #Write-Color @script:WriteParameters -Text "[i] Teams output: ", $Data -Color White, Yellow } if ($ReportOptions.NotificationsSlack.Use) { $MessageTitle = $ReportOptions.NotificationsSlack.MessageTitle [string] $ActivityImageLink = $ReportOptions.NotificationsSlack.MessageImageLink $Attachments = @() foreach ($Server in $BlackListLimited) { $Attachments += New-SlackMessageAttachment -Color $_PSSlackColorMap.red ` -Title "IP $($Server.IP) is Blacklisted" ` -TitleLink "https://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a$($Server.Ip)&run=toolpage" ` -Text $ReportOptions.NotificationsSlack.MessageText ` -Pretext "Found on blacklist $($Server.Blacklist)" ` -Fallback 'Your client is bad' } try { $SlackOutput = New-SlackMessage -Attachments $Attachments ` -Channel $ReportOptions.NotificationsSlack.Channel ` -IconEmoji $ReportOptions.NotificationsSlack.MessageEmoji ` -AsUser ` -Username $ReportOptions.NotificationsSlack.MessageAsUser | ` Send-SlackMessage -Uri $ReportOptions.NotificationsSlack.URI } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning "Couldn't send to Slack - Error occured: $ErrorMessage" $Errors.Slack = $true } #Write-Color @script:WriteParameters -Text "[i] Slack output: ", $Data -Color White, Yellow } if ($ReportOptions.NotificationsDiscord.Use) { if ($null -eq $ReportOptions.NotificationsDiscord.MessageInline) { $ReportOptions.NotificationsDiscord.MessageInline = $false } try { $Facts = foreach ($Server in $BlackListLimited) { [string] $ActivityTitle = "Blacklisted IP $($Server.IP)" [string] $ActivityValue = "Found on blacklist $($Server.Blacklist)" New-DiscordFact -Name $ActivityTitle -Value $ActivityValue -Inline $ReportOptions.NotificationsDiscord.MessageInline } $Thumbnail = New-DiscordThumbnail -Url $ReportOptions.NotificationsDiscord.MessageImageLink $Author = New-DiscordAuthor -Name 'PSBlacklistChecker' -IconUrl $ReportOptions.NotificationsDiscord.MessageImageLink $Section = New-DiscordSection -Title $ReportOptions.NotificationsDiscord.MessageText ` -Description '' ` -Facts $Facts ` -Color $ReportOptions.NotificationsDiscord.MessageColor ` -Author $Author ` -Thumbnail $Thumbnail #-Image $Thumbnail Send-DiscordMessage -WebHookUrl $ReportOptions.NotificationsDiscord.Uri ` -Sections $Section ` -AvatarName $ReportOptions.NotificationsDiscord.MessageAsUser ` -AvatarUrl $ReportOptions.NotificationsDiscord.MessageAsUserImage -Verbose } catch { $ErrorMessage = $_.Exception.Message -replace "`n", " " -replace "`r", " " Write-Warning "Couldn't send to Discord - Error occured: $ErrorMessage" $Errors.Discord = $true } } if ($OutputErrors) { return $Errors } } } Export-ModuleMember ` -Function @('Search-BlackList','Start-ReportBlackLists') ` -Alias @() |