What is the C# equivalent code for the Powershell sript to remove user from Adminstrators group?

huangapple go评论89阅读模式
英文:

What is the C# equivalent code for the Powershell sript to remove user from Adminstrators group?

问题

以下是您要翻译的内容:

using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine))
{
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.Name, args[0]);
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "Administrators");

    if (user != null && group != null)
    {
        try
        {
            if (group.Members.Remove(user))
            {
                Console.WriteLine("User successfully removed from Local Administrators.");
            }
            else
            {
                Console.WriteLine("User is not a Local Administrator1.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("User is not a Local Administrator.");
            Console.WriteLine(ex.ToString());
        }
    }
    else
    {
        Console.WriteLine("User was not found.");
    }
}

请注意,代码部分不要翻译。

英文:

I have a PowerShell script. It is to remove the user from the Administrators group. It's working fine for local and domain users both.

Remove-LocalGroupMember -Group "Administrators" -Member "Admin02"

I want to implement this in C#. I have tried the below code. But it's not working for the domain account.

using (PrincipalContext ctx = new PrincipalContext(ContextType.Machine))
{
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.Name, args[0]);
    GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "Administrators");

    if (user != null && group != null)
    {
        try
        {
            if (group.Members.Remove(user))
            {
                Console.WriteLine("User successfully removed from Local Administrators.");
            }
            else
            {
                Console.WriteLine("User is not a Local Administrator1.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("User is not a Local Administrator.");
            Console.WriteLine(ex.ToString());
        }
    }
    else
    {
        Console.WriteLine("User was not found.");
    }
}

Its printing User was not found.

I have tried with ContextType.Domain as well.

Edit: Thank you @Gabriel Luci. for providing the solution. I tried his solution, but there is a challenge with it.

I have a domain user name T1/spreda (forward slash).

What is the C# equivalent code for the Powershell sript to remove user from Adminstrators group?

But when I run your code and see the value of member, it shows users like this (with back slash). I have written this code to check the user.

var group = new DirectoryEntry("WinNT://./Administrators");
                
foreach (var m in (IEnumerable)group.Invoke("Members"))
{
    var member = new DirectoryEntry(m);
    var str = JsonConvert.SerializeObject(member);
    Console.WriteLine(str);
    //if (str.Contains(args[0]))
    //{
    //    Console.WriteLine("Found");
    //    var returnVal = group.Invoke("Remove", new[] { member.Path });
    //    Console.WriteLine(returnVal.ToString());
    //    break;

So Is there a way to handle this?

What is the C# equivalent code for the Powershell sript to remove user from Adminstrators group?

答案1

得分: 1

使用AccountManagement命名空间来处理(GroupPrincipal/UserPrincipal)的问题在于创建对象时会加载所有属性。这意味着需要连接到AD以创建AD用户的UserPrincipal对象,但我们不需要这样做来从组中移除用户。

您可以使用DirectoryEntry来执行此操作,而GroupPrincipalUserPrincipal在幕后也使用它。代码如下:

var group = new DirectoryEntry("WinNT://./Administrators");

foreach (var m in (IEnumerable)group.Invoke("Members"))
{
    var member = new DirectoryEntry(m);
    if (member.Name == args[0]) {
        group.Invoke("Remove", new [] {member.Path});
        break;
    }
}

这使用了WinNT提供程序(而不是LDAP)来加载本地组。.表示本地计算机。如果要从远程计算机加载管理员组,可以将计算机名称放入路径中,如WinNT://computer1/Administrators

DirectoryEntry是本机Windows C++ COM ADSI对象的包装器。在这种情况下,因为我们正在加载一个组,它是一个IADsGroup对象。我们使用DirectoryEntry.Invoke()来调用底层对象的方法。因此,group.Invoke("Members")调用IADsGroup::Members,它返回成员列表。同样,group.Invoke("Remove", new [] {member.Path})调用IADsGroup::Remove来移除成员。

我总是更喜欢使用DirectoryEntry,即使纯粹处理AD对象时也是如此。它让您更好地控制性能。我在我写的一篇文章中讨论了这一点:Active Directory: Better performance

英文:

The problem with using the AccountManagement namespace for this (GroupPrincipal/UserPrincipal) is that the act of creating the object loads all the properties. That means that it needs to connect to AD to create a UserPrincipal object of an AD user, but we don't need to to do that to remove a user from a group.

You can do this with DirectoryEntry, which GroupPrincipal and UserPrincipal use behind the scenes anyway. It would look like this:

var group = new DirectoryEntry("WinNT://./Administrators");

foreach (var m in (IEnumerable)group.Invoke("Members"))
{
    var member = new DirectoryEntry(m);
    if (member.Name == args[0]) {
        group.Invoke("Remove", new [] {member.Path});
        break;
    }
}

This uses the WinNT provider (as opposed to LDAP) to load the local group. The . means the local computer. If you wanted to load the Administrators group from a remote computer, you can put the computer name in the path, like WinNT://computer1/Administrators.

DirectoryEntry is a wrapper around the native Windows C++ COM ADSI objects. In this case, because we're loading a group, it's an IADsGroup object. We use DirectoryEntry.Invoke() to call a method from the underlying object. So group.Invoke("Members") calls IADsGroup::Members, which returns a list of the members. Likewise, group.Invoke("Remove", new [] {member.Path}) calls IADsGroup::Remove to remove the member.

I always prefer using DirectoryEntry, even when working purely with AD objects. It gives you far more control over performance. I talked about that in an article I wrote: Active Directory: Better performance

huangapple
  • 本文由 发表于 2023年2月27日 17:55:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75578943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定