【问题标题】:Permission elevation from VBScript来自 VBScript 的权限提升
【发布时间】:2012-11-08 19:27:09
【问题描述】:

我们运行 Dynamics GP。由于它存储表单/报告的方式,我需要一些将 .SET 文件复制到程序目录中的安装脚本。这可以手动完成,但让用户运行安装程序脚本来为他们​​安装适当的文件会更快。

我一直在构建一个复制必要文件的 VBScript 安装程序。棘手的部分是一些客户端运行的是 Windows XP,而一些客户端运行的是 Windows 7(甚至 8)。 UAC 已启用,因此权限开始发挥作用。

我尝试这样做的方法是盲目地尝试复制文件,如果检测到权限错误,它会以管理员权限重新启动脚本。我们遇到的问题是一些(全部?)Windows 7 机器启用了虚拟文件/注册表写入,因此当脚本尝试将文件复制到 C:\Program Files\Microsoft Dynamics\GP2010 时,它会默默地失败并复制它们到用户的 AppData\Local\VirtualStore 目录。这不适用于 GP。

所以我需要做的是让脚本将文件复制到 C:\Program Files(而不是 VirtualStore 目录),并仅在必要时提升权限。如果我让它全面提升,这会导致 Windows XP 机器在启动脚本时简单地弹出一个神秘的“运行方式”对话框。

这是我目前所拥有的:

Dim WSHShell, FSO, Desktop, DesktopPath
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("WScript.Shell")
Desktop = WSHShell.SpecialFolders("Desktop")
DesktopPath = FSO.GetAbsolutePathName(Desktop)

'Set working directory to directory the script is in.
'This ends up being C:\Windows\System32 if the script is
'started from ShellExecute, or a link in an email, thus breaking
'relative paths.
WSHShell.CurrentDirectory = FSO.GetFile(WScript.ScriptFullName).ParentFolder

On Error Resume Next

If FSO.FolderExists("C:\Program Files (x86)") Then
    WScript.Echo "Installing 64-bit."
    FSO.CopyFile "64-bit\*.set", "C:\Program Files (x86)\Microsoft Dynamics\GP2010\", True
    FSO.CopyFile "64-bit\*.lnk", DesktopPath, True
ElseIf FSO.FolderExists("C:\Program Files\Microsoft Dynamics\GP2010\Mekorma MICR") Then
    WScript.Echo "Installing 32-bit (with MICR)."
    FSO.CopyFile "32-bit MICR\*.set", "C:\Program Files\Microsoft Dynamics\GP2010\", True
    FSO.CopyFile "32-bit MICR\*.lnk", DesktopPath, True 
Else
    WScript.Echo "Installing 32-bit."
    FSO.CopyFile "32-bit\*.SET", "C:\Program Files\Microsoft Dynamics\GP2010\", True
    FSO.CopyFile "32-bit\*.lnk", DesktopPath, True
End If

If Err.Number = 70 Then
    CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """" , "", "runas", 1
    WScript.Quit
ElseIf Err.Number <> 0 Then
    MsgBox "Error " & Err.Number & vbCrLf & Err.Source & vbCrLf & Err.Description
Else
    MsgBox "Installed successfully."
End If

总结:我如何让 VBScript 提升权限不会导致 XP 在“运行方式”对话框中停止,并且不会导致 Windows 7 复制文件改为 AppData\Local\VirtualStore?

【问题讨论】:

    标签: windows-7 vbscript


    【解决方案1】:

    改进了@db2 答案:

    • 真正的海拔测试,不依赖于传递的参数
    • 将所有原始参数传递给提升的脚本
    • 使用与初始脚本相同的主机:wscript.execscript.exe

    代码:

    Set OSList = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")
    For Each OS In OSList
        If InStr(1, OS.Caption, "XP") = 0 And InStr(1, OS.Caption, "Server 2003") = 0 Then
            With CreateObject("WScript.Shell")
                IsElevated = .Run("cmd.exe /c ""whoami /groups|findstr S-1-16-12288""", 0, true) = 0
                If Not IsElevated Then
                    Dim AllArgs
                    For Each Arg In WScript.Arguments
                        If InStr( Arg, " " ) Then Arg = """" & Arg & """"
                        AllArgs = AllArgs & " " & Arg
                    Next
                    Command = """" & WScript.ScriptFullName & """" & AllArgs
                    With CreateObject("Shell.Application")
                        .ShellExecute WScript.FullName, " //nologo " & Command, "", "runas", 1
                        WScript.Echo WScript.FullName & " //nologo " & Command
                    End With
                    WScript.Quit
                End If
            End With
        End If
    Next
    
    ' Place code to run elevated here
    

    【讨论】:

      【解决方案2】:

      似乎这是最简单的方法。

      1. 检查操作系统版本。
      2. 如果不是 XP 或 2003(我预计不会在任何旧版本上运行),请使用提升重新执行。

      这是我添加到脚本开头的代码块:

      Dim OSList, OS, UAC
      UAC = False
      If WScript.Arguments.Count >= 1 Then
          If WScript.Arguments.Item(0) = "elevated" Then UAC = True
      End If
      
      If Not(UAC) Then
          Set OSList = GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")
          For Each OS In OSList
              If InStr(1, OS.Caption, "XP") = 0 And InStr(1, OS.Caption, "Server 2003") = 0 Then
                  CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """ elevated" , "", "runas", 1
                  WScript.Quit
              End If
          Next
      End If
      

      【讨论】:

      • 看起来你自己回答了,但我会测试当前登录的用户是否有管理员权限,而不是 Win 版本,如果只需要提升。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 2016-01-17
      • 1970-01-01
      相关资源
      最近更新 更多