Dynamic DNS

Want to host something on premise but don't have a static IP address? This can be a bane of sorts. Some ISP's offer their subscribers a static IP as standard, others charge extra for one, while others simply don't offer it at all.

Moving from ADSL2 to NBN some years back, I wasn't able to retain a static IP. While considering Dynamic DNS (DDNS) options, you either have to pay for a custom domain or accept a sub-domain from a provider. 

Quite persistent I could leverage off Azure DNS and some PowerShell scripting, I cobbled together the script below which runs on Windows as a scheduled task every two minutes.
With a bit of tweaking, I even managed to port this onto Debian Linux using pwsh as a crontab task. This script uses the new Az modules, which is recommended as Microsoft are actively maintaining this new module series.

Azure DNS is quite cheap, costing under $9 AUD per year for up to 25 hosted DNS zones, which includes a million queries a month for only $0.55 AUD.

Some DNS registrars provide basic DNS zone management including A and CNAME records, but charge a premium if you need different types of records like MX, NS, SRV, TXT and PTR records. Also, they don't generally have a way to automate zone management unless you are planning to use AWS' route53 DNS.
Azure DNS allows you to create these records as standard and you can automate zone management all though PowerShell and CLI

To use this script, you will need an account with the DNS Zone Contributor role or greater and needs Multifactor Authentication (MFA) disabled.

Important: I would strongly recommend limiting the privileges of this account to just the DNS Zone Contributor role and to use Role Based Access Control (RBAC) at the resource level to limit this account to only modify the desired DNS zone.
Because you cannot use MFA, I would also advise to use an ambiguous account name and lengthy password. Furthermore, do not leave the password as plain text and encrypt it.


$Destination = "1.1.1.1"
#Check that the system is online, otherwise it quits
$Ping = Test-Connection -ComputerName $Destination -Count 1 -Quiet
If ($Ping -eq $false)
{
Write-Host "You're offline"
Exit
}
Else
{
$CurrentIP = Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
$DNSRecord = Resolve-DnsName -Name "server1.magrin.one" -Server "ns1-01.azure-dns.com"
$DNSRecord = $DNSRecord.IPAddress
}
If ($CurrentIP -Contains "$DNSRecord")
{
Write-Host "No change needed"
Exit
}
Else 
{Write-Host "Update DNS"
$AccountName ="MyAzureAccount@magrin.one"
$Password = ConvertTo-SecureString "blablablablablabla" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($AccountName, $Password)
Login-AzAccount -Credential $Credential
#Update 'server1.magrin.one' A record to the current public IP
$UpdateRecord = Get-AzDnsRecordSet -name "server1" -RecordType A -ZoneName "magrin.one" -ResourceGroupName DNS
$UpdateRecord.Records[0].Ipv4Address = $CurrentIP
Set-AzDnsRecordSet -RecordSet $UpdateRecord
Disconnect-AzAccount -Username $AccountName
}