I am trying to write a batch file for my users to run from their Vista machines with UAC. The file is re-writing their hosts file, so it needs to be run with Administrator permissions. I need to be able to send them an email with a link to the .bat file. The desired behavior is that when they right-click on the file and say Open, they will get one of those UAC dialogs that makes the screen go dark and forces them to answer whether they want to give the application permission to run as administrator. Instead, they are just seeing "Access denied" on the command line window.

有可能采取不同的做法吗?


当前回答

我知道这不是OP的解决方案,但是因为我确信这里还有许多其他用例,所以我想分享一下。

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

它不仅允许您以管理员身份运行,还可以检查文件以确保它没有被篡改,并安全地存储所需的信息。我承认它不是最明显的工具,但对于我们这些编写代码的人来说,它应该足够简单。

其他回答

我知道这不是OP的解决方案,但是因为我确信这里还有许多其他用例,所以我想分享一下。

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

它不仅允许您以管理员身份运行,还可以检查文件以确保它没有被篡改,并安全地存储所需的信息。我承认它不是最明显的工具,但对于我们这些编写代码的人来说,它应该足够简单。

基于toster-cx的帖子和本页上其他有趣的帖子,我对如何配置和解决我的问题有了深入的了解。我也遇到过类似的问题,我希望磁盘清理工具每周在周一和周四的午餐时间(比如下午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]

他的帖子有助于在调度任务时配置可选参数。

另一个PowerShell解决方案…

这不是关于作为管理员运行批处理脚本,而是如何从批处理提升另一个程序…

我有一个批处理文件“包装”的exe。它们具有相同的“根文件名”,但扩展名不同。我能够启动exe作为管理员,并将工作目录设置为一个包含脚本,与以下一行powershell调用:

@powershell "Start-Process -FilePath '%~n0.exe' -WorkingDirectory '%~dp0' -Verb RunAs"

更多信息

还有一大堆额外的Start-Process选项,你也可以申请!查看:https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6

注意,我使用了@前缀。这相当于一行的@echo off。我在这里使用%~n0来获得批处理脚本的“根名称”,然后连接.exe以指向相邻的二进制文件。%~dp0的使用提供了批处理所在目录的完整路径。当然,-Verb RunAs参数提供抬高。

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

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

特点:

全参数转发 不更改工作文件夹 错误处理 接受带圆括号的路径(%TEMP%文件夹除外) 支持UNC路径 映射文件夹检查(警告你如果管理员不能访问映射驱动器) 可以用作外部库(查看我在这个主题的帖子:https://stackoverflow.com/a/30417025/4932683) 可以调用时/如果需要在您的代码中的任何地方

只需将其附加到批处理文件的末尾,或将其保存为库(如上所示)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: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 have 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]