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é.
la source
@powershell Start-Process cmd -Verb runas
. De Powershell, laissez tomber@powershell
. Cela démarre cmd avec des droits élevés.Réponses:
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
xcopy
etreg.exe
toujours être exécuté avecpsexec -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) ...la source
psexec -h
ne 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.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):
Le script tire parti du fait qu'il
NET FILE
nécessite des privilèges d'administrateur et revienterrorlevel 1
si 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) :
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:
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'
REM
instruction s'il détecte des droits d'administrateur, sinon quittez avec une erreur. Si vous n'en avez pas besoinPAUSE
, 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 ):
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
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'
.vbs
extension 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 %~dp0
comme 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é
SHIFT
parSHIFT /1
, qui préserve le nom de fichier du%0
paramètreAjouté
del "%temp%\OEgetPrivileges_%batchName%.vbs"
à la:gotPrivileges
section à 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 utiliserfor
pour 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
vbsGetPrivileges
qui est désormais référencée partout permettant de changer facilement le chemin ou le nom du fichier, ne supprimez le.vbs
fichier 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=1
et vérifiez si cela résout déjà le problème. Il s'ajouteracmd.exe
au 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
//X
paramè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:
Citations (") , Bang (!) , Caret (^) , Esperluette (&) , Autres caractères spéciaux
la source
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:
la source
WorkingDirectory
paramètre dansStart-Process
pour des raisons de sécurité dans lesrunas
processusJ'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:Remarque: utilisez
cd /d
pour 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:
la source
cd %~dp0
pour 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!pushd %~dp0
place ... pourquoi? parce quepopd
Je le fais de cette façon:
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 %~dp0
Dé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'/d
option).%~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.
la source
/d
. Merci mon pote :) (PS: le pianiste ici aussi!)cd
commande 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
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.
la source
ECHO UAC.ShellExecute....
ligne,"batchArgs!"
ne développera pas la variable. Utilisez"!batchArgs!"
. Ma modification a été rejetée, alors je commente.test.bat "a thing"
ou"test script.bat" arg1 arg2
. Tout est réparé maintenant.J'utilise PowerShell pour relancer le script élevé s'il ne l'est pas. Mettez ces lignes tout en haut de votre script.
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.
la source
/c %~fnx0 %*'
partie semble laisser chaque partie à part la première. Par exemple, à partir de l'test.bat "arg1 arg2 arg3"
arg1 uniquementnetsh int set int %wifiname% Enable/Disable
.net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
Pour certains programmes, la définition de la
__COMPAT_LAYER
variable d'environnement super secretRunAsInvoker
fonctionnera .Vérifiez ceci:Bien que comme cela, il n'y aura pas d'UAC invitant l'utilisateur à continuer sans autorisations d'administrateur.
la source
regedit
. Il a juste sauté l'UAC.J'ai collé cela au début du script:
la source
cacls
c'est déconseillé dans Windows 7 et les versions plus récentes de Windows.pushd "%CD%"
enregistre le répertoire de travail actuel et les modifications apportées au répertoire de travail actuel?Je l' ai écrit
gsudo
, unesudo
pour 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 :
Alternative (version originale):
Installer:
choco install gsudo
scoop install gsudo
Voir gsudo en action:
la source
.Net Framework 4.6
s'y installer . Heureusementchoco install dotnet4.6.2
, certaines dépendances difficiles à obtenir. Puisgsudo config Prompt "$p# "
Correction d' un problème avecConHost
montrant un mauvais message (caractères de séquence d'échappement au lieu de la forte rouge). @RockPaperLizardBien 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 administrator
directement à 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.
la source
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.
la source
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:
Exemple 1:
Exemple 2:
la source
Essaye ça:
Si vous avez besoin d'informations sur ce fichier de commandes, exécutez l'extrait HTML / JS / CSS:
la source
La solution suivante est propre et fonctionne parfaitement.
Téléchargez le fichier zip Elevate depuis https://www.winability.com/download/Elevate.zip
À 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)
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.
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:
la source