如何在vbs中以管理员身份运行vbs?

29

有人能帮我解决如何以管理员权限从VBScript自身运行的问题吗?我需要通过VBScript重命名Windows 8计算机,但只有在通过管理员命令行(CMD → "以管理员身份运行" → runScript.vbs)运行脚本时才可能实现。如果使用经典CMD启动脚本,则计算机不会被重命名。

我的想法是使用用户权限启动没有参数的脚本,如果没有参数,则脚本将以管理员权限重新运行,并使用参数作为标识符“我是管理员”。

有谁知道我该如何做到这一点吗?

编辑:

我尝试了这个:

If WScript.Arguments.Count = 0 Then
    Set objShell = CreateObject("Shell.Application")
    objShell.ShellExecute "wscript.exe", "c:\Users\admin\Documents\selfConfigure.vbs -1", "", runas", 1
End If

检查高级别PowerToy http://blogs.technet.com/b/elevationpowertoys/archive/2010/06/20/creating-a-self-elevating-script.aspx - Loïc MICHEL
这是很棒的代码,但我认为它不是我的问题的解决方案。我的问题不在于获取脚本是否正在以管理员身份运行,而是需要可靠地以管理员身份运行它。这段代码只是用于检查,我是对的吗? - Daphnis
以下脚本将在未以提升权限运行时“重新启动”自身。 - Loïc MICHEL
1
代码会提升脚本权限,但你在runas之前忘记加引号了。 - user4759923
6个回答

37
如果计算机启用了UAC,类似这样的方法应该可以解决问题:
If Not WScript.Arguments.Named.Exists("elevate") Then
  CreateObject("Shell.Application").ShellExecute WScript.FullName _
    , """" & WScript.ScriptFullName & """ /elevate", "", "runas", 1
  WScript.Quit
End If

'actual code

1
这和我尝试的几乎相同。但它没有起作用。 启用UAC到底意味着什么?我将其设置为“从不通知”,这是禁用的吗? 如果我尝试将UAC更改为更高的选项,它并没有起到帮助的作用。 - Daphnis
在Win8上,“从不通知”并没有完全禁用(您必须使用策略来完全禁用它),但几乎可以认为是禁用了。当我在我的Win7测试机上重新启用UAC时,代码对我来说运行良好。更改UAC级别后,您是否重新启动了计算机? - Ansgar Wiechers
不,我没有,但不幸的是我不能使用启用的UAC,因为这个脚本必须在没有用户的情况下工作。没有用户会等待请求访问权限。这个脚本是用于自动化测试的。难道没有其他选项吗? :/ - Daphnis
你不能把它作为定时任务运行吗? - Ansgar Wiechers
1
对不起,你是正确的。我没有退出第一个脚本,这导致了问题。 :) 现在可以运行了。 - Daphnis

10
将以下内容添加到文件开头:
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.Length = 0 Then
  Set ObjShell = CreateObject("Shell.Application")
  ObjShell.ShellExecute "wscript.exe" _
    , """" & WScript.ScriptFullName & """ RunAsAdministrator", , "runas", 1
  WScript.Quit
End if

@gronostaj,那么你的脚本路径显然包含空格,因为这是这个答案和我的答案之间唯一的区别。 - Ansgar Wiechers
为什么你要这样做 WshShell = WScript.CreateObject("WScript.Shell"),然后从未使用过这个对象呢? - Clint Street
为什么我们需要检查 "If WScript.Arguments.Length = 0"?我想要发送参数... - Raz

3

这是一篇有关提升权限选项的好文章 - http://www.novell.com/support/kb/doc.php?id=7010269

配置应用程序始终请求提升权限:

可以通过在HKCU下的注册表设置来配置程序始终在用户级别请求提升权限。这些注册表设置是即时生效的,因此它们可以在启动特定应用程序之前立即设置,甚至在启动应用程序后立即删除(如果需要的话)。只需在"HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"下为可执行文件的完整路径创建一个"String Value",值为"RUN AS ADMIN"。以下是CMD的示例。

Windows Registry Editor Version 5.00
[HKEY_Current_User\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"c:\\windows\\system32\\cmd.exe"="RUNASADMIN"

3
但是我需要提升权限才能首先编辑那个注册表设置,不是吗?这有点违背初衷。 - masterxilo
https://stackoverflow.com/questions/47895544/mkdir-in-batch-file-as-admin和https://stackoverflow.com/questions/47902221/run-batch-script-as-admin-during-maven-build的程序相关内容,请将文本翻译成中文。只返回翻译后的文本: - CatCat

3

有趣的小批处理文件

@set E=ECHO &set S=SET &set CS=CScript //T:3 //nologo %~n0.vbs /REALTIME^>nul^& timeout 1 /NOBREAK^>nul^& del /Q %~n0.vbs&CLS
@%E%off&color 4a&title %~n0&%S%CX=CLS^&EXIT&%S%BS=^>%~n0.vbs&%S%G=GOTO &%S%H=shell&AT>NUL
IF %ERRORLEVEL% EQU 0 (
    %G%2
) ELSE (
    if not "%minimized%"=="" %G%1
)
%S%minimized=true & start /min cmd /C "%~dpnx0"&%CX%
:1
%E%%S%%H%=CreateObject("%H%.Application"):%H%.%H%Execute "%~dpnx0",,"%CD%", "runas", 1:%S%%H%=nothing%BS%&%CS%&%CX%
:2
%E%%~dpnx0 fvcLing admin mode look up&wmic process where name="cmd.exe" CALL setpriority "realtime"& timeout 3 /NOBREAK>nul
:3
%E%x=msgbox("end of line" ,48, "%~n0")%BS%&%CS%&%CX%

2
@Lizz 这是一个解释一切的网站:https://www.e-learn.cn/content/wangluowenzhang/84740 - DeerSpotter
我不知道是否应该称它为一个有趣的批处理文件!我认为这里应该应用“代码只写一次,但读千百次”的格言。如果代码不易于阅读,那么对任何人来说都没有意义。在可读性方面,这里还有很大的提高空间。但说真的,这只是我的个人意见。许多新手用户在cmd文件和vbs文件中几乎肯定会很难阅读它,因此除非他们完全理解它的作用,否则最好不要实施它...但我也可能错了。 - LarryF

2

我的VBS文件路径:

D:\QTP练习\驱动程序\Testany.vbs'

objShell = CreateObject("Shell.Application")

objShell.ShellExecute "cmd.exe","/k echo test", "", "runas", 1

set x=createobject("wscript.shell")

wscript.sleep(2000)

x.sendkeys "CD\"&"{ENTER}"&"cd D:"&"{ENTER}"&"cd "&"QTP Practice\Driver"&"{ENTER}"&"Testany.vbs"&"{ENTER}"

--来自谷歌搜索和一些调整,对我很有效

2
这是解决此问题的通用且最佳方案:
If WScript.Arguments.Count <> 1 Then WScript.Quit 1
RunAsAdmin
Main

Sub RunAsAdmin()
    Set Shell = CreateObject("WScript.Shell")
    Set Env = Shell.Environment("VOLATILE")
    If Shell.Run("%ComSpec% /C ""NET FILE""", 0, True) <> 0 Then
        Env("CurrentDirectory") = Shell.CurrentDirectory
        ArgsList = ""
        For i = 1 To WScript.Arguments.Count
            ArgsList = ArgsList & """ """ & WScript.Arguments(i - 1)
        Next
        CreateObject("Shell.Application").ShellExecute WScript.FullName, """" & WScript.ScriptFullName & ArgsList & """", , "runas", 5
        WScript.Sleep 100
        Env.Remove("CurrentDirectory")
        WScript.Quit
    End If
    If Env("CurrentDirectory") <> "" Then Shell.CurrentDirectory = Env("CurrentDirectory")
End Sub

Sub Main()
    'Your code here!
End Sub

优点:

1) 不可能进行参数注入。
2) 在提升为管理员后,参数数量不会发生变化,因此您可以在提升前检查它们。
3) 您可以真实且立即地知道脚本是否以管理员身份运行。例如,如果您从控制面板卸载条目调用它,则RunAsAdmin函数不会不必要地运行,因为在这种情况下您已经是管理员。如果您从已经提升为管理员的脚本中调用它,则情况也是如此。
4) 窗口保持其当前大小和位置,正如应该的那样。
5) 获得管理员权限后,当前目录不会更改。

缺点:没有


谢谢,您的答案帮助我回答了这个问题。 - Io-oI

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