Skip to content

Instantly share code, notes, and snippets.

@General-Gouda
Created August 2, 2019 13:59
Show Gist options
  • Select an option

  • Save General-Gouda/7b8ff076ce46e658f7dff84d6c6df72a to your computer and use it in GitHub Desktop.

Select an option

Save General-Gouda/7b8ff076ce46e658f7dff84d6c6df72a to your computer and use it in GitHub Desktop.
SPF Record Flattener
[CmdletBinding()]
param
(
[string]$DNSServer = "8.8.8.8",
[string]$DomainName = "domain.com",
[parameter(Mandatory=$true)]
[AllowNull()]
[AllowEmptyString()]
[AllowEmptyCollection()]
[string[]]$DomainsToFlatten,
[parameter(Mandatory=$true)]
[AllowNull()]
[AllowEmptyString()]
[AllowEmptyCollection()]
[string[]]$IPv4Addresses,
[parameter(Mandatory=$true)]
[AllowNull()]
[AllowEmptyString()]
[AllowEmptyCollection()]
[string[]]$IPv6Addresses,
[parameter(Mandatory=$true)]
[AllowNull()]
[AllowEmptyString()]
[AllowEmptyCollection()]
[string[]]$Includes
)
function Get-DomainSPFRecordIPAddresses {
[CmdletBinding()]
param
(
[string]$DomainName,
[string]$DNSServer
)
$ip_list = New-Object System.Collections.ArrayList
$domain_spf_record = Resolve-DnsName $DomainName -Type TXT -Server $DNSServer | Where-Object {$_.Strings -match "spf"} | Select-Object -ExpandProperty Strings
foreach ($entry in ($domain_spf_record -split " ")){
if ($entry -match "ip4|ip6")
{
$ip_list.Add($entry.replace("ip4:","").replace("ip6:","").trim()) | Out-Null
}
if ($entry -match "include")
{
$sub_lookup_domain_name = $entry.replace("include:","").trim()
$sub_list = Get-DomainSPFRecordIPAddresses -DomainName $sub_lookup_domain_name -DNSServer $DNSServer
$sub_list | ForEach-Object {
$ip_list.Add($_) | Out-Null
}
}
}
Return $ip_list | Select-Object -Unique
}
$spf_entries_list = New-Object System.Collections.ArrayList
0..4 | ForEach-Object {
$spf_record_init = New-Object System.Collections.ArrayList
$spf_record_init.Add("v=spf1 ") | Out-Null
if ($_ -eq 0)
{
$spf_record_init.Add("mx ") | Out-Null
if ($Includes)
{
foreach ($include in $Includes)
{
$spf_record_init.Add("include:$include ") | Out-Null
}
}
$spf_record_init.Add("include:netblocks1.$DomainName ") | Out-Null
$spf_record_init.Add("include:netblocks2.$DomainName ") | Out-Null
$spf_record_init.Add("include:netblocks3.$DomainName ") | Out-Null
$spf_record_init.Add("include:netblocks4.$DomainName ") | Out-Null
$spf_record_init.Add("-all") | Out-Null
}
$spf_entries_list.Add($spf_record_init) | Out-Null
}
$ip_list = New-Object System.Collections.ArrayList
$spf_record_builder = New-Object System.Collections.ArrayList
if ($DomainsToFlatten)
{
foreach ($domain_name in $DomainsToFlatten)
{
Get-DomainSPFRecordIPAddresses -DomainName $domain_name -DNSServer $DNSServer | ForEach-Object {
$ip_list.Add($_) | Out-Null
}
}
foreach ($ip in $ip_list)
{
if ($ip -match ":")
{
$spf_record_builder.Add("ip6:$ip ") | Out-Null
}
elseif ($ip -match ".")
{
$spf_record_builder.Add("ip4:$ip ") | Out-Null
}
}
}
if ($IPv4Addresses){
foreach ($ipv4 in $IPv4Addresses)
{
$spf_record_builder.Add("ip4:$ipv4 ") | Out-Null
}
}
if ($IPv6Addresses)
{
foreach ($ipv6 in $IPv6Addresses)
{
$spf_record_builder.Add("ip4:$ipv6 ") | Out-Null
}
}
$spf_record_builder = $spf_record_builder | Sort-Object
$counter = 1
foreach ($ip in $spf_record_builder)
{
$spf_length = [System.Text.Encoding]::ASCII.GetByteCount($spf_entries_list[$counter] -join "`n") + [System.Text.Encoding]::ASCII.GetByteCount($ip) + [System.Text.Encoding]::ASCII.GetByteCount("-all")
if ($spf_length -lt 476)
{
$spf_entries_list[$counter].Add($ip) | Out-Null
}
elseif ($spf_length -gt 476)
{
$spf_entries_list[$counter].Add("-all") | Out-Null
$counter++
}
$index = [array]::IndexOf($spf_record_builder, $ip)
if ($index -eq ($spf_record_builder.Count - 1))
{
$spf_entries_list[$counter].Add("-all") | Out-Null
}
}
$spf_entries_strings_list = New-Object System.Collections.ArrayList
foreach ($entry in $spf_entries_list)
{
$entry_length = ($entry -join "").Length
$entry_index = [array]::IndexOf($spf_entries_list, $entry)
$custom_object = [PSCustomObject]@{
DNSRecordName = $null
DNSRecordZoneName = $null
DNSEntryValue = $null
}
if ($entry_index -eq 0)
{
$custom_object.DNSRecordName = "@"
}
else
{
$custom_object.DNSRecordName = "netblocks$entry_index"
}
$custom_object.DNSRecordZoneName = $DomainName
if ($entry[$entry.Count - 1] -notmatch "-all")
{
$entry.Add("-all") | Out-Null
}
$entry.Add("") | Out-Null
$custom_object.DNSEntryValue = $entry #-join "`n"
$spf_entries_strings_list.Add($custom_object) | Out-Null
}
return $spf_entries_strings_list
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment