Last active
April 20, 2025 03:18
-
-
Save contactbrenton/0adaf8baa0c20c5c2d1623e2246249e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
This script manages DNS records for specified domains on Cloudflare. | |
.DESCRIPTION | |
The script performs the following tasks: | |
- Retrieves the Zone ID for each domain using Cloudflare’s API. | |
- Deletes all existing DNS records for each domain. | |
- Adds a predefined set of DNS records (A, TXT, and DKIM) to each domain. | |
It is primarily intended for initial domain setup or reconfiguration. | |
.WARNINGS | |
- This script will irreversibly delete *all* existing DNS records for the listed domains. | |
- Ensure you have a full backup or export of DNS settings before running this script. | |
- Double-check the `$apiToken` and domain list to avoid accidental changes. | |
- Run in a safe environment (e.g., test domain) before using in production. | |
.NOTES | |
- Ensure your API token has permissions to manage DNS records. | |
- If a domain has a large number of DNS records, Cloudflare API rate limits may apply. | |
.CREDIT | |
Script authored with substantial contribution and development by Brendan Matheson. | |
#> | |
# Variables | |
$apiToken = "placeholder" | |
$domains = @("domain1.com", "domain2.com") | |
$dnsRecords = @( | |
@{ type = "A"; name = "@"; content = "8.8.8.8" }, | |
@{ type = "A"; name = "www"; content = "8.8.8.8" }, | |
@{ type = "TXT"; name = "@"; content = "v=spf1 -all" }, | |
@{ type = "TXT"; name = "_dmarc"; content = "v=DMARC1; p=reject; pct=100;" }, | |
@{ type = "TXT"; name = "*._domainkey"; content = "v=DKIM1; p=" } | |
) | |
# Headers | |
$headers = @{ "Authorization" = "Bearer $apiToken"; "Content-Type" = "application/json" } | |
# Get Zone ID | |
function Get-ZoneID ($domain) { | |
(Invoke-RestMethod -Uri "https://api.cloudflare.com/client/v4/zones?name=$domain" -Headers $headers).result[0].id | |
} | |
# Remove Existing DNS Records | |
function Remove-AllDNSRecords ($zoneID) { | |
$dnsRecords = (Invoke-RestMethod -Uri "https://api.cloudflare.com/client/v4/zones/$zoneID/dns_records" -Headers $headers).result | |
foreach ($record in $dnsRecords) { | |
Invoke-RestMethod -Method DELETE -Uri "https://api.cloudflare.com/client/v4/zones/$zoneID/dns_records/$($record.id)" -Headers $headers | Out-Null | |
Write-Host "Removed $($record.type) record for $($record.name)" | |
} | |
} | |
# Add DNS Records | |
foreach ($domain in $domains) { | |
$zoneID = Get-ZoneID $domain | |
if ($zoneID) { | |
# Remove all existing DNS records first | |
Remove-AllDNSRecords $zoneID | |
# Add new DNS records | |
foreach ($record in $dnsRecords) { | |
$recordName = if ($record.name -eq "@") { $domain } else { "$($record.name).$domain" } | |
$proxied = if ($record.type -eq "A") { $true } else { $false } | |
Invoke-RestMethod -Method POST -Uri "https://api.cloudflare.com/client/v4/zones/$zoneID/dns_records" ` | |
-Headers $headers ` | |
-Body (@{ | |
type = $record.type | |
name = $recordName | |
content = $record.content | |
ttl = 3600 | |
proxied = $proxied | |
} | ConvertTo-Json -Depth 2) | Out-Null | |
Write-Host "Added $($record.type) record for $recordName" | |
} | |
} else { | |
Write-Host "Failed to retrieve Zone ID for $domain" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment