【问题标题】:transfer CurrentDirectory from un-elevated script to elevated one将 CurrentDirectory 从未提升的脚本转移到提升的脚本
【发布时间】:2019-06-05 19:40:51
【问题描述】:

我需要将与脚本(在我的闪存驱动器中)位于同一目录中的文件“manufacturer.bmp”复制到system32 目录。

我成功地获取了变量sourcefiledestinationdirectory,并提升了我的脚本,但是当我提升它时,我的sourcefile 变量丢失了,因为使用了CurrentDirectory,不同之处在于这种模式。

Set shell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")

CurrentDirectory = fso.GetAbsolutePathName(".")
sourcefile = fso.buildpath(CurrentDirectory, "manufacturer.bmp")
MsgBox(sourcefile)

'Checks if the script is running elevated (UAC)
Function isElevated
  Set shell = CreateObject("WScript.Shell")
  Set whoami = shell.Exec("whoami /groups")
  Set whoamiOutput = whoami.StdOut
  strWhoamiOutput = whoamiOutput.ReadAll

  If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then 
    isElevated = True
  Else
    isElevated = False
  End If
End Function

'Re-runs the process prompting for priv elevation on re-run
Sub uacPrompt
  'Check if we need to run in C or W script
  interpreter = "wscript.exe"
  If InStr(1, WScript.FullName, "CScript", vbTextCompare) = 0 Then
    interpreter = "wscript.exe"
  Else
    interpreter = "cscript.exe"
  End If

  'Start a new instance with an elevation prompt first
  Set shellApp = CreateObject("Shell.Application")
  shellApp.ShellExecute interpreter, Chr(34) & WScript.ScriptFullName & _
    Chr(34) & " uac", "", "runas", 1

  'End the non-elevated instance
  WScript.Quit
End Sub

'Make sure we are running elevated, prompt if not
If Not isElevated Then uacPrompt

destinationdir = fso.buildpath(shell.ExpandEnvironmentStrings("%windir%"), _
                 "system32")
MsgBox(destinationdir)

fso.CopyFile sourcefile, destinationdir

知道如何将我的源文件 var 推送到子提升脚本吗?

【问题讨论】:

    标签: vbscript uac


    【解决方案1】:

    ShellExecute 方法允许您将工作目录指定为 3rd 参数,因此您可以将当前目录传递给提升的脚本并在提升后构建sourcefile 路径。此外,您的代码还可以精简很多。

    Const HKLM   = &h80000002
    Const DELETE = &h10000
    
    Set sh = CreateObject("WScript.Shell")
    
    Set reg = GetObject("winmgmts://./root/default:StdRegProv")
    reg.CheckAccess HKLM, "SYSTEM\CurrentControlSet", DELETE, isAdmin
    
    If Not isAdmin Then
      If WScript.Arguments.Count = 0 Then
        CreateObject("Shell.Application").ShellExecute WScript.FullName, _
          Chr(34) & WScript.ScriptFullName & Chr(34) & " uac", _
          sh.CurrentDirectory, "runas", 1
        WScript.Quit 0
      Else
        WScript.Echo "Privilege elevation failed!"
        WScript.Quit 1
      End If
    End If
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    src = fso.BuildPath(sh.CurrentDirectory, "manufacturer.bmp")
    dst = fso.buildpath(sh.ExpandEnvironmentStrings("%windir%"), "system32")
    
    fso.CopyFile src, dst & "\"
    

    编辑: 或者至少如果您不提升流程,它会这样工作。根据 Raymond Chen 的this blog post,在提升进程时忽略启动目录,因此当前目录中的恶意 DLL 不会被错误地加载到提升的进程中。这意味着您必须“手动”传递工作目录,如下所示:

    Const HKLM   = &h80000002
    Const DELETE = &h10000
    
    Set sh = CreateObject("WScript.Shell")
    
    Set reg = GetObject("winmgmts://./root/default:StdRegProv")
    reg.CheckAccess HKLM, "SYSTEM\CurrentControlSet", DELETE, isAdmin
    
    If Not isAdmin Then
      If WScript.Arguments.Count = 0 Then
        CreateObject("Shell.Application").ShellExecute WScript.FullName, _
          Chr(34) & WScript.ScriptFullName & Chr(34) & " " & _
          Chr(34) & sh.CurrentDirectory & Chr(34), , "runas", 1
        WScript.Quit 0
      Else
        WScript.Echo "Privilege elevation failed!"
        WScript.Quit 1
      End If
    End If
    
    sh.CurrentDirectory = WScript.Arguments(0)
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    src = fso.BuildPath(sh.CurrentDirectory, "manufacturer.bmp")
    dst = fso.buildpath(sh.ExpandEnvironmentStrings("%windir%"), "system32")
    
    fso.CopyFile src, dst & "\"

    请注意,由于您的目标路径是一个文件夹,它必须有一个尾部反斜杠(如documented)。

    【讨论】:

    • 非常感谢您的回答和您的时间,我已经尝试了您的解决方案,但它似乎不起作用。我添加了消息框来输出变量以进行验证。当提升的脚本运行时,工作目录仍然是 C:\windows\system32 并且我无法使用它的相对路径访问给定的 bmp 文件。我通过这种情况的想法是将 bmp 文件临时复制到一个固定的临时文件夹,然后在提升时将其复制到 System32 文件夹中。
    • 它适用于临时目录: If Not isAdmin Then sourcefile = fso.buildpath(CurrentDirectory, "manufacturer.bmp") fso.CopyFile sourcefile, temploc & "\" If WScript.Arguments.Count = 0 然后 [...] 其他 temploc = sh.ExpandEnvironmentStrings("%temp%") sourcefile = fso.buildpath(temploc, "manufacturer.bmp") dst = fso.buildpath(sh.ExpandEnvironmentStrings("%windir%") , "system32") fso.CopyFile sourcefile, dst & "\" End If
    • @Letouane 抱歉回复晚了。请参阅答案以获取解释和解决方法。
    • 尝试了您的答案,非常感谢 Ansgar(与“延迟回复”无关,您为我提供帮助)!
    猜你喜欢
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2022-10-25
    • 2010-09-12
    相关资源
    最近更新 更多