使用C#检查当前已登录用户是否是管理员(远程计算机)

4
我知道关于这个问题有很多讨论,但没有一个真正回答了我的问题。
我正在寻找一种方法,可以远程检查当前登录用户是否具有管理员权限。无论他是机器上内置“管理员”组的成员还是嵌套在“管理员”中的组的成员,例如“域管理员”。
我找到了几种方法,但每种方法都只提供了一半的解决方案。
方法#1(可以远程工作,但仅检查本地“管理员”组):
private bool isAdmin()
{
    ArrayList mem2 = new ArrayList();
    string hostName = basicinfomodel.Loggedusername; //a username I get from another class
    try
    {
        using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + mycomputer.myComputerName)) // remote computer that I get from another class
        {
            //get local admin group
            using (DirectoryEntry group = machine.Children.Find("Administrators", "Group"))
            {
                //get all members of local admin group
                object members = group.Invoke("Members", null);
                foreach (object member in (IEnumerable)members)
                {
                    //get account name
                    string accountName = new DirectoryEntry(member).Name;
                    mem2.Add(new DirectoryEntry(member).Name);
                }
            }
        }
    }
    catch (Exception ex)
    {
        // catch
    }

    if (mem2.Contains(hostName.ToUpper()) || mem2.Contains(hostName.ToLower()))
        return true;
    else
        return false;
}

方法二(检查本地和域管理员权限但无法在远程计算机上工作)

static bool isAdmin()
{
    WindowsIdentity User = new WindowsIdentity(@"user01");
    WindowsPrincipal princ = new WindowsPrincipal(User);
    return princ.IsInRole(WindowsBuiltInRole.Administrator);
}

正如我所说,我没有找到任何既能够检查用户是否真的拥有管理员权限,同时又能够远程执行这个操作的方法。

  1. 检查用户是否真的拥有管理员权限
  2. 远程执行该操作

感谢帮助!


2
“检查用户是否是外部计算机上的本地管理员”(http://stackoverflow.com/a/15098451)没有帮助吗? - Ken White
我不使用VB,但我成功将其转换为C#。它与我的方法非常相似,但我不知道它在哪里有帮助...还是谢谢。 - Sagiv b.g
2个回答

5

好的,我想我找到了一种方法来实现这个,我分享出来以便其他人使用。 我尝试了几种方法并创建了以下内容(似乎有效)

static bool isAdmin(string username, string machinename)
{
    using (PrincipalContext ctxMacine = new PrincipalContext(ContextType.Machine, machinename))
    {
        using (PrincipalContext ctxDomain = new PrincipalContext(ContextType.Domain))
        {
            UserPrincipal up = UserPrincipal.FindByIdentity(ctxDomain, IdentityType.SamAccountName, username);
            GroupPrincipal gp = GroupPrincipal.FindByIdentity(ctxMacine, "Administrators");

            foreach (UserPrincipal usr in gp.GetMembers(true))
            {
                if (up != null)
                {
                    if (up.SamAccountName.ToUpper() == usr.SamAccountName.ToUpper())
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

注意
这是一个天真的实现,你应该验证你的代码,检查null并处理异常。


你有该方法的类文件吗? - RalphF
我不这么认为,这是3年前的事情 :) - Sagiv b.g
@Sagivb.g 我有一台电脑,在这行代码上返回 null:GroupPrincipal gp = GroupPrincipal.FindByIdentity(ctxMacine, "Administrators"); 但是应该检查 gp 是否为 null。 - John
@John,是的,我刚刚更新了我的答案,说__这是一个天真的实现,你应该验证你的代码,检查空值并处理异常__。 - Sagiv b.g

2

上面的解决方案很不错,但对于不同情况可能会抛出太多异常,并且您必须是远程计算机上的管理员才能运行此方法而不出现异常。

所以...我不想捕获所有可能的异常,而且我希望尽快完成。

因此,对于我来说,这是检查远程计算机上当前用户管理员权限的最佳且最快速的方法:

    public static bool AdminCheck(string machineName)
    {
        if (Directory.Exists(string.Format("\\\\{0}\\admin$", machineName)))
        {
            return true;
        }

        return false;
    }

如果没有管理员权限,您将无法访问管理共享,并且在某人删除它们时,它们会自动重新创建。说实话,我不认为有人会尝试删除操作系统文件夹。

更多详细信息可以在这里找到:https://en.wikipedia.org/wiki/Administrative_share


这将仅检查当前已登录的用户。我的需求(和解决方案)是提供任何“用户名”和任何“机器名”以进行匹配。 - Sagiv b.g
@Sagiv b.g 嗯...很抱歉我误解了问题。 :) 我以为你需要知道你的应用程序当前用户在远程计算机上是否具有管理员权限,这是我的错。 - Blaato
但在这种情况下,我认为WMI是获取该信息的最佳方式。 - Blaato
没有问题,你的答案仍然对其他人有价值如果他们需要这种用例。 - Sagiv b.g
1
我已经好几年没用过这个了,但据我所记,WMI并不总是适用于某些策略。当然,这取决于组织的政策。 - Sagiv b.g
我正在尝试检查 Windows 10 计算机上的用户是否具有本地管理员权限(而不是应用程序以提升的权限运行),这是唯一有效的方法 :-\ 我的用户在本地管理员组中,这是我在所有谷歌搜索结果中找到的唯一一个返回 true 的方法。 - oleksa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接