如何在batch file中请求pipe理员访问权限

我正在尝试为我的用户编写一个batch file,以从UAC的Vista计算机运行。 该文件正在重写他们的主机文件,因此需要使用pipe理员权限运行。 我需要能够发送一个电子邮件与链接到.bat文件。 所需的行为是,当他们右键单击文件并打开,他们将得到其中一个UAC对话框,使屏幕变暗,并强制他们回答是否要授予应用程序权限以pipe理员身份运行。 相反,他们只是在命令行窗口中看到“拒绝访问”。

这可能做不同吗?

这个脚本有窍门! 只需将其粘贴到您的bat文件的顶部。 如果要查看脚本的输出,请在batch file的底部添加一个“暂停”命令。

更新:现在稍微编辑此脚本以支持命令行参数和64位操作系统。

谢谢Eneerge @ https://sites.google.com/site/eneerge/scripts/batchgotadmin

@echo off :: BatchGotAdmin :------------------------------------- REM --> Check for permissions IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" ( >nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system" ) ELSE ( >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" ) REM --> If error flag set, we do not have admin. if '%errorlevel%' NEQ '0' ( echo Requesting administrative privileges... goto UACPrompt ) else ( goto gotAdmin ) :UACPrompt echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" set params=%* echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs" "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" exit /B :gotAdmin pushd "%CD%" CD /D "%~dp0" :-------------------------------------- <YOUR BATCH SCRIPT HERE> 

这是我的代码! 它看起来很大,但大多是注释行(以下面的行开头:)。

特征:

  • 全参数转发
  • 不改变工作文件夹
  • error handling
  • 接受带括号的path(%TEMP%文件夹除外)
  • 支持UNCpath
  • 映射的文件夹检查(如果pipe理员无法访问映射驱动器,则发出警告)

  • 可以用作外部库(查看我的post在这个主题: https : //stackoverflow.com/a/30417025/4932683 )

  • 可以在代码中的任何位置调用

只需将其附加到batch file的末尾,或者将其另存为一个库(如上所述)

 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :RequestAdminElevation FilePath %* || goto:eof :: :: By: Cyberponk, v1.5 - 10/06/2016 - Changed the admin rights test method from cacls to fltmc :: v1.4 - 17/05/2016 - Added instructions for arguments with ! char :: v1.3 - 01/08/2015 - Fixed not returning to original folder after elevation successful :: v1.2 - 30/07/2015 - Added error message when running from mapped drive :: v1.1 - 01/06/2015 :: :: Func: opens an admin elevation prompt. If elevated, runs everything after the function call, with elevated rights. :: Returns: -1 if elevation was requested :: 0 if elevation was successful :: 1 if an error occured :: :: USAGE: :: If function is copied to a batch file: :: call :RequestAdminElevation "%~dpf0" %* || goto:eof :: :: If called as an external library (from a separate batch file): :: set "_DeleteOnExit=0" on Options :: (call :RequestAdminElevation "%~dpf0" %* || goto:eof) && CD /D %CD% :: :: If called from inside another CALL, you must set "_ThisFile=%~dpf0" at the beginning of the file :: call :RequestAdminElevation "%_ThisFile%" %* || goto:eof :: :: If you need to use the ! char in the arguments, the calling must be done like this, and afterwards you must use %args% to get the correct arguments: :: set "args=%* " :: call :RequestAdminElevation ..... use one of the above but replace the %* with %args:!={a)% :: set "args=%args:{a)=!%" ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: setlocal ENABLEDELAYEDEXPANSION & set "_FilePath=%~1" if NOT EXIST "!_FilePath!" (echo/Read RequestAdminElevation usage information) :: UAC.ShellExecute only works with 8.3 filename, so use %~s1 set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof) :: Remove parenthesis from the temp filename set _FN=%_FN:(=% set _vbspath="%temp:~%\%_FN:)=%.vbs" & set "_batpath=%temp:~%\%_FN:)=%.bat" :: Test if we gave admin rights fltmc >nul 2>&1 || goto :_getElevation :: Elevation successful (if exist %_vbspath% ( del %_vbspath% )) & (if exist %_batpath% ( del %_batpath% )) :: Set ERRORLEVEL 0, set original folder and exit endlocal & CD /D "%~dp1" & ver >nul & goto:eof :_getElevation echo/Requesting elevation... :: Try to create %_vbspath% file. If failed, exit with ERRORLEVEL 1 echo/Set UAC = CreateObject^("Shell.Application"^) > %_vbspath% || (echo/&echo/Unable to create %_vbspath% & endlocal &md; 2>nul &goto:eof) echo/UAC.ShellExecute "%_batpath%", "", "", "runas", 1 >> %_vbspath% & echo/wscript.Quit(1)>> %_vbspath% :: Try to create %_batpath% file. If failed, exit with ERRORLEVEL 1 echo/@%* > "%_batpath%" || (echo/&echo/Unable to create %_batpath% & endlocal &md; 2>nul &goto:eof) echo/@if %%errorlevel%%==9009 (echo/^&echo/Admin user could not read the batch file. If running from a mapped drive or UNC path, check if Admin user can read it.)^&echo/^& @if %%errorlevel%% NEQ 0 pause >> "%_batpath%" :: Run %_vbspath%, that calls %_batpath%, that calls the original file %_vbspath% && (echo/&echo/Failed to run VBscript %_vbspath% &endlocal &md; 2>nul & goto:eof) :: Vbscript has been run, exit with ERRORLEVEL -1 echo/&echo/Elevation was requested on a new CMD window &endlocal &fc;: 2>nul & goto:eof ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 

如何使用它的例子

 :EXAMPLE @echo off :: Run this script with elevation call :RequestAdminElevation "%~dpfs0" %* || goto:eof echo/I now have Admin rights! echo/ echo/Arguments using %%args%%: %args% echo/Arguments using %%*: %* echo/%%1= %~1 echo/%%2= %~2 echo/%%3= %~3 echo/ echo/Current Directory: %CD% echo/ echo/This file: %0 echo/ pause &goto:eof [here you paste the RequestAdminElevation function code] 

以下是我一直在使用的一行代码:

 @echo off if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit) echo main code here pause 

笔记:

  • 只有在Windows 10上testing过,你可能不得不乱用引用
  • 现在不支持传递参数

我知道这不是OP的解决scheme,但是由于我确信在这里有很多其他的用例,我想我会分享。

我在这些答案中的所有代码示例都有问题,但后来我发现: http : //www.robotronic.de/runasspcEn.html

它不仅可以让你以pipe理员身份运行,而且可以检查文件以确保它没有被篡改,并安全地存储所需的信息。 我承认这不是找出如何使用的最明显的工具,但是对于我们这些编写代码来说应该很简单。

本·格里普卡的解决scheme导致无限循环。 他的批处理像这样(伪代码):

 IF "no admin privileges?" "write a VBS that calls this batch with admin privileges" ELSE "execute actual commands that require admin privileges" 

如您所见,如果VBS失败请求pipe理员权限,则会导致无限循环。

但是,无限循环可能会发生,虽然pipe理员的特权已被请求成功。

Ben Gripka的batch file中的检查只是容易出错。 我玩了批处理,并观察到pipe理员权限可用,虽然检查失败。 有趣的是,如果我从Windows资源pipe理器启动了batch file,检查工作就像预期的那样,但是从我的IDE启动时没有这样做。

所以我build议使用两个单独的batch file。 第一个生成调用第二个batch file的VBS:

 @echo off echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" set params = %*:"="" echo UAC.ShellExecute "cmd.exe", "/c ""%~dp0\my_commands.bat"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" 

第二个命名为“my_commands.bat”,位于与第一个相同的目录中,包含您的实际命令:

 pushd "%CD%" CD /D "%~dp0" REM Your commands which require admin privileges here 

这不会导致无限循环,也会消除易错的pipe理权限检查。

由于这个脚本popup一个新的命令提示符,本身再次运行,在无限循环(使用Win 7 Pro),我build议你尝试另一种方法麻烦: 我如何自动提升我的batch file,以便它要求UACpipe理员权限,如果需要?

请注意,您必须在脚本末尾添加此项(如编辑中所述),以便在权限提升后回到脚本目录:cd / d%〜dp0

另一种方法是

  • 在本地创build快捷方式并将其设置为调用pipe理员权限[属性,高级,以pipe理员身份运行]

接着

  • 向用户发送快捷方式[或指向快捷方式的链接,而不是batch file本身]。

丹尼斯

[之后添加 – 是的,我没有注意到这个线程的date。]

您不能从batch file请求pipe理权限,但是您可以在%temp%中编写一个Windows脚本主机脚本,然后运行该脚本(并以pipe理员身份执行您的批处理)您要调用Shell中的ShellExecute方法。以“runas”作为动词的应用程序对象

使用runas命令。 但是,我不认为你可以轻松地发送一个.bat文件。