清除AD countryCode属性抛出DirectoryServicesCOMException(8311)问题排查
问题成因
- 抛出
WILL_NOT_PERFORM(错误码8311)的根因:countryCode是AD Schema定义的强联动属性,与c(ISO 3166双字母国家代码)、co(国家全称)三个属性存在强制一致性校验规则,不允许单独修改、清空其中任意一个属性。仅调用Clear()方法清空countryCode时,AD目录服务校验发现另外两个关联属性仍保留原有值,判定对象属性状态不合法,会直接拒绝执行操作。 - 抛出
DISP_E_UNKNOWNNAME(错误码0x80020006)的根因:DirectoryEntry.Invoke方法用于调用ADSI COM对象的原生接口方法,IADs接口本身不存在名为Remove/remove的方法,传入不存在的方法名会直接触发未知名称异常。
正确清除countryCode属性的方案
要清空countryCode属性,必须同步清空和它绑定的c、co两个关联属性,不能单独操作单个属性。操作时需要通过ADSI原生的PutEx方法传入清空属性的操作标记,直接调用Properties[xxx].Clear()不会触发AD对联动属性的一致性校验逻辑,依然会触发操作拒绝错误。
具体实现代码如下:
// ADSI属性操作常量:标记操作为清空指定属性值 private const int ADS_PROPERTY_CLEAR = 1; // 国家属性组三个强关联属性名 private const string ATTR_COUNTRY_CODE = "countryCode"; private const string ATTR_COUNTRY_ABBR = "c"; private const string ATTR_COUNTRY_NAME = "co"; // 核心清除逻辑 using (DirectoryEntry dEntry = /* 替换为你的目标AD对象绑定代码 */) { // 对三个关联属性同步执行清空操作 dEntry.Invoke("PutEx", new object[] { ADS_PROPERTY_CLEAR, ATTR_COUNTRY_CODE, 0 }); dEntry.Invoke("PutEx", new object[] { ADS_PROPERTY_CLEAR, ATTR_COUNTRY_ABBR, 0 }); dEntry.Invoke("PutEx", new object[] { ADS_PROPERTY_CLEAR, ATTR_COUNTRY_NAME, 0 }); // 一次性提交所有变更 dEntry.CommitChanges(); }
注意事项
- 操作前需确保绑定AD对象所用的账号拥有目标对象的属性写入权限,权限不足同样会触发目录服务拒绝操作的异常。
- 如果需求是修改国家属性为指定值而非清空,也必须将三个属性同步设置为互相匹配的值,例如设置
c=CN、co=China、countryCode=156,单独修改其中任意一个属性依然会触发8311错误。
内容的提问来源于stack exchange,提问作者Kiquenet
相关产品推荐
相关产品推荐

