2

我正在尝试创建一个这样的校长:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);

group.Name = "Some Group Name";
group.Description = "Some Group Name Description";

group.Save();

但是,执行代码时,我收到以下异常消息:

System.DirectoryServices.AccountManagement:属性对此商店类型无效。

如果我设置Description属性,上面的代码工作得很好,只是没有组的描述。

难道我做错了什么?

提前致谢。

编辑: 我相信我已经找到了解决方法(对于任何可能感兴趣的人)。可以通过与上述相同的方式创建组:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
GroupPrincipal group = new GroupPrincipal(pc);
group.Save();

现在您创建一个DirectoryEntry并将其链接到新创建的组,如下所示:

string path = "WinNT://" + machineName + "/" + group.SamAccountName;
DirectoryEntry dEntry = new DirectoryEntry(path);

这允许访问该组的属性,但我感兴趣的是描述,所以:

dEntry.Properties["description"].Add("Some Decription");
dEntry.CommitChanges();

那应该这样做。

4

2 回答 2

7

答案改写

我得到了你的答案,但你可能不太喜欢它。网上的资料很少,但在代码中,是可以解释的:

  • 创建GroupPrincipal时,会向其中添加一个Context。这个Context内部是一个隐藏类型:SAMStoreCtx,它继承自一个抽象类型StoreCtx;
  • 您调用的 GroupPrincipal 上的每个属性都将调用 IsValidProperty,它是 SamStoreCtx 的内部成员;
  • 但是,对于 Name 属性,它不会这样做;
  • 在 SAMStoreCtx 内部,有一段代码如下所示(Reflector 输出):

    internal override bool IsValidProperty(Principal p, string propertyName)
    {
        ObjectMask none = ObjectMask.None;
        if (!ValidPropertyMap.TryGetValue(propertyName, out none))
        {
            return false;
        }
        if ((MaskMap[p.GetType()] & none) <= ObjectMask.None)
        {
            return false;
        }
        return true;
    }
    
  • 仔细查看该代码(我花了一点时间),您会发现错误。将位标志与none使用 and 运算符进行比较的行将始终导致 ObjectMask.None。因此,第二个 if 语句始终为 true
  • 当此方法返回 false 时,调用代码(描述的属性设置器)会引发异常。

我认为这是 Microsoft 库中的错误。它只发生在 SAMStoreCtx 上。也许这是故意的,但是因为代码在那里但总是返回 false 让我相信程序员打算使用 or 运算符。使用 DisplayName 等其他属性检查我的发现会引发与预期相同的异常。

您可以就此与 Microsoft 联系并向他们展示此线程。我还没有检查 .NET 4.0 的新测试版,它可能会以不同的方式出现。您可以通过下载 Reflector 并加载相关的 .NET 程序集自行检查。

编辑:我已经为您联系了 Microsoft,并通过此处的 connect.microsoft.com报告了该错误。如果你愿意,你可以关注那里的问题。

于 2010-01-18T14:58:18.933 回答
3

您可以使用 GetUnderlyingObject 来获取组的 DirectoryEntry 而不是搜索它。

var newGroup = new GroupPrincipal(context, groupName);

// You must save first           
newGroup.Save();

var entry = (DirectoryEntry) newGroup.GetUnderlyingObject();

entry.Properties["description"].Add(description);
entry.CommitChanges(); 
于 2012-03-09T12:03:11.140 回答