为了账号安全,请及时绑定邮箱和手机立即绑定

我如何能够自动提升我的批处理文件,以便它请求从UAC管理员的权利,如果需要的话?

/ 猿问

我如何能够自动提升我的批处理文件,以便它请求从UAC管理员的权利,如果需要的话?

慕码人2483693 2019-06-25 13:07:05

我如何能够自动提升我的批处理文件,以便它请求从UAC管理员的权利,如果需要的话?

我希望我的批处理文件只运行提升。如果未提升,请为用户提供一个选项,将批处理重新启动为提升。

我正在编写一个批处理文件来设置系统变量,将两个文件复制到程序文件位置,并启动驱动程序安装程序。如果Windows 7/WindowsVista用户(UAC启用,即使他们是本地管理员)运行它没有右键单击和选择“RunasAdministrator”,他们将获得‘访问拒绝’复制两个文件和写入系统变量。

如果用户实际上是管理员,我想使用命令自动重新启动批处理。否则,如果他们不是管理员,我想告诉他们,他们需要管理员特权来运行批处理文件。我在用xCopy复制文件Reg添加若要写入系统变量,请执行以下操作。我正在使用这些命令来处理可能的WindowsXP计算机。我在这个主题上发现了类似的问题,但是没有任何问题涉及到重新启动批处理文件。



查看完整描述

3 回答

?
POPMUISE

您可以让脚本调用自己Pexec-h选择高空作业。

我不知道你怎么知道它是否已经被提升了.也许只有当有一个访问被拒绝的错误时,才重新尝试高高烧?

或者,您可以简单地使用xcopyreg.exe总是与.一起运行psexec -h,但如果最终用户每次都需要输入密码(如果您在脚本中包含密码,则不安全),这对最终用户来说是很烦人的.


查看完整回答
反对 回复 2019-06-25
?
哆啦的时光机

有一种不需要使用外部工具的简单方法-它可以很好地运行。Windows 7、8、8.1和10而且也是向后兼容的(WindowsXP没有任何UAC,因此不需要升级-在这种情况下,脚本就会继续进行)。

看看这段代码(我受到了NIronWolf发布在线程中的代码的启发。)批处理文件-Windows 7上的“拒绝访问”?),但我已经对其进行了改进-在我的版本中,没有创建和删除任何目录来检查管理员权限):

:::::::::::::::::::::::::::::::::::::::::::::: Elevate.cmd - Version 4:: Automatically check & get admin rights:
: see "https://stackoverflow.com/a/12264592/1016343" for description::::::::::::::::::::::::::::::::::::::::::::
 @echo off
 CLS
 ECHO.
 ECHO =============================
 ECHO Running Admin shell
 ECHO =============================:init
 setlocal DisableDelayedExpansion
 set cmdInvoke=1
 set winSysFolder=System32
 set "batchPath=%~0"
 for %%k in (%0) do set batchName=%%~nk set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
 setlocal EnableDelayedExpansion:checkPrivileges
  NET FILE 1>NUL 2>NUL  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ):
  getPrivileges  if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
  ECHO.
  ECHO **************************************
  ECHO Invoking UAC for Privilege Escalation
  ECHO **************************************

  ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
  ECHO args = "ELEV " >> "%vbsGetPrivileges%"
  ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
  ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
  ECHO Next >> "%vbsGetPrivileges%"

  if '%cmdInvoke%'=='1' goto InvokeCmd 

  ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
  goto ExecElevation:InvokeCmd
  ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
  ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%":ExecElevation
 "%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
 exit /B:gotPrivileges
 setlocal & cd /d %~dp0 if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)

 ::::::::::::::::::::::::::::
 ::START ::::::::::::::::::::::::::::
 REM Run shell as admin (example) - put here code as you like
 ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
 cmd /k

脚本利用了这样一个事实NET FILE需要管理员特权和返回errorlevel 1如果你没有的话。通过创建一个重新启动批处理文件以获得特权的脚本来实现提升。这将导致Windows呈现UAC对话框,并向您询问管理员帐户和密码。

我已经用Windows 7,8,8.1,10和WindowsXP测试过它-它对所有人都很好。优点是,在起点之后,您可以放置任何需要系统管理员特权的东西,例如,如果您打算重新安装和重新运行Windows服务以进行调试(假设mypackage.msi是一个服务安装程序包):

msiexec /passive /x mypackage.msi
msiexec /passive /i mypackage.msi
net start myservice

如果没有这个权限提升脚本,UAC会向您询问三次管理员用户和密码-现在您只在开始时被问了一次,而且只有在需要时才会被问到。


如果您的脚本只需要显示错误消息,如果没有管理员权限,则退出而不是自动提升,这甚至更简单:您可以通过在脚本开头添加以下内容来实现这一点:

@ECHO OFF & CLS & ECHO.NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO You must right-click and select &
  ECHO "RUN AS ADMINISTRATOR"  to run this batch. Exiting... & ECHO. &
  PAUSE & EXIT /D)REM ... proceed here with admin rights ...

这样,用户必须右击并选择“以管理员身份运行”..之后,脚本将继续进行。REM语句,如果它检测到管理员权限,则使用错误退出。如果你不需要PAUSE把它移开。重要: NET FILE [...] EXIT /D)一定是在同一条线上。它显示在这里的多行,以更好的可读性!


在一些机器上,我遇到了一些问题,这些问题已经在上面的新版本中解决了。一个原因是不同的双引号处理,另一个问题是UAC在Windows 7机器上被禁用(设置为最低级别),因此脚本一次又一次地调用自己。

我现在已经修正了这个问题,方法是去掉路径中的引号,并在以后重新添加它们,我还添加了一个额外的参数,当脚本以更高的权限重新启动时,会添加一个额外的参数。

双引号由以下内容删除(详细信息如下这里):

setlocal DisableDelayedExpansionset "batchPath=%~0"setlocal EnableDelayedExpansion

然后,您可以使用!batchPath!..它不包含任何双引号,所以可以肯定地说"!batchPath!"稍后在剧本里。

线

if '%1'=='ELEV' (shift & goto gotPrivileges)

检查脚本是否已被VBScript脚本来提升权限,从而避免无休止的递归。它使用shift.


最新情况:

  • 以避免注册.vbs延展Windows 10,我已经换了线
    "%temp%\OEgetPrivileges.vbs" 
    通过
    "%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs" 
    在上面的脚本中;也添加了cd /d %~dp0正如stephen(单独回答)和tomášzato(注释)建议的那样,将脚本目录设置为默认目录。

  • 现在,脚本使用传递给它的命令行参数。感谢jxmallet,TanisDLJ和PeterMortensen的观察和启示。

  • 根据Artjom B.的提示,我分析了它,并替换了SHIFT通过SHIFT /1的文件名。%0参数

  • del "%temp%\OEgetPrivileges_%batchName%.vbs":gotPrivileges要清理的部分(如MLT建议)。加%batchName%如果并行运行不同的批处理,则避免影响。请注意,您需要使用for以便能够利用高级字符串函数,如%%~nk,它只提取文件名。

  • 优化脚本结构,改进(添加变量)vbsGetPrivileges它现在被引用到任何地方,允许很容易地更改文件的路径或名称,只需删除。.vbs如果需要提升批处理,请提交文件)

  • 在某些情况下,需要不同的调用语法来提升。如果脚本不工作,请检查以下参数:
    set cmdInvoke=0 
    set winSysFolder=System32 
    要么将第一个参数更改为set cmdInvoke=1看看这是否已经解决了问题。它会增加cmd.exe到执行高程的脚本。
    或尝试将第二个参数更改为winSysFolder=Sysnative,这在64位系统上可能有帮助(但在大多数情况下不是必需的)。(ADBailey报告了这一点)。“Sysnative”仅用于从32位脚本主机启动64位应用程序(例如VisualStudio构建进程,或从另一个32位应用程序中调用脚本)。

  • 为了更清楚地说明参数是如何解释的,我现在显示它如下P1=value1 P2=value2 ... P9=value9..如果需要将参数(如路径)括在双引号中,这尤其有用。"C:\Program Files".

有用的链接:


查看完整回答
反对 回复 2019-06-25
?
动漫人物

正如jcoder和Matt所提到的,PowerShell使其变得简单,甚至可以嵌入批处理脚本中,而无需创建新脚本。

我修改了马特的剧本:

:checkPrivileges 
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges 
) else ( powershell "saps -filepath %0 -verb runas" >nul 2>&1)
exit /b

没有任何必要:getPrivileges标签。


查看完整回答
反对 回复 2019-06-25

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信