web-dev-qa-db-fra.com

Comment demander un accès administrateur dans un fichier batch

J'essaie d'écrire un fichier de commandes pour que mes utilisateurs puissent s'exécuter à partir de leurs machines Vista avec UAC. Le fichier est en train de réécrire son fichier hosts, il doit donc être exécuté avec des autorisations d'administrateur. Je dois pouvoir leur envoyer un email avec un lien vers le fichier .bat. Le comportement souhaité est que, lorsqu'ils cliquent avec le bouton droit sur le fichier et disent Ouvrir, ils obtiennent l'une de ces boîtes de dialogue de contrôle de compte d'utilisateur qui éteint l'écran et les oblige à indiquer s'ils souhaitent autoriser l'application à s'exécuter en tant qu'administrateur. Au lieu de cela, ils voient juste "Accès refusé" dans la fenêtre de ligne de commande.

Est-ce possible de faire différemment?

160
skb

Ce script fait l'affaire! Il suffit de le coller dans le haut de votre fichier chauve-souris. Si vous souhaitez vérifier le résultat de votre script, ajoutez une commande "pause" au bas de votre fichier de commandes.

UPDATE: Ce script est maintenant légèrement modifié pour prendre en charge les arguments de ligne de commande et un système d’exploitation 64 bits.

Merci 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>
319
Ben Gripka

Voici un one-liner que j'ai utilisé:

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

echo main code here
pause

Remarques:

  • Testé uniquement sous Windows 7 et 10, vous devrez peut-être faire des calculs avec les citations.
  • Ne supporte pas la transmission d'arguments pour l'instant
39
toster-cx

Voici mon code! Ça a l'air gros mais c'est surtout des lignes de commentaires (les lignes commençant par: :).

Fonctionnalités:

  • Transmission complète des arguments
  • Ne change pas le dossier de travail
  • La gestion des erreurs
  • Accepte les chemins avec des parenthèses (sauf pour le dossier% TEMP%)
  • Prend en charge les chemins UNC
  • Vérification du dossier mappé (vous préviendrez si l'administrateur ne peut pas accéder au lecteur mappé)

  • Peut être utilisé comme une bibliothèque externe (consultez mon post à ce sujet: https://stackoverflow.com/a/30417025/493268 )

  • Peut être appelé quand/si besoin n'importe où dans votre code

Il suffit de joindre ceci à la fin de votre fichier de commandes ou de l'enregistrer en tant que bibliothèque (voir ci-dessus)

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

Exemple d'utilisation

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

Une autre approche consiste à

  • créer un raccourci localement et le définir pour qu'il demande l'autorisation de l'administrateur [Propriétés, Avancé, Exécuter en tant qu'administrateur]

puis

  • envoyez à vos utilisateurs le raccourci [ou un lien vers le raccourci plutôt qu'un vers le fichier de commandes lui-même].

Denis

[Ajouté après - Oui, j'ai omis de noter la date de ce fil.]

7
Tryx3

La solution de Ben Gripka provoque des boucles infinies. Son lot fonctionne comme ceci (pseudo code):

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

Comme vous pouvez le constater, cela provoque une boucle infinie si VBS échoue à demander les privilèges d’administrateur.

Cependant, la boucle infinie peut se produire, bien que les privilèges d'administrateur aient été demandés avec succès.

La vérification dans le fichier de commandes de Ben Gripka est sujette aux erreurs. J'ai joué avec le lot et ai observé que les privilèges d'administrateur sont disponibles bien que la vérification ait échoué. Fait intéressant, la vérification a fonctionné comme prévu si j'ai démarré le fichier de commandes à partir de Windows Explorer, mais ce n'était pas le cas lorsque je l'ai démarré à partir de mon IDE.

Je suggère donc d'utiliser deux fichiers de commandes distincts. Le premier génère le VBS qui appelle le deuxième fichier batch:

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

La seconde, nommée "my_commands.bat" et située dans le même répertoire que la première contient vos commandes réelles:

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

Cela ne provoque pas de boucles infinies et supprime également la vérification des privilèges d'administration sujette aux erreurs.

5
fishbone

Je sais que ce n'est pas une solution pour OP, mais comme je suis sûr qu'il y a beaucoup d'autres cas d'utilisation ici, j'ai pensé partager.

J'ai eu des problèmes avec tous les exemples de code dans ces réponses mais ensuite j'ai trouvé: http://www.robotronic.de/runasspcEn.html

Cela vous permet non seulement de vous lancer en tant qu'administrateur, mais aussi de vérifier le fichier pour vous assurer qu'il n'a pas été falsifié et de stocker les informations nécessaires en toute sécurité. J'admets que ce n'est pas l'outil le plus évident pour comprendre comment utiliser, mais pour ceux d'entre nous qui écrivons du code, cela devrait être assez simple.

4
trex005

@echo off et title peuvent précéder ce code:

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

Beaucoup d'autres réponses sont exagérées si vous n'avez pas à vous soucier de ce qui suit:

  • Paramètres
  • Répertoire de travail (cd %~dp0 passera au répertoire contenant le fichier de traitement par lots)
3
FluorescentGreen5

Comme j'ai des problèmes avec ce script pour faire apparaître une nouvelle commande, l'invite de commande s'exécutant à nouveau, en boucle infinie (avec Win 7 Pro), je vous suggère d'essayer une autre approche: Comment puis-je élever automatiquement mon fichier de traitement par lots, demande les droits d’administrateur UAC si nécessaire?

Attention, vous devez ajouter ceci à la fin du script, comme indiqué dans une modification, afin de revenir au répertoire du script une fois les privilèges élevés: cd/d% ~ dp0

1
barbara.post

Basé sur le post de toster-cx et d'autres posts intéressants sur cette page, j'ai eu un aperçu de la façon de configurer et de résoudre mon problème. J'ai eu un problème similaire où je souhaitais que l'utilitaire de nettoyage de disque s'exécute chaque semaine deux fois le lundi et le jeudi à l'heure du déjeuner (par exemple, à 14 heures). Cependant, cela nécessitait des droits élevés.

Partager un fichier batch qui pourrait aider d’autres débutants comme moi -

@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

Merci beaucoup pour ce forum et Rems POST ici [ https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need -to-pass-parameters-to-script] [1]

Son message a aidé à configurer un argument optionnel lors de la planification de la tâche.

1
Anand

Vous ne pouvez pas demander les droits d'administrateur à partir d'un fichier de commandes, mais vous pouvez écrire un script d'hôte de script Windows dans% temp% et l'exécuter (ce qui exécute ensuite votre lot en tant qu'administrateur). Vous souhaitez appeler la méthode ShellExecute dans le shell. Objet d'application avec "runas" comme verbe

0
Anders