Comment puis-je élever automatiquement mon fichier de commandes pour qu'il demande des droits d'administrateur UAC si nécessaire?

209

Je souhaite que mon fichier de commandes s'exécute uniquement en mode élevé. S'il n'est pas élevé, fournissez une option permettant à l'utilisateur de relancer le lot comme élevé.

J'écris un fichier batch pour définir une variable système, copier deux fichiers vers un emplacement Program Files et démarrer un programme d'installation de pilote. Si un utilisateur Windows 7 / Windows Vista ( UAC activé et même s'il est un administrateur local) l'exécute sans cliquer avec le bouton droit et sélectionner "Exécuter en tant qu'administrateur", il obtiendra "Accès refusé" en copiant les deux fichiers et en écrivant la variable système .

Je voudrais utiliser une commande pour redémarrer automatiquement le lot comme élevé si l'utilisateur est en fait un administrateur. Sinon, s'ils ne sont pas administrateurs, je veux leur dire qu'ils ont besoin de privilèges d'administrateur pour exécuter le fichier de commandes. J'utilise xcopy pour copier les fichiers et REG ADD pour écrire la variable système. J'utilise ces commandes pour gérer d'éventuelles machines Windows XP. J'ai trouvé des questions similaires sur ce sujet, mais rien qui traite de la relance d'un fichier batch comme élevé.

PDixon724
la source
2
Vérifiez ce que j'ai publié - vous n'avez besoin d'aucun outil externe, le script vérifie automatiquement les droits d'administrateur et s'auto-élève si nécessaire.
Matt
1
Veuillez considérer si la réponse de Matt serait cochée? Cela me semble ainsi.
akauppi
Veuillez considérer les nouveaux conseils Windows 10 dans la section commentaires du script de commandes que j'ai publié.
Matt
4
De cmd: @powershell Start-Process cmd -Verb runas. De Powershell, laissez tomber @powershell. Cela démarre cmd avec des droits élevés.
BrunoLM

Réponses:

20

Vous pouvez demander au script de s'appeler lui-même avec l' option de psexec-h pour s'exécuter avec élévation.

Je ne sais pas comment vous pourriez détecter s'il fonctionne déjà avec ou sans élévation ... peut-être réessayer avec des autorisations élevées uniquement s'il y a une erreur d'accès refusé?

Ou, vous pourriez simplement avoir les commandes pour le xcopyet reg.exetoujours être exécuté avec psexec -h, mais ce serait ennuyeux pour l'utilisateur final s'il doit entrer son mot de passe à chaque fois (ou peu sûr si vous avez inclus le mot de passe dans le script) ...

ewall
la source
10
Merci pour la réponse. Malheureusement, je ne pense pas pouvoir utiliser quoi que ce soit en dehors des outils Windows Vista / 7 en stock, car ils seront distribués aux clients en dehors de mon bureau. Je ne pense pas pouvoir légalement distribuer PSExec.
PDixon724
2
Oui, je pense que vous avez raison à ce sujet - même si PSExec est maintenant un outil Microsoft (depuis qu'ils ont racheté les gars de Sysinternals!), Le CLUF interdit la distribution :(
ewall
2
Je pense que mes options sont assez limitées. Si je savais coder en VB, je pourrais en faire un exe avec un manifeste administrateur, mais je ne saurais même pas par où commencer. Je suppose que je vais simplement avertir au début du lot de s'exécuter en tant qu'administrateur s'ils exécutent Windows Vista / 7. Merci a tous.
PDixon724
1
Un autre outil tiers qui pourrait être librement redistribuable et facile à intégrer et à apprendre est AutoIt ; cette page montre comment le script demande des privilèges élevés.
ewall
4
psexec -hne fonctionne pas: "Impossible d'installer le service PSEXESVC: l'accès est refusé.". Vous devez déjà avoir les droits d'administrateur pour exécuter psexec.
Nicolas
320

Il existe un moyen simple sans avoir besoin d'utiliser un outil externe - il fonctionne bien avec Windows 7, 8, 8.1 et 10 et est également rétrocompatible (Windows XP n'a pas d'UAC, donc l'élévation n'est pas nécessaire - en ce sens cas où le script se poursuit).

Consultez ce code (je me suis inspiré du code de NIronwolf publié dans le fil Batch File - "Access Denied" Sur Windows 7? ), Mais je l'ai amélioré - dans ma version, il n'y a pas de répertoire créé et supprimé pour vérifier les privilèges d'administrateur):

::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "https://stackoverflow.com/a/12264592/1016343" for description
::::::::::::::::::::::::::::::::::::::::::::
 @echo off
 CLS
 ECHO.
 ECHO =============================
 ECHO Running Admin shell
 ECHO =============================

:init
 setlocal DisableDelayedExpansion
 set cmdInvoke=1
 set winSysFolder=System32
 set "batchPath=%~0"
 for %%k in (%0) do set batchName=%%~nk
 set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
 setlocal EnableDelayedExpansion

:checkPrivileges
  NET FILE 1>NUL 2>NUL
  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )

:getPrivileges
  if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
  ECHO.
  ECHO **************************************
  ECHO Invoking UAC for Privilege Escalation
  ECHO **************************************

  ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
  ECHO args = "ELEV " >> "%vbsGetPrivileges%"
  ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
  ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
  ECHO Next >> "%vbsGetPrivileges%"

  if '%cmdInvoke%'=='1' goto InvokeCmd 

  ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
  goto ExecElevation

:InvokeCmd
  ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
  ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"

:ExecElevation
 "%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
 exit /B

:gotPrivileges
 setlocal & cd /d %~dp0
 if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)

 ::::::::::::::::::::::::::::
 ::START
 ::::::::::::::::::::::::::::
 REM Run shell as admin (example) - put here code as you like
 ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
 cmd /k

Le script tire parti du fait qu'il NET FILEnécessite des privilèges d'administrateur et revient errorlevel 1si vous ne l'avez pas. L'élévation est obtenue en créant un script qui relance le fichier de commandes pour obtenir des privilèges. Cela amène Windows à présenter la boîte de dialogue UAC et vous demande le compte administrateur et le mot de passe.

Je l'ai testé avec Windows 7, 8, 8.1, 10 et Windows XP - cela fonctionne bien pour tous. L'avantage est qu'après le point de départ, vous pouvez placer tout ce qui nécessite des privilèges d'administrateur système, par exemple, si vous avez l'intention de réinstaller et de réexécuter un service Windows à des fins de débogage (en supposant que mypackage.msi est un package d'installation de service) :

msiexec /passive /x mypackage.msi
msiexec /passive /i mypackage.msi
net start myservice

Sans ce script d'élévation de privilèges, l'UAC vous demanderait à trois reprises votre nom d'utilisateur et votre mot de passe administrateur - maintenant, vous n'êtes demandé qu'une seule fois au début, et uniquement si nécessaire.


Si votre script a juste besoin d'afficher un message d'erreur et de quitter s'il n'y a pas de privilèges d'administrateur au lieu d'une élévation automatique, c'est encore plus simple: vous pouvez y parvenir en ajoutant ce qui suit au début de votre script:

@ECHO OFF & CLS & ECHO.
NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO You must right-click and select &
  ECHO "RUN AS ADMINISTRATOR"  to run this batch. Exiting... & ECHO. &
  PAUSE & EXIT /D)
REM ... proceed here with admin rights ...

De cette façon, l'utilisateur doit cliquer avec le bouton droit et sélectionner "Exécuter en tant qu'administrateur" . Le script se poursuivra après l' REMinstruction s'il détecte des droits d'administrateur, sinon quittez avec une erreur. Si vous n'en avez pas besoin PAUSE, supprimez-le. Important: NET FILE [...] EXIT /D) doit être sur la même ligne. Il est affiché ici sur plusieurs lignes pour une meilleure lisibilité!


Sur certaines machines, j'ai rencontré des problèmes, qui sont déjà résolus dans la nouvelle version ci-dessus. L'un était dû à une gestion différente des guillemets doubles, et l'autre problème était dû au fait que l'UAC était désactivé (défini au niveau le plus bas) sur une machine Windows 7, d'où le script s'appelle encore et encore.

J'ai corrigé cela maintenant en supprimant les guillemets dans le chemin d'accès et en les rajoutant plus tard, et j'ai ajouté un paramètre supplémentaire qui est ajouté lorsque le script se relance avec des droits élevés.

Les guillemets doubles sont supprimés par les éléments suivants (les détails sont ici ):

setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion

Vous pouvez ensuite accéder au chemin à l'aide de !batchPath!. Il ne contient pas de guillemets doubles, il est donc sûr de le dire "!batchPath!"plus tard dans le script.

La ligne

if '%1'=='ELEV' (shift & goto gotPrivileges)

vérifie si le script a déjà été appelé par le script VBScript pour élever les droits, évitant ainsi des récursions sans fin. Il supprime le paramètre à l'aide de shift.


Mettre à jour:

  • Pour éviter d'avoir à enregistrer l' .vbsextension dans Windows 10 , j'ai remplacé la ligne
    "%temp%\OEgetPrivileges.vbs"
    par
    "%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
    dans le script ci-dessus; également ajouté cd /d %~dp0comme suggéré par Stephen (réponse séparée) et par Tomáš Zato (commentaire) pour définir le répertoire de script par défaut.

  • Maintenant, le script honore les paramètres de ligne de commande qui lui sont transmis. Merci à jxmallet, TanisDLJ et Peter Mortensen pour leurs observations et inspirations.

  • Selon l'indice d'Artjom B., je l'ai analysé et l'ai remplacé SHIFTpar SHIFT /1, qui préserve le nom de fichier du %0paramètre

  • Ajouté del "%temp%\OEgetPrivileges_%batchName%.vbs"à la :gotPrivilegessection à nettoyer (comme suggéré par mlt ). Ajouté %batchName%pour éviter l'impact si vous exécutez différents lots en parallèle. Notez que vous devez utiliser forpour pouvoir profiter des fonctions de chaîne avancées, telles que %%~nk, qui extrait uniquement le nom de fichier.

  • Structure de script optimisée, améliorations (variable ajoutée vbsGetPrivilegesqui est désormais référencée partout permettant de changer facilement le chemin ou le nom du fichier, ne supprimez le .vbsfichier que si le lot devait être élevé)

  • Dans certains cas, une syntaxe d'appel différente était requise pour l'élévation. Si le script ne fonctionne pas, vérifiez les paramètres suivants:
    set cmdInvoke=0
    set winSysFolder=System32
    Modifiez le 1er paramètre en set cmdInvoke=1et vérifiez si cela résout déjà le problème. Il s'ajoutera cmd.exeau script effectuant l'élévation.
    Ou essayez de changer le 2e paramètre en winSysFolder=Sysnative, cela pourrait aider (mais n'est pas nécessaire dans la plupart des cas) sur les systèmes 64 bits. (ADBailey l'a rapporté). "Sysnative" n'est requis que pour lancer des applications 64 bits à partir d'un hôte de script 32 bits (par exemple, un processus de génération Visual Studio ou un appel de script à partir d'une autre application 32 bits).

  • Pour rendre plus clair comment les paramètres sont interprétés, je les affiche maintenant comme P1=value1 P2=value2 ... P9=value9. Ceci est particulièrement utile si vous devez mettre des paramètres comme des chemins entre guillemets doubles, par exemple "C:\Program Files".

  • Si vous souhaitez déboguer le script VBS, vous pouvez ajouter le //Xparamètre à WScript.exe comme premier paramètre, comme suggéré ici (il est décrit pour CScript.exe, mais fonctionne également pour WScript.exe).

Liens utiles:

Mat
la source
9
Excellente réponse, même si cela m'étonne un peu que vous deviez faire tout cela pour faire quelque chose qui est clairement nécessaire dans certains cas.
jcoder
50
En effet, une commande comme ELEVATE est clairement manquante dans le langage batch de Windows.
Matt
2
C'est peut-être plus facile avec PowerShell qui semble être le lanaguge de script approuvé pour les choses plus complexes, mais je n'ai jamais pris la peine de l'apprendre jusqu'à présent :(
jcoder
1
La syntaxe dans powershell est complètement différente (syntaxe verb-nom), mais elle vous permet d'appeler facilement des assemblys .NET. Mais c'est un peu plus difficile à gérer (signature de scripts etc).
Matt
2
@Matt Pouvez-vous vérifier s'il y a une part de vérité dans cette modification rejetée de votre réponse?
Artjom B.
41

Comme jcoder et Matt l'ont mentionné, PowerShell a rendu les choses plus faciles, et il pourrait même être intégré dans le script batch sans créer de nouveau script.

J'ai modifié le script de Matt:

:: Check privileges 
net file 1>NUL 2>NUL
if not '%errorlevel%' == '0' (
    powershell Start-Process -FilePath "%0" -ArgumentList "%cd%" -verb runas >NUL 2>&1
    exit /b
)

:: Change directory with passed argument. Processes started with
:: "runas" start with forced C:\Windows\System32 workdir
cd /d %1

:: Actual work
Hors du sujet
la source
3
Vous avez raison, si PowerShell est installé, vous pouvez l'utiliser pour exécuter le fichier batch avec élévation (merci pour l'extrait de code!). Et oui, l'étiquette n'est pas nécessaire. Merci pour les indices, ça vaut un +1 ... :-)
Matt
2
Lorsqu'il est appelé à partir de cmd, Powershell.exe n'a pas d'option -verb runas. Il existe si vous êtes déjà dans PowerShell.
Adil Hindistan
1
J'aime vraiment cette solution, fonctionne très bien pour moi. Sur Windows 8.1, j'avais besoin du label: gotPrivileges pour que cela fonctionne.
ShaunO
Je rencontre un problème si ce fichier de commandes est distant sur un chemin UNC.
Ryan Beesley
J'ai ajouté un changement de répertoire au démarrage, simplifié le flux et nettoyé un peu. Le répertoire de travail ne peut pas être modifié via le WorkingDirectoryparamètre dans Start-Processpour des raisons de sécurité dans les runasprocessus
ceztko
28

J'utilise l'excellente réponse de Matt, mais je vois une différence entre mes systèmes Windows 7 et Windows 8 lors de l'exécution de scripts élevés.

Une fois le script élevé sous Windows 8, le répertoire actuel est défini sur C:\Windows\system32. Heureusement, il existe une solution de contournement facile en remplaçant le répertoire en cours par le chemin du script en cours:

cd /d %~dp0

Remarque: utilisez cd /dpour vous assurer que la lettre de lecteur est également modifiée.

Pour tester cela, vous pouvez copier ce qui suit dans un script. Exécutez normalement sur l'une ou l'autre version pour voir le même résultat. Exécutez en tant qu'administrateur et voyez la différence dans Windows 8:

@echo off
echo Current path is %cd%
echo Changing directory to the path of the current script
cd %~dp0
echo Current path is %cd%
pause
Stephen Klancher
la source
1
Bon indice, Stephen. Ainsi, le script devrait se terminer par cd %~dp0pour conserver son chemin actuel (je suppose que cela fonctionne également dans Win7, donc la même commande peut être utilisée bien qu'elle ne soit nécessaire que pour Win8 +). +1 pour cela!
Matt
2
À noter que cela était également requis sur mon système fonctionnant sous Windows 7.
meh-uk
1
ou utiliser à la pushd %~dp0place ... pourquoi? parce quepopd
Jaroslav Záruba
27

Je le fais de cette façon:

NET SESSION
IF %ERRORLEVEL% NEQ 0 GOTO ELEVATE
GOTO ADMINTASKS

:ELEVATE
CD /d %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
EXIT

:ADMINTASKS
(Do whatever you need to do here)
EXIT

De cette façon, c'est simple et n'utilisez que les commandes par défaut de Windows. C'est génial si vous devez redistribuer votre fichier de commandes.

CD /d %~dp0Définit le répertoire courant sur le répertoire courant du fichier (s'il ne l'est pas déjà, quel que soit le lecteur dans lequel se trouve le fichier, grâce à l' /doption).

%~nx0 Renvoie le nom de fichier actuel avec l'extension (si vous n'incluez pas l'extension et qu'il y a un exe avec le même nom dans le dossier, il appellera l'exe).

Il y a tellement de réponses sur ce post que je ne sais même pas si ma réponse sera vue.

Quoi qu'il en soit, je trouve cela plus simple que les autres solutions proposées sur les autres réponses, j'espère que ça aide quelqu'un.

Matheus Rocha
la source
4
cd% ~ dp0 ne fonctionnera pas sur les lecteurs réseau, utilisez plutôt pushd% ~ dp0.
Stavm
1
J'adore la simplicité de cette réponse. Et enfin une raison d'utiliser Jscript!
Joe Coder
1
La magie! Merci beaucoup.
Daniele Orlando
1
@Wolf J'ai tapé une énorme réponse seulement pour réaliser que je vous avais mal compris ... J'ai compris ce que vous voulez dire maintenant. Je vais le modifier pour inclure le /d. Merci mon pote :) (PS: le pianiste ici aussi!)
Matheus Rocha
1
Cela fonctionne très bien, mais il peut être judicieux de déplacer la cdcommande au début (cela garantit que le chemin est également disponible pour le script élevé - sinon le script élevé s'exécute simplement à partir de system32). Vous devez également rediriger la commande net vers nul pour masquer sa sortie:net session >nul 2>&1
Nulano
23

Matt a une excellente réponse, mais il supprime tous les arguments transmis au script. Voici ma modification qui conserve les arguments. J'ai également intégré le correctif de Stephen pour le problème du répertoire de travail dans Windows 8.

@ECHO OFF
setlocal EnableDelayedExpansion

NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto START ) else ( goto getPrivileges ) 

:getPrivileges
if '%1'=='ELEV' ( goto START )

set "batchPath=%~f0"
set "batchArgs=ELEV"

::Add quotes to the batch path, if needed
set "script=%0"
set script=%script:"=%
IF '%0'=='!script!' ( GOTO PathQuotesDone )
    set "batchPath=""%batchPath%"""
:PathQuotesDone

::Add quotes to the arguments, if needed.
:ArgLoop
IF '%1'=='' ( GOTO EndArgLoop ) else ( GOTO AddArg )
    :AddArg
    set "arg=%1"
    set arg=%arg:"=%
    IF '%1'=='!arg!' ( GOTO NoQuotes )
        set "batchArgs=%batchArgs% "%1""
        GOTO QuotesDone
        :NoQuotes
        set "batchArgs=%batchArgs% %1"
    :QuotesDone
    shift
    GOTO ArgLoop
:EndArgLoop

::Create and run the vb script to elevate the batch file
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "cmd", "/c ""!batchPath! !batchArgs!""", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
"%temp%\OEgetPrivileges.vbs" 
exit /B

:START
::Remove the elevation tag and set the correct working directory
IF '%1'=='ELEV' ( shift /1 )
cd /d %~dp0

::Do your adminy thing here...
jxmallett
la source
1
Ceci est une réponse utile. Cependant en ECHO UAC.ShellExecute....ligne, "batchArgs!"ne développera pas la variable. Utilisez "!batchArgs!". Ma modification a été rejetée, alors je commente.
volé des oignons le
1
@fliedonion bien repéré! Je ne sais pas pourquoi votre modification a été rejetée car c'était définitivement une faute de frappe et votre correction fonctionne. J'ai fait le changement moi-même et l'ai testé sur Win 8.1. Maintenant, pour trouver tous les scripts où j'utilise ce code ....
jxmallett
2
Le script s'est cassé lors de l'utilisation d'arguments entre guillemets, comme test.bat "a thing"ou "test script.bat" arg1 arg2. Tout est réparé maintenant.
jxmallett
J'ai réussi à le casser (à cause de ma faute: exécution du script à partir du lecteur réseau mappé, car l'administrateur et l'utilisateur normal n'ont pas le même mappage). Pourtant: existe-t-il un moyen de voir la sortie? Pour moi, je devais trouver le .vbs et changer le / c en a / K puis le voir manuellement.
Andreas Reiff
21

J'utilise PowerShell pour relancer le script élevé s'il ne l'est pas. Mettez ces lignes tout en haut de votre script.

net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c %~fnx0 %*'"
goto :eof
:run
:: TODO: Put code here that needs elevation

J'ai copié la méthode 'net name' de la réponse de @ Matt. Sa réponse est beaucoup mieux documentée et contient des messages d'erreur et autres. Celui-ci a l'avantage que PowerShell est déjà installé et disponible sur Windows 7 et versions ultérieures. Aucun fichier VBScript temporaire (* .vbs), et vous n'avez pas besoin de télécharger d'outils.

Cette méthode devrait fonctionner sans aucune configuration ou installation, tant que vos autorisations d'exécution PowerShell ne sont pas verrouillées.

Ryan Bemrose
la source
lorsque vous fournissez une liste d'espaces séparés par des arguments entourés de guillemets pour la traiter comme une seule, la /c %~fnx0 %*'partie semble laisser chaque partie à part la première. Par exemple, à partir de l' test.bat "arg1 arg2 arg3"arg1 uniquement
Nicolas Mommaerts
Il semble que, quoi qu'il arrive, le Start-Process supprime tous les guillemets doubles dans la liste des arguments.
Nicolas Mommaerts
Travaille pour moi! Je l'utilise pour netsh int set int %wifiname% Enable/Disable.
Marslo
2
J'ai eu le même problème que Nicolas Mommaerts ci-dessus. Je ne comprends pas pourquoi cela fonctionne (le meilleur type de correctif), mais les éléments suivants fonctionnent comme il se doit (notez tous les guillemets supplémentaires à la fin): net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
tremblements
Un autre problème (inconvénient) est que le script se met en pause (attend la saisie de l'utilisateur) si le service serveur ne fonctionne pas (je l'ai désactivé pour des raisons). Je teste généralement les autorisations d'administrateur en essayant d'écrire dans l' emplacement du fichier HOSTS , mais il est peut-être préférable d'appeler la commande powershell -Verb runas , au lieu de s'appuyer sur les services Windows activés ou d'essayer d'écrire des fichiers.
script'n'code
15

Pour certains programmes, la définition de la __COMPAT_LAYERvariable d'environnement super secret RunAsInvoker fonctionnera .Vérifiez ceci:

set "__COMPAT_LAYER=RunAsInvoker"
start regedit.exe

Bien que comme cela, il n'y aura pas d'UAC invitant l'utilisateur à continuer sans autorisations d'administrateur.

npocmaka
la source
1
Le lien vers le site Microsoft ne fonctionnait plus, alors je l'ai changé pour le contenu sur archive.org. Si quelqu'un peut trouver un lien de travail vers le contenu sur le site de Microsoft, mais tous les moyens, veuillez le mettre à jour.
RockPaperLizard
1
il est toujours d' intégrité moyenne non élevée , vous ne pouvez donc pas modifier HKLM dans regedit. Il a juste sauté l'UAC.
HackingAddict1337
5

J'ai collé cela au début du script:

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\icacls.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"
    echo args = "" >> "%temp%\getadmin.vbs"
    echo For Each strArg in WScript.Arguments >> "%temp%\getadmin.vbs"
    echo args = args ^& strArg ^& " "  >> "%temp%\getadmin.vbs"
    echo Next >> "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~s0", args, "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs" %*
    exit /B

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------
TanisDLJ
la source
2
J'aime le traitement d'argument dans votre script. Mais notez que caclsc'est déconseillé dans Windows 7 et les versions plus récentes de Windows.
Matt
Fsutil dirty est encore mieux
Wolf
1
Savez-vous que la ligne pushd "%CD%"enregistre le répertoire de travail actuel et les modifications apportées au répertoire de travail actuel?
Wolf
3

Je l' ai écrit gsudo, une sudopour les fenêtres : qui élève dans la console actuelle (pas le changement de contexte dans une nouvelle fenêtre), avec un cache d'informations d'identification (réduit popups CCU), et augmente également les commandes PowerShell .

Il permet d'élever les commandes qui nécessitent des privilèges d'administrateur, ou le lot entier, si vous le souhaitez. Ajoutez juste gsudo avant tout ce qui doit être élevé.

Exemple de fichier batch qui s'auto-élève à l'aide de gsudo:

EDIT: Nouvelle version à une ligne qui fonctionne avec n'importe quel langage Windows et évite les problèmes de whoami :

net session >nul 2>nul & net session >nul 2>nul || gsudo "%~f0" && exit /b || exit /b
:: This will run as admin ::

Alternative (version originale):

@echo off
  rem Test if current context is already elevated:
  whoami /groups | findstr /b BUILTIN\Administrators | findstr /c:"Enabled group" 1> nul 2>nul && goto :isadministrator
  echo You are not admin. (yet)
  :: Use gsudo to launch this batch file elevated.
  gsudo "%~f0"
  goto end
:isadministrator
  echo You are admin.
  echo (Do admin stuff now).
:end

Installer:

Voir gsudo en action: démo gsudo

Gerardo Grignoli
la source
Cool. Merci. Sur quelles versions de Windows fonctionne-t-il?
RockPaperLizard
La suite de tests s'exécute sur Server 2019 et ma boîte de développement locale est Windows 10 1909. Désolé, je n'ai pas testé la compatibilité avec d'autres anciens systèmes d'exploitation.
Gerardo Grignoli
Merci Gerardo. Si quelqu'un l'essaie sur d'autres versions de Windows, veuillez publier vos résultats.
RockPaperLizard
Je viens de tester gsudo v0.7 sur Windows 8.1 et j'ai travaillé. Ce n'est pas anodin de .Net Framework 4.6s'y installer . Heureusement choco install dotnet4.6.2, certaines dépendances difficiles à obtenir. Puis gsudo config Prompt "$p# "Correction d' un problème avec ConHostmontrant un mauvais message (caractères de séquence d'échappement au lieu de la forte rouge). @RockPaperLizard
Gerardo Grignoli
Merci beaucoup Gerardo. Pourrait-il être recompilé pour fonctionner avec toutes les versions de .Net Framework avant 4.6, ou cela dépend-il de certaines fonctionnalités spécifiques à 4.6?
RockPaperLizard
2

Bien que cela ne soit pas directement applicable à cette question, car il veut des informations pour l'utilisateur, Google m'a amené ici lorsque je voulais exécuter mon fichier .bat élevé à partir du planificateur de tâches.

L'approche la plus simple était de créer un raccourci vers le fichier .bat, car pour un raccourci, vous pouvez définir Run as administratordirectement à partir des propriétés avancées.

L'exécution du raccourci à partir du planificateur de tâches exécute le fichier .bat avec élévation.

Hugo Delsing
la source
1

Si vous n'avez pas besoin de passer d'arguments, voici un script d'invite UAC compact d'une seule ligne. Cela fait une chose similaire au script d'élévation dans la réponse la plus votée mais ne transmet pas d'arguments car il n'y a pas de moyen infaillible de le faire qui gère toutes les combinaisons possibles de caractères empoisonnés.

@echo off
net sess>nul 2>&1||(echo(CreateObject("Shell.Application"^).ShellExecute"%~0",,,"RunAs",1:CreateObject("Scripting.FileSystemObject"^).DeleteFile(wsh.ScriptFullName^)>"%temp%\%~nx0.vbs"&start wscript.exe "%temp%\%~nx0.vbs"&exit)

:: Your batch file goes here
user8922283
la source
0

Utilisation de PowerShell.

Si le fichier cmd est long, j'utilise un premier pour exiger l'élévation, puis j'appelle celui qui fait le travail réel.

Si le script est une simple commande, tout peut tenir sur un seul fichier cmd. N'oubliez pas d'inclure le chemin dans les fichiers de script.

Modèle:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c " comands or another script.cmd go here "'"

Exemple 1:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\BIN\x.ps1"'"

Exemple 2:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c "c:\bin\myScript.cmd"'"
Manuel Alves
la source
0

Essaye ça:

@echo off
CLS
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
set winSysFolder=System32
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
if '%cmdInvoke%'=='1' goto InvokeCmd 
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
goto ExecElevation
:InvokeCmd
ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"
:ExecElevation
"%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)
REM Run shell as admin (example) - put here code as you like
ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
cmd /k

Si vous avez besoin d'informations sur ce fichier de commandes, exécutez l'extrait HTML / JS / CSS:

document.getElementsByTagName("data")[0].innerHTML="ElevateBatch, version 4, release<br>Required Commands:<ul><li>CLS</li><li>SETLOCAL</li><li>SET</li><li>FOR</li><li>NET</li><li>IF</li><li>ECHO</li><li>GOTO</li><li>EXIT</li><li>DEL</li></ul>It auto-elevates the system and if the user presses No, it just doesn't do anything.<br>This CANNOT be used to create an Elevated Explorer.";
data{font-family:arial;text-decoration:none}
<data></data>


la source
-3

La solution suivante est propre et fonctionne parfaitement.

  1. Téléchargez le fichier zip Elevate depuis https://www.winability.com/download/Elevate.zip

  2. À l'intérieur du zip, vous devriez trouver deux fichiers: Elevate.exe et Elevate64.exe. (Ce dernier est une compilation 64 bits native, si vous avez besoin que, bien que la version 32 bits normale, Elevate.exe, devrait fonctionner correctement avec les versions 32 et 64 bits de Windows)

  3. Copiez le fichier Elevate.exe dans un dossier où Windows peut toujours le trouver (tel que C: / Windows). Ou mieux vous pouvez copier dans le même dossier où vous prévoyez de conserver votre fichier bat.

  4. Pour l'utiliser dans un fichier batch, ajoutez simplement la commande que vous souhaitez exécuter en tant qu'administrateur avec la commande elevate, comme ceci:

 elevate net start service ...
Vaibhav Jain
la source
2
Cette commande ouvre uniquement une fenêtre de dialogue qui demande à l'utilisateur si cette commande peut être exécutée. Vous ne pouvez donc pas utiliser cette commande dans un fichier de commandes ce qui devrait s'exécuter SANS interaction avec l'utilisateur.
Radon8472
S'il était possible d'élever SANS interaction avec l'utilisateur, ce serait un énorme trou de sécurité, n'est-ce pas? Chaque virus commencerait à utiliser cette méthode pour s'élever sans l'approbation de l'utilisateur.
Andrei Belogortseff