如何通过PowerShell Runbook自动备份Azure DNS区域至存储账户
问题:Azure DNS区域自动备份至存储账户的PowerShell Runbook实现
我尝试通过Azure自动化账户,将Azure DNS区域自动备份至Azure存储账户,希望创建一个PowerShell Runbook,获取所有DNS区域并导出区域文件后上传至存储账户。
现有代码如下:
#Authentication Connect-AzAccount Set-AzContext -Subscription mysubscriptiom #Variables $storageAccountName = "dnszonesbackup" $storageAccountKey = "key" $containerName = "dns-backups" #Logic $context = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey $zones = Get-AzDnsZone foreach ($zone in $zones) { $zoneFile = "Here i am stuck, How to export a zone files of DNS Zones and pass into blob storage" $blobName = $zone.Name + ".zone" Set-AzStorageBlobContent -Context $context -Container $containerName -File $zoneFile -Blob $blobName }
但我尝试导出区域文件时,找不到对应的导出Cmdlet,请问是否有可行的实现方法?
解决方案
Azure PowerShell确实没有直接导出DNS区域文件的Cmdlet,但可以手动生成符合RFC 1035标准的区域文件内容,再上传至存储账户。以下是完整的实现方案:
1. 核心思路
- 遍历目标订阅下的所有DNS区域
- 读取每个区域的SOA、NS及各类资源记录,拼接成标准DNS区域文件格式的内容
- 将生成的内容写入临时文件,再上传至存储账户Blob容器
- 推荐使用Azure自动化账户的托管身份认证,替代硬编码密钥,提升安全性
2. 完整Runbook代码
# 系统托管身份认证(自动化账户需先启用系统托管身份) Connect-AzAccount -Identity # 切换到目标订阅 Set-AzContext -Subscription "mysubscription" # 变量定义 $storageAccountName = "dnszonesbackup" $containerName = "dns-backups" $storageResourceGroup = "your-storage-rg-name" # 存储账户所在资源组 # 获取存储账户上下文(无需硬编码密钥) $storageAccount = Get-AzStorageAccount -Name $storageAccountName -ResourceGroupName $storageResourceGroup $context = $storageAccount.Context # 获取所有DNS区域 $zones = Get-AzDnsZone foreach ($zone in $zones) { # 获取当前区域的所有记录集 $recordSets = Get-AzDnsRecordSet -ZoneName $zone.Name -ResourceGroupName $zone.ResourceGroupName # 初始化区域文件内容,先写入SOA记录 $zoneContent = "@ IN SOA " + $zone.NameServers[0] + " " + $zone.SOA.Email.Replace("@", ".") + " (" + ` $zone.SOA.SerialNumber + " " + ` $zone.SOA.RefreshTime + " " + ` $zone.SOA.RetryTime + " " + ` $zone.SOA.ExpireTime + " " + ` $zone.SOA.Ttl + ")" + "`n`n" # 写入NS记录 $zoneContent += "@ IN NS " + $zone.NameServers[0] + "`n" foreach ($ns in $zone.NameServers[1..($zone.NameServers.Count-1)]) { $zoneContent += "@ IN NS " + $ns + "`n" } $zoneContent += "`n" # 遍历记录集,写入各类资源记录(跳过已手动写入的SOA、NS) foreach ($rs in $recordSets) { if ($rs.RecordType -eq "SOA" -or $rs.RecordType -eq "NS") { continue } $recordName = if ($rs.Name -eq "@") { "" } else { $rs.Name + "." + $zone.Name } $ttl = $rs.Ttl switch ($rs.RecordType) { "A" { foreach ($record in $rs.Records) { $zoneContent += "$recordName IN A $($record.Ipv4Address)`n" } } "AAAA" { foreach ($record in $rs.Records) { $zoneContent += "$recordName IN AAAA $($record.Ipv6Address)`n" } } "CNAME" { foreach ($record in $rs.Records) { $zoneContent += "$recordName IN CNAME $($record.Cname)`n" } } "MX" { foreach ($record in $rs.Records) { $zoneContent += "$recordName IN MX $($record.Preference) $($record.Exchange)`n" } } "TXT" { foreach ($record in $rs.Records) { $zoneContent += "$recordName IN TXT `"$($record.Value)`"`n" } } # 可按需扩展SRV、PTR等其他记录类型 } } # 写入临时文件(自动化账户临时路径为$env:TEMP) $tempFilePath = Join-Path -Path $env:TEMP -ChildPath "$($zone.Name).zone" $zoneContent | Out-File -Path $tempFilePath -Encoding UTF8 # 上传至Blob存储 Set-AzStorageBlobContent -Context $context -Container $containerName -File $tempFilePath -Blob "$($zone.Name).zone" -Force # 清理临时文件 Remove-Item -Path $tempFilePath -Force }
3. 权限配置
- 为自动化账户的系统托管身份分配:
- DNS区域所在资源组的DNS区域读取者角色
- 存储账户的存储Blob数据贡献者角色
内容的提问来源于stack exchange,提问作者Nish
相关产品推荐
相关产品推荐

