Private/Helper/Debug-SPFRecord.ps1
<#
Copyright © 2024 Integris. For internal company use only. All rights reserved. #> FUNCTION Get-DNSEmailHealthCheck { [CmdletBinding()] PARAM ( [Parameter(Mandatory)] [string[]]$Domain, [switch]$IssuesOnly = $False, [switch]$CheckBlacklist = $False ) FUNCTION Debug-SPFRecord { <# .SYNOPSIS Checks SPF Records for correct syntax. .DESCRIPTION Checks SPF Records for correct syntax and returns the results .EXAMPLE Debug-DNSRecordSPF IntegrisIT.com Checks SPF Records for correct syntax and returns the results #> param ( [Parameter(Mandatory)] [string]$Domain ) FUNCTION Format-SPFRecord { param ( [Parameter(Mandatory)] [string]$Domain2 ) $SPFRecord = Get-DNSRecordSPF $Domain2 -ErrorAction SilentlyContinue $SPFRecord = $SPFRecord.Value -Join "" $SPFRecord = ($SPFRecord -Replace ("v=spf1 ","")) RETURN $SPFRecord.Split(" ") } $Results = @() $LookupFQDNs = @() $LookupCount = 0 $Length = 0 $TXTRecord = Get-DNSRecordSPF $Domain -ErrorAction SilentlyContinue $SPFRecord = $TXTRecord.Value -Join "" $Length = $SPFRecord.Length $Split = Format-SPFRecord $Domain FOREACH ($Item in $Split) { IF ($Item -eq "a" -or $Item -eq "+a" -or $Item -like "a:*") { $LookupCount++; $LookupFQDNs += $Item } ELSEIF ($Item -eq "mx" -or $Item -eq "+mx" -or $Item -like "mx:*") { $LookupCount++; $LookupFQDNs += $Item } ELSEIF ($Item -like "*include:*" -or $Item -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item $Split2 = Format-SPFRecord ($Item -replace ("include:","")) FOREACH ($Item2 in $Split2) { IF ($Item2 -like "*include:*" -or $Item2 -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item2 $Split3 = Format-SPFRecord ($Item2 -replace ("include:","")) FOREACH ($Item3 in $Split3) { IF ($Item3 -like "*include:*" -or $Item3 -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item3 $Split4 = Format-SPFRecord ($Item3 -replace ("include:","")) FOREACH ($Item4 in $Split4) { IF ($Item4 -like "*include:*" -or $Item4 -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item4 $Split5 = Format-SPFRecord ($Item4 -replace ("include:","")) FOREACH ($Item5 in $Split5) { IF ($Item5 -like "*include:*" -or $Item5 -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item5 $Split6 = Format-SPFRecord ($Item5 -replace ("include:","")) FOREACH ($Item6 in $Split6) { IF ($Item6 -like "*include:*" -or $Item6 -like "*%{*") { $LookupCount++ $LookupFQDNs += $Item6 } } } } } } } } } } } } ### Syntax Checker ### Test Line #$SPFRecord = "v=spf1 ip6:1234:2234:2223::0000 a include:horses.net include:f02934hrjio2qjr39023jr203rk.net ?all" $SPFSyntaxErrors = @() IF ($SPFRecord -match " ") { $SPFSyntaxErrors += "Error: SPF has Unnecessary Spaces" } $SyntaxSplit = $SPFRecord.Split(" ") $SPFSyntaxVersionCount = 0 $SPFSyntaxInvalidIP4 = $False $SPFSyntaxInvalidIP6 = $False $SPFRecordInvalidFQDNCount = 0 $SPFFQDNDoesntResolveCount = 0 $SPFValidPolicyCount = 0 $SPFUnknownInvalidEntryFound = 0 $RedirectCount = 0 FOREACH ($Item in $SyntaxSplit) { IF ($null -eq $Item) { continue } IF ("" -eq $Item) { continue } IF ($Item -eq "mx") { continue } IF ($Item -eq "a") { continue } IF ($Item.Substring($Item.Length-3,1) -eq "/") { $Item = $Item.Substring(0,$Item.Length-3) } IF ($Item.Substring($Item.Length-2,1) -eq "/") { $Item = $Item.Substring(0,$Item.Length-2) } IF ($Item -eq "v=spf1") { $SPFSyntaxVersionCount++; continue } IF ($Item -like "*ip4:*") { TRY { $Test = [System.Net.IPAddress]($Item -replace ("ip4:","")); continue } CATCH { $SPFSyntaxInvalidIP4 = $True; $SPFSyntaxErrors+= "Invalid IPv4 Entry: $Item"; continue } } IF ($Item -match "ip6:") { TRY { $Test = [System.Net.IPAddress]($Item -replace ("ip6:","")); continue } CATCH { $SPFSyntaxInvalidIP6 = $True; $SPFSyntaxErrors+= "Invalid IPv6 Entry: $Item"; continue } } IF ($Item -match "include:" -or $Item -match "exists:" -or $Item -match "mx:" -or $Item -match "a:") { IF ($Item -match "{" -and $Item -match "}") { continue } TRY { $Test = $null $Test = Resolve-DnsName $Item.Split(":")[1] -ErrorAction SilentlyContinue IF ($null -eq $Test) { $SPFFQDNDoesntResolveCount++; $SPFSyntaxErrors+= "FQDN Entry Does Not Resolve: $Item"; } } CATCH { $SPFFQDNDoesntResolveCount++; $SPFSyntaxErrors+= "FQDN Entry Does Not Resolve: $Item"; } continue } IF ($Item -match "all") { IF ( $Item -match "~" -or $Item -match "-" -or $Item -match "\+" -or $Item -match "\?") { $SPFValidPolicyCount++; continue } } IF ($Item -match "redirect=") { $RedirectCount++; continue } $SPFUnknownInvalidEntryFound++ $SPFSyntaxErrors+= "Unknown Entry: $Item" } IF ($SPFSyntaxVersionCount -eq 0) { $SPFSyntaxErrors+= "Error: Missing Valid SPF Version" } IF ($SPFSyntaxVersionCount -gt 1) { $SPFSyntaxErrors+= "Error: Multiple Version Entries" } IF ($SPFValidPolicyCount -eq 0 -and $RedirectCount -eq 0) { $SPFSyntaxErrors+= "Error: Missing Valid SPF Policy" } IF ($SPFValidPolicyCount -gt 1) { $SPFSyntaxErrors+= "Error: Multiple Policy Entries" } $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Type = $TXTRecord.Type Name = $TXTRecord.Name LookupCount = $LookupCount LookupFQDNs = $LookupFQDNs Length = $Length Value = $TXTRecord.Value -Join "" SyntaxErrors = $SPFSyntaxErrors } RETURN $Results | Select Type, Name, LookupCount, LookupFQDNs, Length, Value, SyntaxErrors } FUNCTION Get-DNSEMailInfo { param ( [Parameter(Mandatory)] [string[]]$Domain, [switch]$MainProgressBarOff = $False, [switch]$SkipBlacklistCheck = $False ) $Results = @() $DomainCount = 0 $DomainCountTotal = $Domain.Count FOREACH ($Item in $Domain) { IF ($MainProgressBarOff -eq $False) { $DomainActivityMessage = "Getting E-Mail DNS Info" $DomainStatusMessage = "Checking $($DomainCount+1) of $DomainCountTotal - $Item" $DomainProgressPercent = [math]::round(($DomainCount / $DomainCountTotal * 100),0) Write-Progress -ID 64251342 -Activity $DomainActivityMessage -Status $DomainStatusMessage -PercentComplete $DomainProgressPercent } $DomainCount++ Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 1 of 7 - Getting DNS Records" -PercentComplete 0 $AllRecords = Get-DNSRecordAll $Item Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 2 of 7 - Counting MX Records" -PercentComplete 15 $HasMX = $False $HasSPF = $False $HasDMARC = $False $HasDKIM = $False ### Confirm if Each Record Type Exists FOREACH ($Record in $AllRecords) { IF ($Record.Purpose -eq "MX") { $HasMX = $True } IF ($Record.Purpose -eq "SPF") { $HasSPF = $True } IF ($Record.Purpose -eq "DMARC") { $HasDMARC = $True } IF ($Record.Purpose -eq "DKIM") { $HasDKIM = $True } } ### Confirm Count of Records IF ( (($AllRecords) | Where-Object { $_.Purpose -eq "MX" }).Count -eq $Null ) { $MXRecordCount = 1 } ELSE { $MXRecordCount = (($AllRecords) | Where-Object { $_.Purpose -eq "MX" }).Count } IF ( (($AllRecords) | Where-Object { $_.Purpose -eq "SPF" }).Count -eq $Null ) { $SPFRecordCount = 1 } ELSE { $SPFRecordCount = (($AllRecords) | Where-Object { $_.Purpose -eq "SPF" }).Count } IF ( (($AllRecords) | Where-Object { $_.Purpose -eq "DMARC" }).Count -eq $Null ) { $DMARCRecordCount = 1 } ELSE { $DMARCRecordCount = (($AllRecords) | Where-Object { $_.Purpose -eq "DMARC" }).Count } IF ( (($AllRecords) | Where-Object { $_.Purpose -eq "DKIM" }).Count -eq $Null ) { $DKIMRecordCount = 1 } ELSE { $DKIMRecordCount = (($AllRecords) | Where-Object { $_.Purpose -eq "DKIM" }).Count } Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 3 of 7 - Checking for Duplicate Records" -PercentComplete 30 ### Check for Duplicates Records $MXRecordDuplicateCount = ((($AllRecords) | Where-Object { $_.Purpose -eq "MX" }) | Group-Object Value | Where-Object { $_.Count -gt 1 }).Count $DKIMRecordDuplicateCount = ((($AllRecords) | Where-Object { $_.Purpose -eq "DKIM" }) | Group-Object Value | Where-Object { $_.Count -gt 1 }).Count Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 4 of 7 - Reviewing SPF Record" -PercentComplete 45 ### SPF Parsing $SPFCheck = Debug-DNSRecordSPF $Item $SPFSplit = ($SPFCheck.Value -replace ("v=spf1 ","")).Split(" ") $FailType = $SPFSplit[$SPFSplit.Length-1] $SPFSplit = $SPFSplit | Where-Object { $_ -like "*include:*" } ### SPF Fail Type $SPFFailString = "" IF ($FailType -match "~") { $SPFFailString = "Soft Fail"; $AlertString = "" } ELSEIF ($FailType -match "-") { $SPFFailString = "Fail"; $AlertString = "" } ELSEIF ($FailType -match "\+") { $SPFFailString = "Pass"; $AlertString = "Error: SPF Policy set to Pass" } ELSEIF ($FailType -match "\?") { $SPFFailString = "None"; $AlertString = "Error: SPF Policy set to None" } ELSEIF ($FailType -like "*redirect*") { $SPFFailString = "Redirected"; $AlertString = "" } ELSE { $FailType = ""; $SPFFailString = "Missing"; $AlertString = "Error: SPF Policy is Missing" } Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 5 of 7 - Reviewing DMCAR Record" -PercentComplete 60 ### DMARC Parsing $DMARCRecords = (($AllRecords) | Where-Object { $_.Purpose -eq "DMARC" }) FOREACH ($DMARCRecord in $DMARCRecords) { $DMARCVersion = ((($DMARCRecord.Value -replace (";"," ")) -replace (" "," "))).Split(" ") | Where-Object { $_ -like "*v=*" } $DMARCPolicy = ((($DMARCRecord.Value -replace (";"," ")) -replace (" "," "))).Split(" ") | Where-Object { $_ -like "*p=*" } $DMARCRUA = ((($DMARCRecord.Value -replace(";"," ")) -replace (" "," "))).Split(" ") | Where-Object { $_ -like "*rua=*" } } ### DMARC Fail Type $DMARCFailString = "" IF ($DMARCPolicy -eq "p=none") { $DMARCFailString = "Monitoring"; $AlertString = "Warning: DMARC Enforcement Not Enabled" } ELSEIF ($DMARCPolicy -eq "p=quarantine") { $DMARCFailString = "Quarantine"; $AlertString = "" } ELSEIF ($DMARCPolicy -eq "p=reject") { $DMARCFailString = "Reject"; $AlertString = "" } ELSE { $DMARCPolicy = ""; $DMARCFailString = "Missing"; $AlertString = "Error: DMARC Policy is Missing" } Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 6 of 7 - Getting WhoIS Info" -PercentComplete 75 $WhoISInfo = Get-WhoIS $Item Write-Progress -ID 61201542 -Activity "Collecting Data" -Status "Step 7 of 7 - Checking for Blacklist Entries" -PercentComplete 90 ### Check for Blacklistings $Blacklist = $Null $BlacklistCount = 0 IF ($SkipBlacklistCheck -eq $False) { $Blacklist = Get-EmailDomainBlacklist $Item $BlacklistCount = ($Blacklist.BlacklistedOn | select -Unique).Count } ### Join SPF Records FOREACH ($SPF in ($AllRecords | Where-Object { $_.Purpose -eq "SPF" })) { $SPF.Value = $SPF.Value -join "" } $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Registrar = $WhoISInfo.Registrar FirstRegistrationDate = $WhoISInfo.CreationDate HasMXRecord = $HasMX MXRecord = ($AllRecords | Where-Object { $_.Purpose -eq "MX" }).Value MXRecordCount = $MXRecordCount DuplicateMXRecord = ($MXRecordDuplicateCount -ne 0) HasSPFRecord = $HasSPF SPFRecord = ($AllRecords | Where-Object { $_.Purpose -eq "SPF" }).Value SPFRecordCount = $SPFRecordCount SPFLookupCount = $SPFCheck.LookupCount SPFLookupFQDNs = $SPFCheck.LookupFQDNs SPFPolicy = $SPFFailString SPFSyntaxErrors = $SPFCheck.SyntaxErrors HasDMARCRecord = $HasDMARC DMARCRecord = ($AllRecords | Where-Object { $_.Purpose -eq "DMARC" }).Value DMARCRecordCount = $DMARCRecordCount DMARCPolicy = $DMARCFailString HasDKIMRecord = $HasDKIM DKIMRecord = ($AllRecords | Where-Object { $_.Purpose -eq "DKIM" }).Value DKIMRecordCount = $DKIMRecordCount HasBlacklist = ($BlacklistCount -ne 0) BlacklistEntries = $Blacklist.BlacklistedOn } } RETURN $Results | Select Domain, Registrar, FirstRegistrationDate, HasMXRecord, MXRecord, MXRecordCount, DuplicateMXRecord, HasSPFRecord, SPFRecord, SPFRecordCount, SPFLookupCount, SPFLookupFQDNs, SPFPolicy, SPFSyntaxErrors, HasDMARCRecord, DMARCRecord, DMARCRecordCount, DMARCPolicy, HasDKIMRecord, DKIMRecord, DKIMRecordCount, HasBlacklist, BlacklistEntries } FUNCTION Get-EmailDomainBlacklist { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] #List of MX records to monitor if the parameter is not changed [string[]]$Domain ) #Blacklist Servers $BlacklistServers = @( 'b.barracudacentral.org' 'spam.rbl.msrbl.net' 'zen.spamhaus.org' 'bl.deadbeef.com' 'bl.spamcannibal.org' 'bl.spamcop.net' 'blackholes.five-ten-sg.com' 'blacklist.woody.ch' 'bogons.cymru.com' 'cbl.abuseat.org' 'combined.abuse.ch' 'combined.rbl.msrbl.net' 'db.wpbl.info' 'dnsbl-1.uceprotect.net' 'dnsbl-2.uceprotect.net' 'dnsbl-3.uceprotect.net' 'dnsbl.cyberlogic.net' 'dnsbl.inps.de' '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' 'spamrbl.imp.ch' 'spamsources.fabel.dk' 't3direct.dnsbl.net.au' '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' ) #Initialize Variables $Results = @() $MXInfo = @() $MXRecords = @() ### Collect MX Records FOREACH ($Name in $Domain) { $MXRecords += (Get-DNSRecordMX $Name).Value; $MXRecords += $Domain } $MXRecords = $MXRecords | select -Unique ### Collect IPs FOREACH ($MX in $MXRecords){ $IPs = ((Resolve-DnsName $MX) | Where-Object { $_.Type -eq "A" }).IPAddress $IPs = $IPs | Select -Unique FOREACH ($IP in $IPs) { IF ($MXInfo.IP -contains $IP) { continue } $MXInfo += New-Object PSObject -WarningAction SilentlyContinue -Property @{ MXRecord = $MX IP = $IP } } } $MXCount = 0 $MXCountTotal = $MXInfo.Count FOREACH ($Info in $MXInfo) { $MXActivityMessage = "Checking for Blacklist Entries..." $MXStatusMessage = "Checking $($MXCount+1) of $MXCountTotal - $($Info.MXRecord) ($($Info.IP)) " $MXProgressPercent = [math]::round(($MXCount / $MXCountTotal * 100),0) Write-Progress -ID 34572342 -Activity $MXActivityMessage -Status $MXStatusMessage -PercentComplete $MXProgressPercent $MXCount++ ### Check for Blacklisting $JobResults = $BlacklistServers | Start-RSJob { $Info = $Using:Info $ReversedIP = ($Info.IP -split '\.')[3..0] -join '.' $FQDN = "$reversedIP.$_" $BlacklistResults = New-Object PSObject TRY { Write-Verbose "Checking $IP against $server" $null = [System.Net.Dns]::GetHostEntry($FQDN) Add-Member -InputObject $BlacklistResults -MemberType NoteProperty -Name IP -Value $Info.IP Add-Member -InputObject $BlacklistResults -MemberType NoteProperty -Name "BlacklistedOn" -Value $_ Add-Member -InputObject $BlacklistResults -MemberType NoteProperty -Name "MXRecord" -Value $Info.MXRecord } CATCH { } RETURN $BlacklistResults } | Wait-RSJob | Receive-RSJob $Results = $JobResults | Where-Object { $_.IP -ne $null } } Write-Progress -ID 34572342 -Activity $MXActivityMessage -PercentComplete 100 -Completed RETURN $Results } $Results = @() ### Progress Bar Stuff $DomainCount = 0 $DomainCountTotal = $Domain.Count FOREACH ($Item in $Domain) { $ErrorCount = 0 ### Progress Bar Stuff $DomainActivityMessage = "Checking E-mail Health" $DomainStatusMessage = "Checking $($DomainCount+1) of $DomainCountTotal - $Item" $DomainProgressPercent = [math]::round(($DomainCount / $DomainCountTotal * 100),0) Write-Progress -ID 12551342 -Activity $DomainActivityMessage -Status $DomainStatusMessage -PercentComplete $DomainProgressPercent $DomainCount++ IF ($CheckBlacklist) { $DNSInfo = Get-DNSEMailInfo $Item -MainProgressBarOff -CheckBlacklist } ELSE { $DNSInfo = Get-DNSEMailInfo $Item -MainProgressBarOff } $RegistrationTimeSpan = (Get-Date) - $DNSInfo.FirstRegistrationDate ### First Registration Date IF ($DNSInfo.FirstRegistrationDate -ne 0) { IF ($RegistrationTimeSpan.TotalDays -lt 180) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Registration" ItemCheck = "Recently Registered" ItemResults = $True ItemDetails = $DNSInfo.FirstRegistrationDate Alert = "Error: Domain Registered Less Than 6 Months Ago" } $ErrorCount++ } ELSEIF ($RegistrationTimeSpan.TotalDays -lt 365) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Registration" ItemCheck = "Recently Registered" ItemResults = $True ItemDetails = $DNSInfo.FirstRegistrationDate Alert = "Warning: Domain Registered Less Than a Year Ago" } $ErrorCount++ } ELSEIF ($RegistrationTimeSpan.TotalDays -ge 365) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Registration" ItemCheck = "Recently Registered" ItemResults = $False ItemDetails = $DNSInfo.FirstRegistrationDate Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Registration" ItemCheck = "Recently Registered" ItemResults = "" ItemDetails = "" Alert = "Error: Unknown Registration Date" } $ErrorCount++ } } ### MX Record IF ($DNSInfo.MXRecordCount -ne 0) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "MX" ItemCheck = "MX Record Exists" ItemResults = $True ItemDetails = $DNSInfo.MXRecord Alert = "" } IF ($DNSInfo.DuplicateMXRecord -eq $False) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "MX" ItemCheck = "Duplicate MX Records" ItemResults = $DNSInfo.DuplicateMXRecord ItemDetails = $DNSInfo.MXRecord Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "MX" ItemCheck = "Duplicate MX Records" ItemResults = $DNSInfo.DuplicateMXRecord ItemDetails = $DNSInfo.MXRecord Alert = "Warning: Duplicate MX Record Found" } $ErrorCount++ } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "MX" ItemCheck = "MX Record Exists" ItemResults = $False ItemDetails = $DNSInfo.MXRecord Alert = "Error: Missing MX Record" } $ErrorCount++ } ### SPF Record IF ($DNSInfo.SPFRecordCount -eq 0) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Record Exists" ItemResults = $False ItemDetails = $DNSInfo.SPFRecord Alert = "Error: Missing SPF Record" } $ErrorCount++ } ELSEIF ($DNSInfo.SPFRecordCount -eq 1) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Record Exists" ItemResults = $True ItemDetails = $DNSInfo.SPFRecord Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Record Exists" ItemResults = $True ItemDetails = $DNSInfo.SPFRecord Alert = "Error: Multiple SPF Records Found" } $ErrorCount++ } IF ($DNSInfo.SPFRecordCount -ne 0) { ### SPF Policy Info IF ($DNSInfo.SPFPolicy -eq "Fail") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Fail" ItemDetails = "-All" Alert = "" } } ELSEIF ($DNSInfo.SPFPolicy -eq "Soft Fail") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Soft Fail" ItemDetails = "~All" Alert = "" } } ELSEIF ($DNSInfo.SPFPolicy -eq "Pass") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Soft Fail" ItemDetails = "+All" Alert = "Error: SPF Policy Set to Pass" } $ErrorCount++ } ELSEIF ($DNSInfo.SPFPolicy -eq "None") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Soft Fail" ItemDetails = "?All" Alert = "Error: No SPF Policy Set" } $ErrorCount++ } ELSEIF ($DNSInfo.SPFPolicy -eq "Redirected") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Redirect" ItemDetails = ((($DNSInfo.SPFRecord) -replace (" "," ")).Split(" ") | Where-Object { $_ -like "*redirect*"}) Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Policy" ItemResults = "Not Set" ItemDetails = "" Alert = "Error: SPF Policy Not Set" } $ErrorCount++ } ### SPF Lookup Info IF ($DNSInfo.SPFLookupCount -le 8 -and $DNSInfo.SPFPolicy -ne "Redirected") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Lookup Count" ItemResults = $DNSInfo.SPFLookupCount ItemDetails = $DNSInfo.SPFLookupFQDNs Alert = "" } } ELSEIF ($DNSInfo.SPFLookupCount -le 10 -and $DNSInfo.SPFPolicy -ne "Redirected") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Lookup Count" ItemResults = $DNSInfo.SPFLookupCount ItemDetails = $DNSInfo.SPFLookupFQDNs Alert = "Warning: High SPF Lookup Count" } $ErrorCount++ } ELSEIF ($DNSInfo.SPFPolicy -ne "Redirected") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Lookup Count" ItemResults = $DNSInfo.SPFLookupCount ItemDetails = $DNSInfo.SPFLookupFQDNs Alert = "Error: Too Many SPF Lookups" } $ErrorCount++ } ### SPF Syntax Errors IF ($DNSInfo.SPFSyntaxErrors.Count -gt 0) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Syntax" ItemResults = "$($DNSInfo.SPFSyntaxErrors.Count.ToString()) Errors" ItemDetails = $DNSInfo.SPFSyntaxErrors Alert = "Error: SPF Has Syntax Errors" } $ErrorCount++ } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "SPF" ItemCheck = "SPF Syntax" ItemResults = "No Issues Found" ItemDetails = $DNSInfo.SPFSyntaxErrors Alert = "" } } } ### DMARC Record Exists IF ($DNSInfo.DMARCRecordCount -eq 0) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Record Exists" ItemResults = $False ItemDetails = $DNSInfo.DMARCRecord Alert = "Error: Missing DMARC Record" } $ErrorCount++ } ELSEIF ($DNSInfo.DMARCRecordCount -eq 1) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Record Exists" ItemResults = $True ItemDetails = $DNSInfo.DMARCRecord Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Record Exists" ItemResults = $True ItemDetails = $DNSInfo.DMARCRecord Alert = "Error: Multiple DMARC Records Found" } $ErrorCount++ } ### DMARC Policy IF ($DNSInfo.DMARCRecordCount -ne 0) { IF ($DNSInfo.DMARCPolicy -eq "Monitoring") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Policy" ItemResults = "Monitoring" ItemDetails = "p=none" Alert = "Warning: DMARC Policy Set to Monitoring" } $ErrorCount++ } ELSEIF ($DNSInfo.DMARCPolicy -eq "Quarantine") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Policy" ItemResults = "Quarantine" ItemDetails = "p=quarantine" Alert = "" } } ELSEIF ($DNSInfo.DMARCPolicy -eq "Reject") { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Policy" ItemResults = "Reject" ItemDetails = "p=reject" Alert = "" } } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DMARC" ItemCheck = "DMARC Policy" ItemResults = "Unknown" ItemDetails = "" Alert = "Error: Unknown DMARC Policy" } $ErrorCount++ } } ### DKIM Record Exists IF ($DNSInfo.DKIMRecordCount -eq 0) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DKIM" ItemCheck = "DKIM Records Exists" ItemResults = $False ItemDetails = "" Alert = "Warning: Missing DKIM Record" } $ErrorCount++ } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "DKIM" ItemCheck = "DKIM Records Exists" ItemResults = $True ItemDetails = $DNSInfo.DKIMRecord Alert = "" } } ### Blacklist IF ($DNSInfo.HasBlacklist -eq $False) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Blacklist" ItemCheck = "Blacklist Entry Exists" ItemResults = $False ItemDetails = "" Alert = "" } } ELSEIF ($DNSInfo.BlacklistEntries.Count -gt 4) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Blacklist" ItemCheck = "Blacklist Entry Exists" ItemResults = $True ItemDetails = $DNSInfo.BlacklistEntries Alert = "Error: Several Blacklist Entries Found" } $ErrorCount++ } ELSE { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Blacklist" ItemCheck = "Blacklist Entry Exists" ItemResults = $True ItemDetails = $DNSInfo.BlacklistEntries Alert = "Warning: Blacklist Entries Found" } $ErrorCount++ } IF ($ErrorCount -eq 0 -and $IssuesOnly -eq $True) { $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Domain = $Item Item = "Health Check" ItemCheck = "Issues" ItemResults = $False ItemDetails = "No Issues Found" Alert = "" } } } IF ($IssuesOnly -eq $True) { $Results = $Results | Where-Object { ($_.Alert -ne "" -and $_.Alert -ne $null) -or $_.ItemDetails -eq "No Issues Found" } } RETURN $Results | Select Domain, Item, ItemCheck, ItemResults, Alert, ItemDetails | FT -GroupBy Domain | Out-String -Stream | ForEach-Object { $OutA = IF ($_ -match 'Warning') { @{ 'ForegroundColor' = 'Yellow' } } ELSEIF ($_ -match 'Category:') { @{ 'ForegroundColor' = 'White' } } ELSEIF ($_ -like '*----*') { @{ 'ForegroundColor' = 'White' } } ELSEIF ($_ -match 'AlertLevel') { @{ 'ForegroundColor' = 'White' } } ELSEIF ($_ -match 'Error') { @{ 'ForegroundColor' = 'Red' } } ELSEIF ($_ -match 'Critical') { @{ 'ForegroundColor' = 'Red' } } ELSE { @{ 'ForegroundColor' = 'White' } } Write-Host @OutA $_ } } |