同版本AD模块下Get-ADGroup的ProtectedFromAccidentalDeletion为何在Server2019报空引用错误
问题原因
该问题的根因是PowerShell版本对.NET Framework兼容层的实现差异:
- RSAT自带的ActiveDirectory 1.0.1.0模块是基于.NET Framework开发的传统Windows组件,并非原生适配.NET Core的跨平台模块。
- Windows 10上运行的PowerShell 7使用.NET Core 3.1及以上版本的兼容层,对.NET Framework API的空值处理逻辑做了修复,解析
ProtectedFromAccidentalDeletion属性时不会触发异常。这个属性不是AD对象的原生存储属性,是模块动态读取对象ACL的访问规则保护状态后生成的衍生属性。 - Windows Server 2019上的PowerShell 6使用.NET Core 2.x版本的兼容层,解析ACL时如果碰到无效ACE(比如SID无法解析的孤立条目、空安全描述符),没有做空值校验,就会抛出
NullReferenceException。
修复方案
- 方案1:升级PowerShell版本
直接将Server 2019上的PowerShell 6升级到PowerShell 7或更高版本,无需重新安装RSAT AD组件,升级后直接运行原有脚本即可解决兼容问题,是最彻底的修复方案。 - 方案2:明确指定查询属性,避免触发异常属性解析
不要使用-Properties *这种全量拉取属性的写法,你原有脚本只需要4个属性,其中DistinguishedName、CN、GroupCategory是Get-ADGroup默认返回的属性,仅需额外指定非默认的Description即可,修改后的命令如下:
该写法不会触发$ADGroupsList = @(Get-ADGroup -Filter * -Properties Description | Select-Object DistinguishedName,CN,GroupCategory,Description | Sort-Object CN)ProtectedFromAccidentalDeletion属性的解析逻辑,完全规避报错。 - 方案3:若必须使用
ProtectedFromAccidentalDeletion属性且无法升级PowerShell
改用ADSI接口直接读取ACL状态,替代模块的内置属性解析,示例代码如下:$group = Get-ADGroup -Identity ACC_Admin $adsiObj = [adsi]"LDAP://$($group.DistinguishedName)" $ProtectedFromAccidentalDeletion = $adsiObj.PSBase.ObjectSecurity.AreAccessRulesProtected
内容的提问来源于stack exchange,提问作者TylerH
相关产品推荐
相关产品推荐

