Exécuter une commande en tant qu'administrateur à l'aide de PowerShell?

280

Vous savez comment si vous êtes l'utilisateur administratif d'un système et vous pouvez simplement cliquer avec le bouton droit sur, un script de commandes et l'exécuter en tant qu'administrateur sans entrer le mot de passe administrateur?

Je me demande comment faire cela avec un script PowerShell. Je ne veux pas avoir à saisir mon mot de passe; Je veux simplement imiter la méthode Exécuter en tant qu'administrateur avec un clic droit .

Tout ce que j'ai lu jusqu'à présent vous oblige à fournir le mot de passe administrateur.

chrips
la source
Essayez gsudo. Un sudo open-source gratuit pour Windows qui permet de s'exécuter en tant qu'administrateur à partir de la ligne de commande. Une fenêtre contextuelle UAC apparaît.
Gerardo Grignoli

Réponses:

313

Si la console actuelle n'est pas élevée et que l'opération que vous essayez de faire nécessite des privilèges élevés, vous pouvez démarrer PowerShell avec l' Run as administratoroption:

PS> Start-Process powershell -Verb runAs
Shay Levy
la source
1
Cela semble être la seule façon de réussir. Cependant, la fenêtre de shell ajoutée s'avère problématique dans de nombreux cas. J'ai fini par configurer tout ce qui invoquait le script pour s'exécuter en tant qu'administrateur (par exemple via le registre).
Jacek Gorgoń
17
Cela ouvrira une nouvelle console à un emplacement différent. Existe-t-il un moyen de s'exécuter en tant qu'administrateur dans le répertoire de travail actuel?
Conteneur codé du
11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Dev Anand Sadasivam
2
Win+ X Tel que discuté ici
Dev Anand Sadasivam
1
vous pouvez trouver le document ici: docs.microsoft.com/en-us/powershell/module/… pour le fichier .exe, les verbes peuvent être: Open, RunAs, RunAsUser
Kevin Xiong
115

Voici un ajout à la suggestion de Shay Levi (ajoutez simplement ces lignes au début d'un script):

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

{   
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}

Il en résulte que le script actuel est transmis à un nouveau processus PowerShell en mode Administrateur (si l'utilisateur actuel a accès au mode Administrateur et que le script n'est pas lancé en tant qu'administrateur).

pgk
la source
6
Cela a fonctionné pour moi:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
G. Lombard
Facilement modifié pour simplement lancer une erreur lorsqu'il n'est pas exécuté en tant qu'administrateur. Il suffit de prendre la ifdéclaration et de mettre un throwà l'intérieur du bloc d'alors.
jpmc26
2
@ Le commentaire de G.Lombard contenait une subtile erreur de syntaxe. C'est ce qui a fonctionné pour moi:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
angularsen
La seule syntaxe qui a fonctionné pour moi est dans le message d'origine, pas celle de G.Lombard ni anjdreas
Nicolas Mommaerts
2
Je suis d'accord que l'utilisation de la valeur enum ( [Security.Principal.WindowsBuiltInRole]::Administrator)) devrait être préférée à l'argument chaîne "Administrator"- J'ai rencontré des environnements renforcés de sécurité avec des rôles intégrés renommés
eXavier
105

Script PowerShell à élévation automatique

Windows 8.1 / PowerShell 4.0 +

Une ligne :)

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

# Your script here
Jayowend
la source
145
eh bien, techniquement parlant, tout est "une ligne" si formaté comme ça, mais cela ne le rend pas réellement "une ligne"
immigrant illégal
3
Inconvénient: si vous entrez un non-administrateur dans l'invite, vous vous retrouvez dans une boucle de sortie de fourche sans fin.
Manuel Faux
3
mais cela ne passe pas args
kyb
2
Pour passer des arguments, je l'ai modifié pour:if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" `"$args`"" -Verb RunAs; exit }
ab.
2
Cette réponse ne conserve pas le répertoire de travail. Voir ici pour celui qui fait: stackoverflow.com/a/57035712/2441655
Venryx
45

Benjamin Armstrong a publié un excellent article sur les scripts PowerShell auto-élévateurs . Il y a quelques problèmes mineurs avec son code; une version modifiée basée sur les correctifs suggérés dans le commentaire est ci-dessous.

Fondamentalement, il obtient l'identité associée au processus en cours, vérifie s'il s'agit d'un administrateur et, dans le cas contraire, crée un nouveau processus PowerShell avec des privilèges d'administrateur et met fin à l'ancien processus.

# Get the ID and security principal of the current user account
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID);

# Get the security principal for the administrator role
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;

# Check to see if we are currently running as an administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
    # We are running as an administrator, so change the title and background colour to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)";
    $Host.UI.RawUI.BackgroundColor = "DarkBlue";
    Clear-Host;
}
else {
    # We are not running as an administrator, so relaunch as administrator

    # Create a new process object that starts PowerShell
    $newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell";

    # Specify the current script path and name as a parameter with added scope and support for scripts with spaces in it's path
    $newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"

    # Indicate that the process should be elevated
    $newProcess.Verb = "runas";

    # Start the new process
    [System.Diagnostics.Process]::Start($newProcess);

    # Exit from the current, unelevated, process
    Exit;
}

# Run your code that needs to be elevated here...

Write-Host -NoNewLine "Press any key to continue...";
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
Andrew Odri
la source
Je n'obtenais pas le nom du script et les paramètres correctement résolus, j'ai donc $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
encapsulé
Y a-t-il un avantage à le faire comme ça au lieu de Start-Process? Je suis curieux de connaître les différences entre cette méthode et les autres postées ci-dessus et sur d'autres threads. Ils s'appuient tous les deux sur .NET, mais cette méthode plus lourdement ...
ZaxLofful
J'ai trouvé que divers commentaires associés au lien direct vers le post d'Armstrong (première phrase de ce post) étaient également très utiles.
BentChainRing
2
Cette réponse ne conserve pas le répertoire de travail. Voir ici pour celui qui fait: stackoverflow.com/a/57035712/2441655
Venryx
22

Vous pouvez créer un fichier de commandes ( *.bat) qui exécute votre script PowerShell avec des privilèges administratifs lorsque vous double-cliquez dessus. De cette façon, vous n'avez pas besoin de modifier quoi que ce soit dans votre script powershell . Pour ce faire, créez un fichier de commandes avec le même nom et l'emplacement de votre script powershell, puis mettez-y le contenu suivant:

@echo off

set scriptFileName=%~n0
set scriptFolderPath=%~dp0
set powershellScriptFileName=%scriptFileName%.ps1

powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"%scriptFolderPath%\`\"; & \`\".\%powershellScriptFileName%\`\"`\"\" -Verb RunAs"

C'est tout!

Voici l'explication:

En supposant que votre script PowerShell se trouve dans le chemin C:\Temp\ScriptTest.ps1, votre fichier de commandes doit avoir le chemin C:\Temp\ScriptTest.bat. Lorsque quelqu'un exécute ce fichier de commandes, les étapes suivantes se produisent:

  1. Le cmd exécutera la commande

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Une nouvelle session Powershell s'ouvrira et la commande suivante sera exécutée:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. Une autre nouvelle session PowerShell avec des privilèges administratifs s'ouvrira dans le system32dossier et les arguments suivants lui seront transmis:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. La commande suivante sera exécutée avec des privilèges administratifs:

    cd "C:\Temp"; & ".\ScriptTest.ps1"

    Une fois que le chemin du script et les arguments de nom sont entre guillemets, ils peuvent contenir des espaces ou des guillemets simples ( ').

  5. Le dossier actuel passera de system32à C:\Tempet le script ScriptTest.ps1sera exécuté. Une fois le paramètre -NoExitpassé, la fenêtre ne sera pas fermée, même si votre script powershell lève une exception.

Rosberg Linhares
la source
Si je fais cela, j'obtiens une fenêtre contextuelle qui me demande si j'autorise PowerShell à apporter des modifications à mon système. Cela le rend inutilisable pour l'automatisation.
John Slegers
@JohnSlegers, si vous avez besoin de l'automatiser, il est de votre responsabilité de vous assurer que le processus automatisé est exécuté en tant qu'administrateur. Si vous pouviez automatiquement élever un processus non administrateur à un processus administrateur sans interaction avec l'utilisateur, cela irait à l'encontre du but d'exiger qu'un processus ait des privilèges d'administrateur en premier lieu.
meustrus
@meustrus: En tant qu'ingénieur de publication , mon travail consiste à créer et à maintenir des processus de génération qui s'exécutent de manière entièrement automatique, soit périodiquement, soit lorsque certains critères sont remplis. Certains de ces processus nécessitent des privilèges d'administrateur, et nécessitant une entrée utilisateur rend un processus inutilisable dans ce contexte. - Sous Linux, vous pouvez y parvenir en utilisant la sudocommande et en configurant l'utilisateur que vous utilisez pour le processus automatisé avec NOPASSWD: ALLdans le sudoersfichier .
John Slegers
1
C'est une meilleure réponse que les autres car elle préserve le répertoire de travail. J'ai rassemblé ici quelques variantes d'une ligne de cette approche (une pour cmd / batch, une pour les entrées du menu contextuel de l'Explorateur et une pour PowerShell): stackoverflow.com/a/57033941/2441655
Venryx
17

Voici un extrait auto-élévateur pour les scripts Powershell qui préserve le répertoire de travail :

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
    exit;
}

# Your script here

La conservation du répertoire de travail est importante pour les scripts qui effectuent des opérations relatives au chemin. Presque toutes les autres réponses ne conservent pas ce chemin, ce qui peut provoquer des erreurs inattendues dans le reste du script.

Si vous préférez ne pas utiliser un script / extrait de code auto-élévateur, et que vous souhaitez plutôt simplement un moyen facile de lancer un script en tant qu'administrateur (par exemple, à partir du menu contextuel de l'Explorateur), consultez mon autre réponse ici: https: // stackoverflow .com / a / 57033941/2441655

Venryx
la source
16

En utilisant

#Requires -RunAsAdministrator

n'a pas encore été déclaré. Il ne semble y être que depuis PowerShell 4.0.

http://technet.microsoft.com/en-us/library/hh847765.aspx

Lorsque ce paramètre de commutateur est ajouté à votre instruction require, il spécifie que la session Windows PowerShell dans laquelle vous exécutez le script doit être démarrée avec des droits d'utilisateur élevés (Exécuter en tant qu'administrateur).

Pour moi, cela semble être une bonne façon de procéder, mais je ne suis pas encore sûr de l'expérience sur le terrain. Les runtimes PowerShell 3.0 ignorent probablement cela, ou pire encore, donnent une erreur.

Lorsque le script est exécuté en tant que non-administrateur, l'erreur suivante s'affiche:

Le script 'StackOverflow.ps1' ne peut pas être exécuté car il contient une instruction "#requires" pour être exécuté en tant qu'administrateur. La session Windows PowerShell actuelle ne s'exécute pas en tant qu'administrateur. Démarrez Windows PowerShell à l'aide de l'option Exécuter en tant qu'administrateur, puis réessayez d'exécuter le script.

+ CategoryInfo          : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptRequiresElevation
akauppi
la source
7
Malheureusement, il ne fait qu'échouer le script avec une erreur si le shell n'a pas de privilèges d'administrateur. Il n'élève pas par lui-même.
Jacek Gorgoń
La PS3 semble donner une erreur comme suggéré. Je comprends Parameter RunAsAdministrator requires an argument. @akauppi Je ne suis pas convaincu qu'ils pensent toujours.
jpmc26
14

Vous pouvez facilement ajouter des entrées de registre pour obtenir un menu contextuel "Exécuter en tant qu'administrateur" pour les .ps1fichiers:

New-Item -Path "Registry::HKEY_CLASSES_ROOT\Microsoft.PowershellScript.1\Shell\runas\command" `
-Force -Name '' -Value '"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit "%1"'

(mis à jour vers un script plus simple de @Shay)

Fondamentalement, HKCR:\Microsoft.PowershellScript.1\Shell\runas\commanddéfinissez la valeur par défaut pour appeler le script à l'aide de Powershell.

manojlds
la source
Cela ne fonctionne pas, vous créez une clé '(par défaut)', pas la mise à jour de la valeur de clé '(par défaut)'. J'ai pu condenser le code en une seule ligne qui fonctionne pour moi. Pouvez-vous le tester? New-Item -Path "Registry :: HKEY_CLASSES_ROOT \ Microsoft.PowershellScript.1 \ Shell \ runas \ command" -Force -Name '' -Value '"c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -noexit "% 1" '
Shay Levy
@Shay Levy - Salut Shay, merci pour la mise à jour. J'ai mis à jour la réponse avec. Ça marche. Mais celui que j'avais travaillé aussi, bien qu'il soit verbeux. Je n'avais pas fait beaucoup d'édition de reg avec Powershell, mais le faire avec "(par défaut)" était quelque chose que j'avais vu comme exemple. Il n'a pas créé de nouvelle clé (qui aurait quelque chose comme défaut) mais a mis à jour la clé par défaut comme prévu. L'avez-vous essayé ou simplement deviné à partir de la (default)partie?
Manojlds
Je l'ai essayé. Il a créé une clé '(par défaut)' sous la touche de commande.
Shay Levy
Cela a fonctionné pour moi après quelques modifications mineures à la valeur de Registre: "c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -ExecutionPolicy RemoteSigned -NoExit "& '% 1'"
MikeBaz - MSFT
1
La valeur de registre dans la réponse a toutes sortes de problèmes. Il n'exécute pas réellement la commande et ne cite pas correctement le nom du script (ce qui signifie qu'il se casse sur les chemins avec des espaces). J'utilise avec succès les éléments suivants:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
Kal Zekdor
10

Le code affiché par Jonathan et Shay Levy n'a pas fonctionné pour moi.

Veuillez trouver le code de travail ci-dessous:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
#"No Administrative rights, it will display a popup window asking user for Admin rights"

$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments

break
}
#"After user clicked Yes on the popup, your file will be reopened with Admin rights"
#"Put your code here"
John
la source
2
Solution très utile et pratique: il suffit de le confondre avec mon script et ça marche.
CDuv
3
@Abatonime Que diriez-vous de signaler les différences faciles à manquer au profit de vos lecteurs? Honnêtement, ce changement ne vaut pas plus qu'un commentaire sur l'autre réponse.
jpmc26
8

Vous devez réexécuter le script avec des privilèges administratifs et vérifier si le script a été lancé dans ce mode. Ci-dessous, j'ai écrit un script qui a deux fonctions: DoElevatedOperations et DoStandardOperations . Vous devez placer votre code qui nécessite des droits d'administrateur dans le premier et des opérations standard dans le second. La variable IsRunAsAdmin est utilisée pour identifier le mode administrateur.

Mon code est un extrait simplifié du script Microsoft qui est généré automatiquement lorsque vous créez un package d'application pour les applications du Windows Store.

param(
    [switch]$IsRunAsAdmin = $false
)

# Get our script path
$ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path

#
# Launches an elevated process running the current script to perform tasks
# that require administrative privileges.  This function waits until the
# elevated process terminates.
#
function LaunchElevated
{
    # Set up command line arguments to the elevated process
    $RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '" -IsRunAsAdmin'

    # Launch the process and wait for it to finish
    try
    {
        $AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru
    }
    catch
    {
        $Error[0] # Dump details about the last error
        exit 1
    }

    # Wait until the elevated process terminates
    while (!($AdminProcess.HasExited))
    {
        Start-Sleep -Seconds 2
    }
}

function DoElevatedOperations
{
    Write-Host "Do elevated operations"
}

function DoStandardOperations
{
    Write-Host "Do standard operations"

    LaunchElevated
}


#
# Main script entry point
#

if ($IsRunAsAdmin)
{
    DoElevatedOperations
}
else
{
    DoStandardOperations
}
Rython
la source
7

Ajout de mes 2 cents. Ma version simple basée sur une session Internet qui fonctionne jusqu'à présent sous Windows 7 / Windows 10. Pourquoi la compliquer trop?

if (!(net session)) {$path =  "& '" + $myinvocation.mycommand.definition + "'" ; Start-Process powershell -Verb runAs -ArgumentList $path ; exit}

ajoutez simplement en haut du script et il fonctionnera en tant qu'administrateur.

Rakha
la source
1
existe-t-il un moyen de transmettre un message à l'utilisateur après l'affichage de "Accès refusé"?
ycomp
... ou pour éviter le message du tout
Günter Zöchbauer
1
@ GünterZöchbauer if (!(net session 2>&1 | Out-Null)) { ... @ycomp ... } else { echo "your message" }.
Matthieu
obtenir des erreurs pour cela,cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
user2305193
1
@ user2305193 Set-ExecutionPolicy -ExecutionPolicy <PolicyName>, vous pouvez le définir sur bypass Mais bypasspeut être dangereux. Réglez-leAllSigned
AliFurkan
5

Ce comportement est inhérent à conception. Il existe plusieurs couches de sécurité, car Microsoft ne voulait vraiment pas que les fichiers .ps1 soient le dernier virus de messagerie. Certaines personnes trouvent cela contraire à la notion même d'automatisation des tâches, ce qui est juste. Le modèle de sécurité Vista + consiste à "désautomatiser" les choses, permettant ainsi à l'utilisateur de les accepter.

Cependant, je soupçonne que si vous lancez PowerShell lui-même comme élevé, il devrait être capable d'exécuter des fichiers batch sans demander à nouveau le mot de passe jusqu'à ce que vous fermiez PowerShell.

VoidStar
la source
5

Vous pouvez également forcer l'application à s'ouvrir en tant qu'administrateur, si vous avez un compte administrateur, bien sûr.

entrez la description de l'image ici

Recherchez le fichier, cliquez avec le bouton droit> propriétés> Raccourci> Avancé et cochez Exécuter en tant qu'administrateur

Cliquez ensuite sur OK.

raphie
la source
1
Comment écrivez-vous cela?
Dieter
4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellest l'endroit où réside le raccourci de PowerShell. Il va aussi toujours à un emplacement différent pour invoquer le «exe» réel ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe).

Étant donné que PowerShell est piloté par le profil utilisateur lorsque les autorisations sont concernées; si votre nom d'utilisateur / profil est autorisé à faire quelque chose, alors sous ce profil, dans PowerShell, vous pourrez généralement le faire également. Cela étant dit, il serait logique que vous modifiiez le raccourci situé sous votre profil utilisateur, par exemple C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell,.

Cliquez avec le bouton droit et cliquez sur Propriétés. Cliquez sur le bouton "Avancé" sous l'onglet "Raccourci" situé juste en dessous du champ de texte "Commentaires" adjacent à la droite de deux autres boutons, "Ouvrir l'emplacement du fichier" et "Changer d'icône", respectivement.

Cochez la case "Exécuter en tant qu'administrateur". Cliquez sur OK, puis Applyet OK. Une fois de plus, cliquez avec le bouton droit sur l'icône intitulée «Windows PowerShell» située dans C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellet sélectionnez «Épingler au menu Démarrer / barre des tâches».

Désormais, chaque fois que vous cliquez sur cette icône, il invoque l' UAC pour l'escalade. Après avoir sélectionné «OUI», vous remarquerez que la console PowerShell est ouverte et elle sera étiquetée «Administrateur» en haut de l'écran.

Pour aller plus loin ... vous pouvez cliquer avec le bouton droit sur le même raccourci d'icône dans votre emplacement de profil de Windows PowerShell et attribuer un raccourci clavier qui fera exactement la même chose que si vous avez cliqué sur l'icône récemment ajoutée. Donc, là où il est dit "touche de raccourci", mettez une combinaison clavier / bouton comme: Ctrl+ Alt+ P P(pour PowerShell) . Cliquez sur Applyet OK.

Maintenant, tout ce que vous avez à faire est d'appuyer sur la combinaison de boutons que vous avez affectée et vous verrez l'UAC être invoqué, et après avoir sélectionné 'OUI', vous verrez une console PowerShell apparaître et "Administrateur" affiché dans la barre de titre.

ittechandres
la source
Mec :) Le mot-clé dans la question OP est le script !! Pas une solution de clic de souris UI.
Christian
3

J'ai trouvé un moyen de le faire ...

Créez un fichier batch pour ouvrir votre script:

@echo off
START "" "C:\Scripts\ScriptName.ps1"

Créez ensuite un raccourci, par exemple sur votre bureau (cliquez avec le bouton droit sur Nouveau -> Raccourci ).

Collez-le ensuite dans l'emplacement:

C:\Windows\System32\runas.exe /savecred /user:*DOMAIN*\*ADMIN USERNAME* C:\Scripts\BatchFileName.bat

Lors de la première ouverture, vous devrez saisir votre mot de passe une fois. Cela l'enregistrera ensuite dans le gestionnaire d'informations d'identification Windows.

Après cela, vous devriez pouvoir exécuter en tant qu'administrateur sans avoir à entrer un nom d'utilisateur ou un mot de passe administrateur.

Jack
la source
/ savecred n'est pas sûr!
Nathan Goings
Il s'agit de la seule solution qui n'utilise pas l'invite d'élévation graphique qui pourrait ne pas être accessible sur une session distante.
DustWolf
3

Le problème avec les réponses @pgk et @Andrew Odri , c'est quand vous avez des paramètres de script, spécialement quand ils sont obligatoires. Vous pouvez résoudre ce problème en utilisant l'approche suivante:

  1. L'utilisateur clique avec le bouton droit sur le fichier .ps1 et sélectionne «Exécuter avec PowerShell»: demandez-lui les paramètres via les zones de saisie (c'est une bien meilleure option que d'utiliser l' attribut de paramètre HelpMessage );
  2. L'utilisateur exécute le script via la console: lui permettre de passer les paramètres souhaités et laisser la console le forcer à renseigner les obligatoires.

Voici comment serait le code si le script avait les paramètres obligatoires ComputerName et Port :

[CmdletBinding(DefaultParametersetName='RunWithPowerShellContextMenu')]
param (
    [parameter(ParameterSetName='CallFromCommandLine')]
    [switch] $CallFromCommandLine,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [string] $ComputerName,

    [parameter(Mandatory=$false, ParameterSetName='RunWithPowerShellContextMenu')]
    [parameter(Mandatory=$true, ParameterSetName='CallFromCommandLine')]
    [UInt16] $Port
)

function Assert-AdministrativePrivileges([bool] $CalledFromRunWithPowerShellMenu)
{
    $isAdministrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

    if ($isAdministrator)
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            # Must call itself asking for obligatory parameters
            & "$PSCommandPath" @script:PSBoundParameters -CallFromCommandLine
            Exit
        }
    }
    else
    {
        if (!$CalledFromRunWithPowerShellMenu -and !$CallFromCommandLine)
        {
            $serializedParams = [Management.Automation.PSSerializer]::Serialize($script:PSBoundParameters)

            $scriptStr = @"
                `$serializedParams = '$($serializedParams -replace "'", "''")'

                `$params = [Management.Automation.PSSerializer]::Deserialize(`$serializedParams)

                & "$PSCommandPath" @params -CallFromCommandLine
"@

            $scriptBytes = [System.Text.Encoding]::Unicode.GetBytes($scriptStr)
            $encodedCommand = [Convert]::ToBase64String($scriptBytes)

            # If this script is called from another one, the execution flow must wait for this script to finish.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -EncodedCommand $encodedCommand" -Verb 'RunAs' -Wait
        }
        else
        {
            # When you use the "Run with PowerShell" feature, the Windows PowerShell console window appears only briefly.
            # The NoExit option makes the window stay visible, so the user can see the script result.
            Start-Process -FilePath 'powershell' -ArgumentList "-ExecutionPolicy Bypass -NoProfile -NoExit -File ""$PSCommandPath""" -Verb 'RunAs'
        }

        Exit
    }
}

function Get-UserParameters()
{
    [string] $script:ComputerName = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a computer name:', 'Testing Network Connection')

    if ($script:ComputerName -eq '')
    {
        throw 'The computer name is required.'
    }

    [string] $inputPort = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a TCP port:', 'Testing Network Connection')

    if ($inputPort -ne '')
    {
        if (-not [UInt16]::TryParse($inputPort, [ref]$script:Port))
        {
            throw "The value '$inputPort' is invalid for a port number."
        }
    }
    else
    {
        throw 'The TCP port is required.'
    }
}

# $MyInvocation.Line is empty in the second script execution, when a new powershell session
# is started for this script via Start-Process with the -File option.
$calledFromRunWithPowerShellMenu = $MyInvocation.Line -eq '' -or $MyInvocation.Line.StartsWith('if((Get-ExecutionPolicy')

Assert-AdministrativePrivileges $calledFromRunWithPowerShellMenu

# Necessary for InputBox
[System.Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') | Out-Null

if ($calledFromRunWithPowerShellMenu)
{
    Get-UserParameters
}

# ... script code
Test-NetConnection -ComputerName $ComputerName -Port $Port
Rosberg Linhares
la source
3

Un certain nombre de réponses ici sont proches, mais un peu plus de travail que nécessaire.

Créez un raccourci vers votre script et configurez-le sur "Exécuter en tant qu'administrateur":

  • Créez le raccourci.
  • Raccourci droit et ouverture Properties...
  • Modifier Targetde <script-path>àpowershell <script-path>
  • Cliquez Advanced...et activezRun as administrator
Désabusé
la source
2

Une autre solution plus simple est que vous pouvez également cliquer avec le bouton droit sur "C: \ Windows \ System32 \ cmd.exe" et choisir "Exécuter en tant qu'administrateur", puis vous pouvez exécuter n'importe quelle application en tant qu'administrateur sans fournir de mot de passe.

DupDup
la source
2

J'utilise la solution ci-dessous. Il gère stdout / stderr via la fonction de transcription et transmet le code de sortie correctement au processus parent. Vous devez ajuster le chemin de transcription / nom de fichier.

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{ 
  echo "* Respawning PowerShell child process with elevated privileges"
  $pinfo = New-Object System.Diagnostics.ProcessStartInfo
  $pinfo.FileName = "powershell"
  $pinfo.Arguments = "& '" + $myinvocation.mycommand.definition + "'"
  $pinfo.Verb = "RunAs"
  $pinfo.RedirectStandardError = $false
  $pinfo.RedirectStandardOutput = $false
  $pinfo.UseShellExecute = $true
  $p = New-Object System.Diagnostics.Process
  $p.StartInfo = $pinfo
  $p.Start() | Out-Null
  $p.WaitForExit()
  echo "* Child process finished"
  type "C:/jenkins/transcript.txt"
  Remove-Item "C:/jenkins/transcript.txt"
  Exit $p.ExitCode
} Else {
  echo "Child process starting with admin privileges"
  Start-Transcript -Path "C:/jenkins/transcript.txt"
}

# Rest of your script goes here, it will be executed with elevated privileges
Marek Obuchowicz
la source
Cela perd tous les arguments d'invocation
Guillermo Prandi
2

Voici comment exécuter une commande PowerShell élevée et collecter son formulaire de sortie dans un fichier batch Windows dans une seule commande (c'est-à-dire sans écrire un script PowerShell PS1).

powershell -Command 'Start-Process powershell -ArgumentList "-Command (Get-Process postgres | Select-Object Path | Select-Object -Index 0).Path | Out-File -encoding ASCII $env:TEMP\camp-postgres.tmp" -Verb RunAs'

Ci-dessus, vous voyez que je lance d'abord un PowerShell avec une invite élevée et que je demande ensuite de lancer un autre PowerShell (sous-shell) pour exécuter la commande.

hardeep
la source
1

En plus de la réponse de Shay Levy, suivez la configuration ci-dessous (une seule fois)

  1. Démarrez un PowerShell avec des droits d'administrateur.
  2. Suivez la question Stack Overflow PowerShell dit que «l'exécution des scripts est désactivée sur ce système». .
  3. Placez votre fichier .ps1 dans l'un des PATHdossiers, par exemple. Dossier Windows \ System32

Après la configuration:

  1. Appuyez sur Win+R
  2. Invoquer powershell Start-Process powershell -Verb runAs <ps1_file>

Vous pouvez maintenant tout exécuter sur une seule ligne de commande. Ce qui précède fonctionne sur Windows 8 Basic 64 bits.

Lee Chee Kiam
la source
1

Le moyen le plus fiable que j'ai trouvé est de l'envelopper dans un fichier .bat auto-élévateur:

@echo off
NET SESSION 1>NUL 2>NUL
IF %ERRORLEVEL% EQU 0 GOTO ADMINTASKS
CD %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 0); close();"
EXIT

:ADMINTASKS

powershell -file "c:\users\joecoder\scripts\admin_tasks.ps1"

EXIT

Le .bat vérifie si vous êtes déjà administrateur et relance le script en tant qu'administrateur si nécessaire. Il empêche également l'ouverture de fenêtres "cmd" superflues avec le 4ème paramètre ShellExecute()défini sur 0.

Joe Coder
la source
Bonne réponse, mais je l'ai essayée et je n'ai pas fonctionné (et j'ai quitté la ligne de commande à partir de laquelle je l'ai appelée). J'ai corrigé de cette façon: j'ai changé le premier EXITen a GOTO :EOFet supprimé le second. De plus, le cd %~dp0devrait être cd /d %~dp0ET placé la première commande après le @echo off. De cette façon, vous n'avez pas besoin du chemin absolu .ps1non plus, placez-le simplement dans le même dossier que le .bat. Si vous avez besoin de voir le résultat, changez le 4ème paramètre en 1.
cdlvcdlv
Quelle O / S et quelle version utilisez-vous?
Joe Coder
Windows 7 SP1 Ultimate. J'ai un système en C: mais aussi des données et des applications portables en D: principalement (et plusieurs autres lecteurs). Au fait ... que faire si le programme / script utilise des paramètres? Quelle serait la mshtacommande?
cdlvcdlv
Je pense que vous avez peut-être commis une erreur dans vos tests, car le script fonctionne très bien. Soit dit en passant, il est conçu pour quitter le cmdprocessus d' appel afin de ne pas le "réparer", mais je suis heureux que vous ayez pu le modifier en fonction de vos besoins.
Joe Coder
Ok si vous voulez quitter cmd(je ne l'ai pas fait). Mais en ce qui concerne les autres changements, je pense que ce sont des correctifs car ma version fonctionnerait pour nous deux alors que la vôtre ne l'est pas pour moi, c'est-à-dire la mienne plus générale (abordez le scénario des différents lecteurs). Quoi qu'il en soit, une approche très intelligente.
cdlvcdlv
0

Je n'ai jamais vu ma propre façon de le faire auparavant, alors essayez-le. Il est beaucoup plus facile à suivre et a une empreinte beaucoup plus petite:

if([bool]([Security.Principal.WindowsIdentity]::GetCurrent()).Groups -notcontains "S-1-5-32-544") {
    Start Powershell -ArgumentList "& '$MyInvocation.MyCommand.Path'" -Verb runas
    }

Très simplement, si la session Powershell en cours a été appelée avec des privilèges d'administrateur, le SID bien connu du groupe administrateur apparaîtra dans les groupes lorsque vous récupérerez l'identité actuelle. Même si le compte est membre de ce groupe, le SID n'apparaîtra que si le processus a été appelé avec des informations d'identification élevées.

Presque toutes ces réponses sont une variation de la méthode extrêmement populaire de Ben Armstrong de Microsoft pour savoir comment l'accomplir tout en ne saisissant pas vraiment ce qu'elle fait réellement et comment émuler la même routine.

Rincevent
la source
0

Pour ajouter la sortie de la commande à un nom de fichier texte qui inclut la date actuelle, vous pouvez faire quelque chose comme ceci:

$winupdfile = 'Windows-Update-' + $(get-date -f MM-dd-yyyy) + '.txt'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`"" -Verb RunAs; exit } else { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -Command `"Get-WUInstall -AcceptAll | Out-File $env:USERPROFILE\$winupdfile -Append`""; exit }
Travis Runyard
la source
0

Ceci est une clarification ...

Le justificatif d'identité RUNAS / SAVECRED powershell "n'est pas sûr", l'a essayé et il ajoute l'identité d'administrateur et le mot de passe dans le cache des justificatifs d'identité et peut être utilisé ailleurs OOPS !. Si vous avez fait cela, je vous suggère de vérifier et de supprimer l'entrée.

Passez en revue votre programme ou votre code car la politique de Microsoft est que vous ne pouvez pas avoir de code utilisateur et administrateur mélangés dans le même blob de code sans l'UAC (le point d'entrée) pour exécuter le programme en tant qu'administrateur. Ce serait sudo (même chose) sous Linux.

L'UAC a 3 types, dont ne pas voir, une invite ou un point d'entrée généré dans le manifeste du programme. Il n'élève pas le programme, donc s'il n'y a pas d'UAC et qu'il a besoin d'un administrateur, il échouera. L'UAC bien qu'en tant qu'exigence d'administrateur soit bonne, elle empêche l'exécution de code sans authentification et empêche le scénario de codes mixtes de s'exécuter au niveau de l'utilisateur.

Mark diacre
la source
Cela devrait être un commentaire, ce n'est pas une solution à la question (juste le fonctionnement du forum; votre contenu est utile, mais ce n'est pas une solution).
bgmCoder
-2

Il s'avère que c'était trop facile. Tout ce que vous avez à faire est d'exécuter un cmd en tant qu'administrateur. Tapez ensuite explorer.exeet appuyez sur Entrée. Cela ouvre l' Explorateur Windows . Maintenant, faites un clic droit sur votre script PowerShell que vous souhaitez exécuter, choisissez "exécuter avec PowerShell" qui le lancera dans PowerShell en mode administrateur.

Il peut vous demander d'activer la stratégie, tapez Y et appuyez sur Entrée. Maintenant, le script s'exécutera dans PowerShell en tant qu'administrateur. Dans le cas où il est tout rouge, cela signifie que votre stratégie n'a pas encore pris effet. Réessayez ensuite et cela devrait fonctionner correctement.

bilal-atlanta
la source