首页 文章

如何在批处理文件中请求管理员访问权限

提问于
浏览
149

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

这可能有不同的做法吗?

11 回答

  • 18

    这个脚本可以解决问题!只需将其粘贴到bat文件的顶部即可 . 如果要查看脚本的输出,请在批处理文件的底部添加“暂停”命令 .

    更新:此脚本现在稍微编辑,以支持命令行参数和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>
    
  • 1

    这是我一直在使用的单线程:

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

    笔记:

    • 仅在Windows 7和10上进行了测试,您可能不得不搞乱报价

    • 暂时不支持传递参数

  • 296

    这是我的代码!它看起来很大但主要是注释行(以:)开头的行 .

    特征:

    • 完整参数转发

    • 不更改工作文件夹

    • 错误处理

    • 接受带括号的路径(%TEMP%文件夹除外)

    • 支持UNC路径

    • 映射文件夹检查(如果管理员无法访问映射驱动器,请警告您)

    • 可以用作外部库(请查看此主题的帖子:https://stackoverflow.com/a/30417025/4932683

    • 可以在代码中的任何位置/需要时调用

    Just attach this to the end of your batch file, or save it as a library (check above)

    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :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 on how to use it

    :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]
    
  • 1

    另一种方法是

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

    然后

    • 向用户发送快捷方式[或快捷方式的链接,而不是批处理文件本身的链接] .

    丹尼斯

    [后来添加 - 是的,我确实没有注意到这个帖子的日期 . ]

  • 35

    Ben Gripka的解决方案导致无限循环 . 他的批处理就像这样(伪代码):

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

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

    However, the infinite loop can occur, although admin priviliges have been requested successfully.

    检查Ben Gripka的批处理文件只是容易出错 . 我玩了批处理并观察到虽然检查失败,但管理员权限可用 . 有趣的是,如果我从Windows资源管理器启动批处理文件,检查按预期工作,但是当我从IDE启动它时它没有 .

    所以我建议使用两个单独的批处理文件 . 第一个生成调用第二个批处理文件的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
    

    这不会导致无限循环,也会删除容易出错的管理员权限检查 .

  • 0

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

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

    它不仅允许您以管理员身份运行,还会检查文件以确保其未被篡改并安全地存储所需信息 . 我承认这不是最明显的工具来弄清楚如何使用,但对于我们这些编写代码的人来说应该很简单 .

  • 2

    @echo offtitle 可以在此代码之前:

    net session>nul 2>&1
    if %errorlevel%==0 goto main
    echo CreateObject("Shell.Application").ShellExecute "%~f0", "", "", "runas">"%temp%/elevate.vbs"
    "%temp%/elevate.vbs"
    del "%temp%/elevate.vbs"
    exit
    
    :main
        <code goes here>
    exit
    

    如果您不需要担心以下问题,很多其他答案都是矫枉过正的:

    • 参数

    • 工作目录( cd %~dp0 将更改为包含批处理文件的目录)

  • 5

    由于我遇到麻烦,这个脚本弹出一个新的命令提示符,它自己再次运行,在无限循环中(使用Win 7 Pro),我建议你尝试另一种方法:How can I auto-elevate my batch file, so that it requests from UAC administrator rights if required?

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

  • 4

    根据toster-cx的帖子和本页上的其他有趣帖子,我深入了解了如何配置和解决我的问题 . 我有类似的问题,我希望Disk Cleanup实用程序在周一和周四的午餐时间(比如下午2点)每周运行两次 . 但是,这需要提升权利 .

    共享批处理文件可能会帮助像我这样的其他初学者 -

    @echo off
    echo  Welcome to scheduling 'PC Maintenance Activity'
    ping localhost -n 3 >nul
    echo -- Step - 1 of 3 : Please give 'Admin' rights on next screen
    ping localhost -n 5 >nul
    if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit)
    cls
    echo -- Step - 2 of 3 : In next screen, select temp areas for cleaning 
    during routine scheduled activity
    ping localhost -n 3 >nul
    C:\Windows\System32\cleanmgr.exe /sageset:112
    cls
    echo    Now scheduling maintenance activity...
    SchTasks /Create /SC WEEKLY /D MON,THU /TN PC_Cleanup /TR 
    "C:\Windows\System32\cleanmgr.exe "/sagerun:112 /ST 14:00
    
    cls
    
    echo                         -- Thanks for your co-operation --
    echo                    -- Maintenance activity is scheduled for --
    echo                       -- Every Monday and Thursday at 2 pm --
    
    ping localhost -n 10 >nul
    

    非常感谢这个论坛和Rems POST在这里[https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need-to-pass-parameters-to-script][1]

    他的帖子在调度任务时帮助配置了可选参数 .

  • 6

    您无法从批处理文件中请求管理员权限,但您可以在%temp%中编写Windows脚本主机脚本并运行该脚本(然后以管理员身份执行批处理)您希望在命令行管理程序中调用ShellExecute方法 . 以“runas”作为动词的应用程序对象

  • -2

    使用runas命令 . 但是,我认为您不能轻易地通过电子邮件发送.bat文件 .

相关问题