如何通过PowerShell获取与DNS控制台一致的区域安全权限信息?
解决思路:获取DNS控制台「DNS安全」选项卡完整权限信息
你的脚本仅从AD对象读取ACL,只能覆盖AD集成式DNS区域的AD层面权限,但DNS安全选项卡的内容包含三类权限,需针对性处理:
问题根源
- 非AD集成的DNS区域(如标准主要/辅助区域)存储在本地文件而非AD中,脚本未处理这类区域
- AD集成区域的DNS特定权限(如「添加记录」「删除记录」)需将AD ACL的
ActiveDirectoryRights枚举值映射为控制台显示的友好名称,而非直接输出原始枚举值 - 脚本未包含DNS服务器本身的安全权限(控制台中服务器节点的「DNS安全」选项卡)
分步解决方法
1. 区分DNS区域类型,针对性读取ACL
通过Get-DnsServerZone的IsDsIntegrated属性判断区域类型:
- AD集成区域:继续从AD对象读取ACL,同时映射权限名称
- 非AD集成区域:读取区域文件的ACL(默认路径
C:\Windows\System32\dns\<ZoneName>.dns,可通过Get-DnsServerZone -Name $zone.ZoneName | Select-Object ZoneFile获取实际路径)
2. 映射AD集成区域权限到DNS友好名称
AD ACL的ActiveDirectoryRights枚举值与DNS控制台权限对应关系如下,可通过哈希表转换:
$dnsPermissionMap = @{ "CreateChild" = "添加记录" "DeleteChild" = "删除记录" "WriteProperty" = "修改记录" "ReadProperty" = "读取记录" "FullControl" = "完全控制" "GenericRead" = "读取" "GenericWrite" = "写入" }
3. 读取DNS服务器本身的安全权限
通过Get-DnsServer的SecurityDescriptor属性解析服务器级权限:
$serverSD = (Get-DnsServer -ComputerName $serverName).SecurityDescriptor $serverACL = New-Object System.Security.AccessControl.DirectorySecurity $serverACL.SetSecurityDescriptorBinaryForm($serverSD)
修改后的完整脚本示例
$serverName = "你的DNS服务器名称" $aclList = @() $dnsPermissionMap = @{ "CreateChild" = "添加记录" "DeleteChild" = "删除记录" "WriteProperty" = "修改记录" "ReadProperty" = "读取记录" "FullControl" = "完全控制" "GenericRead" = "读取" "GenericWrite" = "写入" } # 获取所有DNS区域 $zones = Get-DnsServerZone -ComputerName $serverName foreach ($zone in $zones) { if ($zone.IsDsIntegrated) { # 处理AD集成区域 $zoneDN = "DC=$($zone.ZoneName.Replace('.', ',DC='))" Write-Host "处理AD集成区域: $zoneDN" $acl = Get-Acl "AD:$zoneDN" -ErrorAction SilentlyContinue if ($acl) { foreach ($access in $acl.Access) { $dnsPermission = $dnsPermissionMap[$access.ActiveDirectoryRights.ToString()] ?? $access.ActiveDirectoryRights.ToString() $aclList += [PSCustomObject]@{ ServerName = $serverName ZoneName = $zone.ZoneName Type = "AD集成区域" Identity = $access.IdentityReference AccessControlType = $access.AccessControlType DNSPermission = $dnsPermission InheritanceType = $access.InheritanceType IsInherited = $access.IsInherited } } } } else { # 处理非AD集成区域(文件存储) $zoneFilePath = $zone.ZoneFile Write-Host "处理非AD集成区域文件: $zoneFilePath" if (Test-Path $zoneFilePath) { $acl = Get-Acl $zoneFilePath -ErrorAction SilentlyContinue if ($acl) { foreach ($access in $acl.Access) { $aclList += [PSCustomObject]@{ ServerName = $serverName ZoneName = $zone.ZoneName Type = "非AD集成区域" Identity = $access.IdentityReference AccessControlType = $access.AccessControlType FileSystemRights = $access.FileSystemRights InheritanceFlags = $access.InheritanceFlags PropagationFlags = $access.PropagationFlags IsInherited = $access.IsInherited } } } } else { Write-Host "未找到区域文件: $zoneFilePath" } } } # 获取DNS服务器本身的安全权限 Write-Host "处理DNS服务器本身权限" $serverSD = (Get-DnsServer -ComputerName $serverName).SecurityDescriptor if ($serverSD) { $serverACL = New-Object System.Security.AccessControl.DirectorySecurity $serverACL.SetSecurityDescriptorBinaryForm($serverSD) foreach ($access in $serverACL.Access) { $dnsPermission = $dnsPermissionMap[$access.ActiveDirectoryRights.ToString()] ?? $access.ActiveDirectoryRights.ToString() $aclList += [PSCustomObject]@{ ServerName = $serverName ZoneName = "DNS服务器本身" Type = "服务器级权限" Identity = $access.IdentityReference AccessControlType = $access.AccessControlType DNSPermission = $dnsPermission InheritanceType = $access.InheritanceType IsInherited = $access.IsInherited } } } # 输出结果 $aclList | Format-Table -AutoSize
额外注意事项
- 运行脚本需具备DNS服务器的管理员权限(或对应ACL的读取权限)
- 部分特殊区域(如自动创建的反向查找区域)可能需要额外适配处理
内容的提问来源于stack exchange,提问作者wellyhartanto
相关产品推荐
相关产品推荐

