Last active
October 15, 2020 11:23
-
-
Save Shonke/0d332e5fda0a57aef9b0b356187b87d5 to your computer and use it in GitHub Desktop.
cloudflareDDNS-PowerShell
This file contains 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
Param( | |
[Parameter(Mandatory = $true)] [string] $Token, | |
[Parameter(Mandatory = $true)] [string] $Zone, | |
[Parameter(Mandatory = $false)] [string] $RecordNameV4, | |
[Parameter(Mandatory = $false)] [string] $RecordNameV6 | |
) | |
# add Scheduled Task | |
# At computer startup | |
# Every 2 hours | |
# When connecting to the network | |
# Program/script: | |
# C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& 'C:\srv\ddns_cf.ps1' -Token 9U.... -Zone 019... -RecordNameV4 xxx.xxx.com -RecordNameV6 xxx.xxx.com" | |
# TTL in seconds (1=auto) | |
$RECORD_TTL="1" | |
$DATE=Get-Date -Format g | |
$CF_URI = 'https://api.cloudflare.com/client/v4/zones' | |
$CF_HEADER = @{"Content-Type" = "application/json"; "Authorization" = "Bearer $Token"} | |
# [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
function Write-Log { | |
Param ($Text) | |
Write-Host ($DATE + ", " + $Text) | |
} | |
function Get-CF-Record { | |
Param ( | |
[Parameter(Mandatory = $true)] [string] $RecordType, | |
[Parameter(Mandatory = $true)] [string] $RecordName | |
) | |
$Uri = "${CF_URI}/${Zone}/dns_records?name=${RecordName}&type=${RecordType}" | |
try { | |
$Response = Invoke-RestMethod -Uri $Uri -Headers $CF_HEADER | |
return $Response.result | |
} catch { | |
$Message = "ERROR on " + $RecordName + " Response: " + $_ | |
Write-Log $Message | |
} | |
} | |
function Invoke-CF-Record { | |
Param ( | |
[Parameter(Mandatory = $true)] [string] $Zone, | |
[Parameter(Mandatory = $true)] [string] $RecordName, | |
[Parameter(Mandatory = $true)] [string] $RecordType, | |
[Parameter(Mandatory = $false)] [string] $RecordId, | |
[Parameter(Mandatory = $true)] [string] $IP | |
) | |
$Uri = "${CF_URI}/${Zone}/dns_records" | |
$Method = "POST" | |
if ($RecordId) { | |
$Uri = "${CF_URI}/${Zone}/dns_records/${RecordId}" | |
$Method = "PUT" | |
} | |
$Body = @{"id" = $Zone; "type" = $RecordType; "name" = $RecordName; "content" = $IP; "ttl" = $RECORD_TTL; "proxied" = $FALSE} | ConvertTo-Json | |
try { | |
$Response = Invoke-RestMethod -Method $Method -Uri $Uri -Headers $CF_HEADER -Body $Body | |
} catch { | |
$Message = "ERROR on " + $RecordName + " Response: " + $_ | |
Write-Log $Message | |
} | |
} | |
function Invoke-CF-IP { | |
Param ( | |
[Parameter(Mandatory = $true)] [string] $Zone, | |
[Parameter(Mandatory = $true)] [string] $RecordType, | |
[Parameter(Mandatory = $true)] [string] $RecordName, | |
[Parameter(Mandatory = $true)] [string] $IP | |
) | |
$record = Get-CF-Record -RecordType A -RecordName $RecordName | |
if ($record) { | |
if (-Not ($IP -eq $record.content)) { | |
try { | |
Invoke-CF-Record -Zone $Zone -RecordName $RecordName -RecordType $RecordType -RecordId $record.id -IP $IP | |
} catch { | |
Write-Log "Update Record ${RecordType} fail" | |
} | |
} | |
} else { | |
try { | |
Invoke-CF-Record -Zone $Zone -RecordName $RecordName -RecordType $RecordType -IP $IP | |
} catch { | |
Write-Log "Update Record ${RecordType} fail" | |
} | |
} | |
} | |
function Get-Public-IP { | |
Write-Log "Check IP Address" | |
$linkIpList = Get-NetIPAddress -AddressState Preferred -PrefixOrigin Dhcp,RouterAdvertisement | |
$linkIpv4List = $linkIpList |? -m AddressFamily IPv4 | |
$linkIpv6List = $linkIpList |? -m AddressFamily IPv6 |? -m SuffixOrigin Link | |
if ($linkIpv4List) { $linkIpv4 = $linkIpv4List.IPAddress } | |
if ($linkIpv6List) { $linkIpv6 = $linkIpv6List.IPAddress } | |
Write-Log ("Device Link IPv4 Address: " + $linkIpv4) | |
Write-Log ("Device Link IPv6 Address: " + $linkIpv6) | |
try { | |
$ip = Invoke-RestMethod "https://api.ipify.org" | |
$publicIpv4 = $ip.Trim() | |
Write-Log ("Device Public IPv4 Address: " + $publicIpv4) | |
} catch { | |
Write-Log "Get Public Ipv4 fail" | |
} | |
return { "v4" = $publicIpv4; "v6" = $linkIpv6 } | |
} | |
$ip = Get-Public-IP | |
# update | |
if ($RecordNameV4) { Invoke-CF-IP -Zone $Zone -RecordType A -RecordName $RecordNameV4 -IP $ip.v4 } | |
if ($RecordNameV6) { Invoke-CF-IP -Zone $Zone -RecordType AAAA -RecordName $RecordNameV6 -IP $ip.v6 } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment