【问题标题】:Best way to know if a user has administrative privileges from a VBScript了解用户是否具有 VBScript 管理权限的最佳方法
【发布时间】:2008-11-19 13:17:49
【问题描述】:

我需要检查执行脚本的用户是否在机器上具有管理权限。

我已经指定了执行脚本的用户,因为该脚本可能已经使用类似于“Runas”的登录用户以外的用户执行。

@Javier:这两种解决方案都可以在安装了英文版 Windows 的 PC 上工作,但如果安装的是不同的语言,则不能。这是因为管理员组不存在,名称不同,例如西班牙语。我需要适用于所有配置的解决方案。

【问题讨论】:

    标签: vbscript privileges


    【解决方案1】:

    这样做可以打破用户拥有脚本所需权限但不属于管理员的情况。与其检查组成员身份,不如检查您需要的特定能力。

    【讨论】:

    • 我同意这将是一种更好的实现方式,但它要求用户具有安装软件的管理权限,因此我认为检查会更容易。
    【解决方案2】:

    我知道这个帖子很旧并且标记为已回答,但答案并没有真正给出 OP 所询问的内容。

    对于搜索和查找此页面的其他人,这里有一个替代方案,它基于权限而不是组成员身份进行报告,因此 Runas 管理员将管理员权限显示为 True。

    Option Explicit 
    
    msgbox isAdmin(), vbOkonly, "Am I an admin?"
    
    Private Function IsAdmin()
        On Error Resume Next
        CreateObject("WScript.Shell").RegRead("HKEY_USERS\S-1-5-19\Environment\TEMP")
        if Err.number = 0 Then 
            IsAdmin = True
        else
            IsAdmin = False
        end if
        Err.Clear
        On Error goto 0
    End Function
    

    【讨论】:

    • 这能够检测到我何时以“管理员身份”打开了 MS Access。在 Windows 10 64 位和 Office 2016 32 位上测试。
    【解决方案3】:

    如果要查看登录用户是否为管理员,可以使用脚本

    Set objNetwork = CreateObject("Wscript.Network")
    strComputer = objNetwork.ComputerName
    strUser = objNetwork.UserName
    
    isAdministrator = false
    
    Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators")
    For Each objUser in objGroup.Members
        If objUser.Name = strUser Then
            isAdministrator = true        
        End If
    Next
    
    If isAdministrator Then
        Wscript.Echo strUser & " is a local administrator."
    Else
        Wscript.Echo strUser & " is not a local administrator."
    End If
    

    恐怕当脚本使用“Runas”运行时,我不确定如何处理它。

    【讨论】:

    • 嗨,蒂姆 C,谢谢。我检查了它,它似乎在我的情况下也可以正常工作。我得到的用户名不是记录的用户名,而是正在执行脚本的用户名。只有一条评论。它有点慢。我从一个 HTML 页面的启动调用这个脚本,它大约需要 2/3 秒。
    • 如果用户不是直接在管理员组中而是通过某些组成员身份,这不起作用。
    【解决方案4】:

    检查“\\computername\Admin$\system32”怎么样?

    function IsLoggedInAsAdmin()
        isAdmin = false
        set shell = CreateObject("WScript.Shell")
        computername = WshShell.ExpandEnvironmentStrings("%computername%")
        strAdmin = "\\" & computername & "\Admin$\System32"
    
        isAdmin = false
    
        set fso = CreateObject("Scripting.FileSystemObject")
    
        if fso.FolderExists(strAdmin) then
            isAdmin = true
        end if
    
        IsLoggedInAsAdmin = isAdmin
    end function
    

    【讨论】:

      【解决方案5】:

      我在公司网络上的 Windows 7 机器上尝试了 Tim C 的解决方案,我确实拥有管理员权限。但它显示我的用户没有管理员权限。

      相反,我使用了一种更骇人听闻的方法,因为在 cmd 提示符下调用“碎片整理”需要管理员权限。虽然它可以工作,但请注意 XP 和 7(以及可能的 Windows 未来版本)在返回码方面存在差异。可能有比碎片整理更一致的选择,但它目前有效。

      Function isAdmin
          Dim shell
          set shell = CreateObject("WScript.Shell")
          isAdmin = false
          errlvl = shell.Run("%comspec% /c defrag /?>nul 2>nul", 0, True)
          if errlvl = 0 OR errlvl = 2 Then '0 on Win 7, 2 on XP
              isAdmin = true
          End If
      End Function
      

      【讨论】:

        【解决方案6】:

        This article 有很多关于如何枚举组成员的代码(为方便起见,在此处复制并编辑为不使用电子邮件地址):

        Function RetrieveUsers(domainName,grpName)
        
        dim GrpObj
        dim mbrlist
        dim mbr
        
        '-------------------------------------------------------------------------------
        ' *** Enumerate Group Members ***
        '-------------------------------------------------------------------------------
        
        ' Build the ADSI query and retrieve the group object
        Set GrpObj = GetObject("WinNT://" & domainName & "/" & grpName & ",group")
        
        ' Loop through the group membership and build a string containing the names
        for each mbr in GrpObj.Members
           mbrlist = mbrlist & vbTab & mbr.name & vbCrLf
        Next
        
        RetrieveUsers=mbrlist
        
        End Function
        

        然后您可以编写一个函数来查看用户是否在列表中...

        Function IsAdmin(user)
            IsAdmin = InStr(RetrieveUsers("MachineName", "Administrators"), user) > 0
        End Function
        

        ...然后这样称呼它:

        If IsAdmin("LocalAccount") Then
            Wscript.Echo "LocalAccount is an admin"
        Else
            Wscript.Echo "LocalAccount is not an admin"
        End If
        

        【讨论】:

          【解决方案7】:

          另一种快速的肮脏方法。返回 0 If IsNotAdmin

          Function IsNotAdmin()
              With CreateObject("Wscript.Shell")
                  IsNotAdmin = .Run("%comspec% /c OPENFILES > nul", 0, True)
              End With
          End Function
          

          【讨论】:

          • 当我已经在运行“作为管理员”时,这会提示我进行 UAC 程序提升,如果我选择“是”则返回 0。在我的普通帐户下运行时,它返回 1 但没有 UAC 提示。我不喜欢这种方法。
          【解决方案8】:

          用户可能不在本地管理员组中。例如 - 域管理员。 UAC 通常会阻止管理员访问注册表、共享等。即使对于管理员(只有手动“以管理员身份运行”才正确)...

          这是我的疯狂方式:

          Set Shell = CreateObject("WScript.Shell")
          set fso = CreateObject("Scripting.FileSystemObject")
          strCheckFolder = Shell.ExpandEnvironmentStrings("%USERPROFILE%") 
          strCheckFolder = strCheckFolder+"\TempFolder"
          
          if fso.FolderExists(strCheckFolder) then
                  fso.DeleteFolder(strCheckFolder)
          end if
          
          fso.CreateFolder(strCheckFolder)
          tempstr = "cmd.exe /u /c chcp 65001 | whoami /all >" & strCheckFolder & "\rights.txt"
          Shell.run tempstr
          
          tempstr = strCheckFolder & "\rights.txt"
          WScript.Sleep 200
          Set txtFile = FSO.OpenTextFile(tempstr,1)
          
          IsAdmin = False
          
          Do While Not txtFile.AtEndOfStream
            x=txtFile.Readline
            If InStr(x, "S-1-5-32-544") Then
                IsAdmin = True
            End If
          Loop
          
          txtFile.Close
          

          【讨论】:

            【解决方案9】:
            Function isAdmin
                Dim shell
                Set shell = CreateObject("WScript.Shell")
                isAdmin = false
                errorLevel = shell.Run("%comspec% /c net session >nul 2>&1", 0, True)
                if errorLevel = 0
                    isAdmin = true
                End If
            End Function
            

            【讨论】:

              【解决方案10】:

              使用“localhost”而不是真正的主机名将脚本运行时间增加了大约 10 倍!
              我的最终代码是:

              ' get_admin_status.vbs
              Option Explicit
              
              Dim oGroup:   Set oGroup   = GetObject("WinNT://localhost/Administrators,group")
              Dim oNetwork: Set oNetwork = CreateObject("Wscript.Network")
              
              Dim sSearchPattern: sSearchPattern = "WinNT://" & oNetwork.UserDomain & "/" & oNetwork.UserName
              
              Dim sMember
              For Each sMember In oGroup.Members
                If sMember.adsPath = sSearchPattern Then
                  ' Found...
                  Call WScript.Quit(0)
                End If
              Next
              
              ' Not found...
              Call WScript.Quit(1)
              

              如果当前用户是本地管理员,则此脚本返回退出代码 0。
              用法:cscript.exe get_admin_status.vbs

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-07-09
                • 1970-01-01
                • 1970-01-01
                • 2012-03-28
                • 2011-02-26
                • 2011-02-17
                • 1970-01-01
                • 2014-06-25
                相关资源
                最近更新 更多