So fordern Sie den Administratorzugriff in einer Batchdatei an


177

Ich versuche, eine Batchdatei zu schreiben, die meine Benutzer von ihren Vista-Computern mit UAC ausführen können. Die Datei schreibt ihre Hosts-Datei neu, daher muss sie mit Administratorrechten ausgeführt werden. Ich muss in der Lage sein, ihnen eine E-Mail mit einem Link zur .bat-Datei zu senden. Das gewünschte Verhalten ist, dass sie, wenn sie mit der rechten Maustaste auf die Datei klicken und Öffnen sagen, eines dieser UAC-Dialogfelder erhalten, das den Bildschirm dunkel macht und sie zwingt zu antworten, ob sie der Anwendung die Berechtigung zum Ausführen als Administrator erteilen möchten. Stattdessen wird im Befehlszeilenfenster nur "Zugriff verweigert" angezeigt.

Ist das anders möglich?


2
Wenn Sie darauf gestoßen sind und wie ich mit PowerShell zufrieden sind, sollten Sie den Einzeiler von @ toster-cx nicht verpassen. Perfekt!
Michael Repucci

Antworten:


350

Dieses Skript macht den Trick! Fügen Sie es einfach oben in Ihre Fledermausdatei ein. Wenn Sie die Ausgabe Ihres Skripts überprüfen möchten, fügen Sie am Ende Ihrer Batchdatei einen Befehl "Pause" hinzu.

UPDATE: Dieses Skript wurde jetzt leicht bearbeitet, um Befehlszeilenargumente und ein 64-Bit-Betriebssystem zu unterstützen.

Vielen Dank, dass Sie 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>

21
Ich hasse es, diesen dreckigen Dos-Batch-Unsinn machen zu müssen, aber manchmal bist du dazu gezwungen und das funktioniert großartig. Prost!
Matt brennt

4
Diese Methode leitet keine Argumente weiter. Wissen Sie, wie das geht? Grundsätzlich beobachte ich, dass% 1 in der ersten Zeile einen Wert hat und in der letzten Zeile% 1 null ist. Ich muss die Argumente weiterleiten.
Zinken

3
Nur als FYI wird dies als funktionierend in Windows 8 Embedded getestet
Robert Snyder

6
Dies wirft meine Maschine in eine Spirale von Befehlsfenstern, die sich diagonal über den Bildschirm öffnen und schließen. Die einzige Möglichkeit, dies zu stoppen, besteht darin, die ursprüngliche Batchdatei zu löschen. Es wird wiederholt meine Batch-Datei ausgeführt und die VBS-Datei geschrieben. Beim ersten Mal wurde um Autorisierung gebeten, danach wird nur noch eine Schleife ausgeführt.
TomDestry

2
Ich hatte genau das gleiche Problem wie TomDestry mit der Endlosschleife und dem Rückkehrcode 2. Dies war unter Windows 8.1. Ich weiß, dass es unter Windows 8.0 funktioniert hat, und kann nicht sicher sagen, ob es das 8.1-Update oder etwas anderes war, das das Problem verursacht hat. Die Lösung, die für mich funktioniert hat, war, nicht cacls.exe (oder icacls) zu verwenden, sondern: net session> nul 2> & 1 IF ERRORLEVEL 1 gehe zu UACPrompt ...
crig

55

Hier ist ein Einzeiler, den ich verwendet habe:

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

echo main code here
pause

Anmerkungen:

  • Nur unter Windows 7 und 10 getestet, müssen Sie möglicherweise mit dem Zitat herumspielen
  • Unterstützt vorerst keine Weitergabe von Argumenten

1
Wenn Sie wissen, wie viele Parameter es geben könnte, können Sie Parameter übergeben, indem Sie sie nach einschließen. am_admin if not "%1"=="am_admin" (powershell start -verb runas '%0' 'am_admin "%~1" "%~2"' & exit)Die Parameter befinden sich über dem Ort, an dem sie sich befanden
Tony Brix,

Auch möglich, 'am_admin %*'um alles zu übergeben, spielt nicht gut mit Anführungszeichen und Leerzeichen tho: / Sie können shiftim Stapel verwenden, um das erste Argument zu entfernen, wodurch alle Argumente außer behoben werden %0.
Toster-CX

Dies ist eine gute Antwort, sollte aber nicht akzeptiert werden, da NICHT geprüft wird, ob sie beim ERSTEN Ausführen mit ADMIN-Berechtigung ausgeführt wurde oder nicht.
T.Todua

Um das Arbeitsverzeichnis zu behalten, fügen Sie cd /D %~dp0nachif not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
Pedro Duarte

Gute Antwort. Funktioniert einfach, während das VB-Skript eine Endlosschleife erstellt, auch mit Schreibberechtigung für% temp%.
Twonky

19

Hier ist mein Code! Es sieht groß aus, aber es sind meistens Kommentarzeilen (die Zeilen beginnen mit: :).

Eigenschaften:

  • Vollständige Argumentweiterleitung
  • Ändert den Arbeitsordner nicht
  • Fehlerbehandlung
  • Akzeptiert Pfade in Klammern (außer im Ordner% TEMP%)
  • Unterstützt UNC-Pfade
  • Überprüfung des zugeordneten Ordners (Warnt Sie, wenn der Administrator nicht auf das zugeordnete Laufwerk zugreifen kann)

  • Kann als externe Bibliothek verwendet werden (siehe meinen Beitrag zu diesem Thema: https://stackoverflow.com/a/30417025/4932683 )

  • Kann bei Bedarf überall in Ihrem Code aufgerufen werden

Hängen Sie dies einfach an das Ende Ihrer Batch-Datei an oder speichern Sie es als Bibliothek (siehe oben).

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

Beispiel zur Verwendung

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

Funktioniert super, aber ich musste eine Zeile ändern, damit sie funktioniert. Das &fc;: 2>nulIn hat set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)den Fehlerlevel auf 1 gesetzt. Ich habe das Bit entfernt und es hat perfekt funktioniert. Ich verwende Windows 10 Home.
Knyri

Hat Ihr% temp% -Ordner Klammern im Pfad? Nur in diesem Fall soll die Fehlerstufe 1 eingestellt werden.
Cyberponk

Nee. Braucht es das fc;:da es geht: eof gleich danach? Ich bin mir nicht sicher, warum dieses kleine Problem das Problem verursacht hat, da es ausgeführt werden sollte.
Knyri

"fc;: 2> nul" dient absichtlich dazu, ERRORLEVEL 1 vor dem Beenden einzustellen, um einen Fehler zu signalisieren. Könnten Sie bitte das @echo entfernen und einen Lauf machen und mir die Ausgabe in einer privaten Nachricht senden? Vielen Dank!
Cyberponk

Wie auch immer, die echo/%TEMP%| findstr /C:"(" >nulTests, ob es ein (Zeichen in Ihrer %temp%Umgebungsvariablen gibt, und sollten den Teil erst nach dem &&Wenn positiv ausführen . Es ist seltsam, warum Ihr (Test positiv ausfällt.
Cyberponk

7

Ein anderer Ansatz ist zu

  • Erstellen Sie lokal eine Verknüpfung und stellen Sie diese so ein, dass die Administratorberechtigung aufgerufen wird. [Eigenschaften, Erweitert, Als Administrator ausführen]

und dann

  • Senden Sie Ihren Benutzern die Verknüpfung [oder einen Link zur Verknüpfung anstelle einer Verknüpfung zur Batchdatei selbst].

Denis

[Nachträglich hinzugefügt - Ja, ich habe das Datum dieses Threads nicht bemerkt.]


6

Die Lösung von Ben Gripka verursacht Endlosschleifen. Sein Batch funktioniert folgendermaßen (Pseudocode):

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

Wie Sie sehen können, führt dies zu einer Endlosschleife, wenn der VBS keine Administratorrechte anfordert.

Die Endlosschleife kann jedoch auftreten, obwohl Administratorrechte erfolgreich angefordert wurden.

Die Überprüfung in der Batch-Datei von Ben Gripka ist nur fehleranfällig. Ich habe mit dem Stapel herumgespielt und festgestellt, dass Administratorrechte verfügbar sind, obwohl die Prüfung fehlgeschlagen ist. Interessanterweise funktionierte die Überprüfung wie erwartet, wenn ich die Batchdatei über den Windows Explorer startete, aber nicht, als ich sie über meine IDE startete.

Daher schlage ich vor, zwei separate Batch-Dateien zu verwenden. Der erste generiert den VBS, der die zweite Batchdatei aufruft:

@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"

Die zweite mit dem Namen "my_commands.bat" befindet sich im selben Verzeichnis wie die erste und enthält Ihre eigentlichen Befehle:

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

Dies verursacht keine Endlosschleifen und entfernt auch die fehleranfällige Administratorberechtigungsprüfung.


Für dich gearbeitet? Leider scheitern dies und alle anderen hier und aus dem anderen Thread an demselben zugrunde liegenden Problem. Der Parameter "runas" (oder Befehl) schlägt fehl, wenn das Shell-Objekt indirekt aus einem anderen Programm heraus erstellt wird. Interessantes Thema hier .
Laurie Stearn

Arbeitete für mich :)
Sritam Jagadev

6

Eine weitere PowerShell-Lösung ...

Hier geht es nicht darum, ein Batch-Skript als Administrator auszuführen, sondern darum, wie ein anderes Programm aus dem Batch ...

Ich habe eine Batch-Datei "Wrapper" für eine Exe. Sie haben den gleichen "Root-Dateinamen", aber alternative Erweiterungen. Ich kann die Exe als Administrator starten und das Arbeitsverzeichnis mit dem folgenden einzeiligen Powershell-Aufruf auf das Verzeichnis einstellen, das das Skript enthält:

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

Mehr Info

Es gibt eine ganze Reihe zusätzlicher Start-ProcessOptionen, die Sie anwenden können! Überprüfen Sie: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6

Beachten Sie, dass ich das @Präfix verwende. Das entspricht @echo offder einen Zeile. Ich benutze %~n0hier, um den " .exeStammnamen " des Batch-Skripts zu erhalten, dann verkette ich den , um darauf die benachbarte Binärdatei zu verweisen. Die Verwendung von %~dp0stellt den vollständigen Pfad zu dem Verzeichnis bereit, in dem sich der Stapel befindet. Und natürlich, das -Verb RunAsbietet Parameter die Höhe .


4

Ich weiß, dass dies keine Lösung für OP ist, aber da ich sicher bin, dass es hier viele andere Anwendungsfälle gibt, dachte ich, ich würde sie teilen.

Ich hatte Probleme mit allen Codebeispielen in diesen Antworten, fand dann aber: http://www.robotronic.de/runasspcEn.html

Sie können nicht nur als Administrator ausgeführt werden, sondern auch die Datei überprüfen, um sicherzustellen, dass sie nicht manipuliert wurde, und die erforderlichen Informationen sicher speichern. Ich gebe zu, es ist nicht das naheliegendste Werkzeug, um herauszufinden, wie man es benutzt, aber für diejenigen von uns, die Code schreiben, sollte es einfach genug sein.


3

@echo offund titlekann vor diesem Code kommen:

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

Viele der anderen Antworten sind übertrieben, wenn Sie sich nicht um Folgendes kümmern müssen:

  • Parameter
  • Arbeitsverzeichnis ( cd %~dp0wechselt in das Verzeichnis mit der Batchdatei)

1

Da ich Probleme mit diesem Skript habe, eine neue Eingabeaufforderung aufzurufen, die in einer Endlosschleife (mit Win 7 Pro) erneut ausgeführt wird, empfehle ich Ihnen, einen anderen Ansatz zu versuchen: Wie kann ich meine Batch-Datei automatisch erhöhen, damit sie von angefordert wird? UAC-Administratorrechte bei Bedarf?

Seien Sie vorsichtig, Sie müssen dies am Ende des Skripts hinzufügen, wie in einer Bearbeitung angegeben, damit Sie nach dem Erhöhen der Berechtigungen wieder im Skriptverzeichnis sind: cd / d% ~ dp0


Überprüfen Sie meine Antwort auf diese Frage. Es behandelt all diese Probleme.
Cyberponk

1

Basierend auf dem Beitrag von toster-cx und anderen interessanten Beiträgen auf dieser Seite erhielt ich einen Einblick in die Konfiguration und Lösung meines Problems. Ich hatte ein ähnliches Problem, bei dem ich mir wünschte, dass das Dienstprogramm zur Datenträgerbereinigung jede Woche zweimal am Montag und Donnerstag während der Mittagspause (z. B. 14 Uhr) ausgeführt wird. Dies erforderte jedoch erhöhte Rechte.

Batch-Datei teilen, die anderen Anfängern wie mir helfen könnte -

@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

Vielen Dank für dieses Forum und Rems POST hier [ https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need-to-pass-parameters-to-script ] [1]

Sein Beitrag half beim Konfigurieren optionaler Argumente beim Planen der Aufgabe.


1

Es gibt auch die FSUTIL-Abfrage aus diesem Beitrag, die ebenfalls auf ss64.com verlinkt ist und den folgenden Code enthält:

@Echo Off
Setlocal
:: First check if we are running As Admin/Elevated
FSUTIL dirty query %SystemDrive% >nul
if %errorlevel% EQU 0 goto START

::Create and run a temporary VBScript to elevate this batch file
   Set _batchFile=%~f0
   Set _Args=%*
   :: double up any quotes
   Set _batchFile=""%_batchFile:"=%""
   Set _Args=%_Args:"=""%

   Echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\~ElevateMe.vbs"
   Echo UAC.ShellExecute "cmd", "/c ""%_batchFile% %_Args%""", "", "runas", 1 >> "%temp%\~ElevateMe.vbs"

   cscript "%temp%\~ElevateMe.vbs" 
   Exit /B

:START
:: set the current directory to the batch file location
cd /d %~dp0
:: Place the code which requires Admin/elevation below
Echo We are now running as admin [%1] [%2]
pause

Solange FSUTIL verfügbar ist, ist es eine zuverlässige Alternative.


1
@echo off 
Net session >nul 2>&1 || (PowerShell start -verb runas '%~0' &exit /b)
Echo Administrative privileges have been got. & pause

Das obige funktioniert auf meinem Windows 10 Version 1903


0

Sie können keine Administratorrechte aus einer Batchdatei anfordern, aber Sie können ein Windows-Skript-Hostskript in% temp% schreiben und ausführen (und das wiederum Ihren Batch als Administrator ausführen). Sie möchten die ShellExecute-Methode in der Shell aufrufen. Anwendungsobjekt mit "Runas" als Verb


0

Verwenden Sie mshtadiese Option, um nach Administratorrechten zu fragen:

@echo off
net session >nul 2>&1 && goto :admintasks
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
exit /b
:admintasks
rem ADMIN TASKS HERE

Oder mit Powershell:

powershell -c Start-Process "%~nx0" -Verb runas

-5

Verwenden Sie den Befehl runas. Ich glaube jedoch nicht, dass Sie eine .bat-Datei einfach per E-Mail versenden können.


6
Diese Antwort ist falsch. Der runasBefehl kann nicht verwendet werden, um eine Höhe zu provozieren.
Bill_Stewart
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.