DomainHealthChecker.psm1
<#>
HelpInfoURI 'https://github.com/T13nn3s/Show-SpfDkimDmarc/blob/main/README.md' #> function Show-SpfDkimDmarc { [CmdletBinding()] param ( # Specifies the domain for resolving the SPF, DKIM and DMARC-record. [Parameter( Mandatory, ParameterSetName = 'domain', ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "Specifies the domain for resolving the SPF, DKIM and DMARC-record.", Position = 1)] [string]$Name, # Show SPF, DKIM and DMARC-records from multiple domains from a file. [Parameter( Mandatory, ParameterSetName = 'file', ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, HelpMessage = "Show SPF, DKIM and DMARC-records from multiple domains from a file.", Position = 2)] [System.IO.FileInfo]$File, # Custom DKIM Selector [Parameter(Mandatory = $False, HelpMessage = "Specify a custom DKIM selector.", Position = 3)] [string]$DkimSelector, # DNS Server to use [Parameter(Mandatory = $false, HelpMessage = "DNS Server to use.", Position = 4)] [string]$Server ) begin { class SpfDkimDmarc { [string]$Name [string]$SPFRecord [string]$SpfAdvisory [string]$DmarcRecord [string]$DmarcAdvisory [string]$DkimSelector [string]$DkimRecord [string]$DkimAdvisory # Constructor: Created the object with the SPF, DMARC and DKIM values SpfDkimDmarc ( [string]$d, [string]$SPF, [string]$SpfAdvisory, [string]$DMARC, [string]$DmarcAdvisory, [string]$DkimSelector, [string]$DKIM, [string]$DkimAdvisory ) { $this.Name = $d $this.SPFRecord = $SPF $this.SpfAdvisory = $SpfAdvisory $this.DmarcRecord = $DMARC $this.DmarcAdvisory = $DmarcAdvisory $this.DkimSelector = $DkimSelector $this.DkimRecord = $DKIM $this.DkimAdvisory = $DkimAdvisory } } if ($PSBoundParameters.ContainsKey('Server')) { $SplatParameters = @{ 'Server' = $Server 'ErrorAction' = 'SilentlyContinue' } } Else { $SplatParameters = @{ 'ErrorAction' = 'SilentlyContinue' } } # Custom list of DKIM-selectors # https://help.sendmarc.com/support/solutions/articles/44001891845-email-provider-commonly-used-dkim-selectors $DkimSelectors = @( 'selector1' # Microsoft 'google', # Google 'everlytic', # Everlytic 'k1', # Mailchimp / Mandrill 'mxvault' # Global Micro 'dkim' # Hetzner ) } process { if ($file) { if (-not(Test-Path $file)) { Write-error "$($file) does not exist" return } } function StartDomainHealthCheck($domain) { # Check SPF-record $SPF = $null $SPF = Resolve-DnsName -Name $Domain -Type TXT @SplatParameters | where-object { $_.strings -match "v=spf1" } | Select-Object -ExpandProperty strings -ErrorAction SilentlyContinue if ($SPF -eq $null) { $SpfAdvisory = "Domain does not have an SPF record. To prevent abuse of this domain, please add an SPF record to it." } if ($SPF -is [array]) { $SpfAdvisory = "Domain has more than one SPF-record. One SPF record for one domain. This is explicitly defined in RFC4408" } Else { switch -Regex ($SPF) { '~all' { $SpfAdvisory = "An SPF-record is configured but the policy is not sufficiently strict." } '-all' { $SpfAdvisory = "An SPF-record is configured and the policy is sufficiently strict." } "\?all" { $SpfAdvisory = "Your domain has a valid SPF record but your policy is not effective enough." } '\+all' { $SpfAdvisory = "Your domain has a valid SPF record but your policy is not effective enough." } Default { $SpfAdvisory = "No qualifier found. Your domain has a SPF record but your policy is not effective enough." } } } # Check DKIM-record $DKIM = $null if ($DkimSelector) { $DKIM = Resolve-DnsName -Type TXT -Name "$($DkimSelector)._domainkey.$($Domain)" @SplatParameters | Select-Object -ExpandProperty Strings -ErrorAction SilentlyContinue if ($DKIM -eq $null) { $DkimAdvisory = "No DKIM-record found for selector $($DkimSelector)._domainkey." } elseif ($DKIM -match "v=DKIM1" -or $DKIM -match "k=") { $DkimAdvisory = "DKIM-record found." } } else { foreach ($DkimSelector in $DkimSelectors) { $DKIM = Resolve-DnsName -Type TXT -Name "$($DkimSelector)._domainkey.$($Domain)" @SplatParameters | Select-Object -ExpandProperty strings -ErrorAction SilentlyContinue if ($DKIM -eq $null) { $DkimAdvisory = "We couldn't find a DKIM record associated with your domain." } elseif ($DKIM -match "v=DKIM1" -or $DKIM -match "k=") { $DkimAdvisory = "DKIM-record found." break } } } # Check DMARC-record $DMARC = $null $DMARC = Resolve-DnsName -type TXT -name _dmarc.$Domain @SplatParameters | Select-Object -ExpandProperty strings -ErrorAction SilentlyContinue if ($DMARC -eq $null) { $DmarcAdvisory = "Does not have a DMARC record. This domain is at risk to being abused by phishers and spammers." } Else { switch -Regex ($DMARC) { ('p=none') { $DmarcAdvisory = "Domain has a valid DMARC record but the DMARC (subdomain) policy does not prevent abuse of your domain by phishers and spammers." } ('p=quarantine') { $DmarcAdvisory = "Domain has a DMARC record and it is set to p=quarantine. To fully take advantage of DMARC, the policy should be set to p=reject." } ('p=reject') { $DmarcAdvisory = "Domain has a DMARC record and your DMARC policy will prevent abuse of your domain by phishers and spammers." } } } $ReturnValues = [SpfDkimDmarc]::New($Domain, $SPF, $SpfAdvisory, $DMARC, $DmarcAdvisory, $DkimSelector, $DKIM, $DkimAdvisory) $ReturnValues } if ($file) { foreach ($Domain in (Get-Content -Path $file)) { StartDomainHealthCheck -Domain $Domain } } if ($Name) { StartDomainHealthCheck -Domain $Name } } end {} } |