Skip to content

Instantly share code, notes, and snippets.

@jschlackman
Last active March 20, 2025 15:16
Show Gist options
  • Save jschlackman/6c192601bf47abc2af5fa9c6a33af1a4 to your computer and use it in GitHub Desktop.
Save jschlackman/6c192601bf47abc2af5fa9c6a33af1a4 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Retrieves an audit of MX, SPF, and DMARC records from public DNS for a given list of domains.
.DESCRIPTION
Author: James Schlackman
Last Modified: March 20 2025
.PARAMETER DomainPath
Pathname to CSV file with list of domains to check.
.PARAMETER DomainNameField
Column name in CSV file that identifies the domain names to check.
.PARAMETER OutputPath
Export file pathname.
#>
Param(
[Parameter(Mandatory)] [String]$ImportPath,
[Parameter()] [String] $DomainNameField,
[Parameter()] [ValidateNotNullorEmpty()] [String] $OutputPath = ('{0:yyMMdd} Domain Mail DNS Records.csv' -f (Get-Date))
)
# Attempt to load list of domains
If (Test-Path $ImportPath -ErrorAction SilentlyContinue) {
$domainList = Import-Csv -Path $ImportPath
# Get list of valid potential domain name fields
$fields = (@($domainList)[0] | Get-Member -MemberType NoteProperty) | Select Name, @{Name='Sample data';Expression={($_.Definition -split '=')[1]}} | Where-Object {$_.'Sample data'}
# Select domain name field if not specified
If (!$DomainNameField) {
$DomainNameField = ($fields | Out-GridView -Title 'Select import field to identify domain' -OutputMode Single).Name
Write-Host ('Import file domain name field: {0}' -f $DomainNameField)
} Else {
If ($fields.Name -notcontains $DomainNameField) {
Write-Error 'Specified domain name field not found in import file, or field data empty.'
Exit
}
}
}
# Report number loaded
Write-Host ('Domains to check: {0}' -f $domainList.Count)
# Now check them
If ($domainList) {
Write-Host 'Retrieving MX, SPF, and DMARC records...'
$auditOutput = foreach ($domainName in $domainList.$DomainNameField) {
Write-Debug $domainName
$soa = Resolve-DnsName -Type SOA -Name $domainName -ErrorAction SilentlyContinue
If ($soa) {
[PSCustomObject]@{
Name = $domainName
PrimaryServer = $soa.PrimaryServer
NameAdministrator = $soa.NameAdministrator
DMARC = (Resolve-DnsName -Type TXT -Name ('_dmarc.{0}' -f $domainName) -ErrorAction SilentlyContinue) | Where-Object {$_.Strings -ne $null} | Select -ExpandProperty Strings
MX = ((Resolve-DnsName -Type MX -Name $domainName -ErrorAction SilentlyContinue).NameExchange -join ', ')
SPF = ((Resolve-DnsName -Type TXT -Name $domainName -ErrorAction SilentlyContinue) |
Where-Object {$_.Strings -Match 'v=spf1'} |
Select -ExpandProperty Strings) -join ''
}
} Else {
[PSCustomObject]@{
Name = $domainName
PrimaryServer = 'Not found'
}
}
}
Write-Host 'Done.'
$exportOutput = $auditOutput | Out-GridView -OutputMode Multiple -Title 'Select records for export'
# If at least 1 record was selected for export
If ($exportOutput) {
Write-Host 'Exporting to ' -NoNewline
Write-Host $OutputPath -ForegroundColor Green
$exportOutput | Export-Csv -NoTypeInformation -Path ($OutputPath) -Encoding UTF8
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment