Ausführen eines Befehls als Administrator mit PowerShell?

280

Sie wissen, wie Sie als Administrator eines Systems mit der rechten Maustaste auf ein Batch-Skript klicken und es als Administrator ausführen können, ohne das Administratorkennwort einzugeben?

Ich frage mich, wie ich das mit einem PowerShell-Skript machen soll. Ich möchte mein Passwort nicht eingeben müssen. Ich möchte nur die Rechtsklick- Methode Als Administrator ausführen nachahmen .

Für alles, was ich bisher gelesen habe, müssen Sie das Administratorkennwort angeben.

Chrips
quelle
Versuchen Sie es gsudo. Ein kostenloses Open-Source-Sudo für Windows, mit dem Sie als Administrator über die Befehlszeile ausgeführt werden können. Ein UAC-Popup wird angezeigt.
Gerardo Grignoli

Antworten:

310

Wenn die aktuelle Konsole nicht erhöht ist und der Vorgang, den Sie ausführen möchten, erhöhte Berechtigungen erfordert, können Sie Powershell mit der folgenden Run as administratorOption starten :

PS> Start-Process powershell -Verb runAs
Shay Levy
quelle
1
Das scheint der einzige Weg zu sein, es erfolgreich zu machen. Das hinzugefügte Shell-Fenster erweist sich jedoch in vielen Fällen als problematisch. Am Ende habe ich alles konfiguriert, was das Skript aufgerufen hat, um als Administrator ausgeführt zu werden (z. B. über die Registrierung).
Jacek Gorgoń
17
Dadurch wird eine neue Konsole an einem anderen Ort geöffnet. Gibt es eine Möglichkeit, als Administrator im aktuellen Arbeitsverzeichnis ausgeführt zu werden?
Codierter Container
11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Dev Anand Sadasivam
2
Win+ X Wie hier besprochen
Dev Anand Sadasivam
1
Sie finden das Dokument hier: docs.microsoft.com/en-us/powershell/module/… für die EXE- Datei können die Verben lauten: Open, RunAs, RunAsUser
Kevin Xiong
114

Hier ist eine Ergänzung zu Shay Levis Vorschlag (fügen Sie einfach diese Zeilen am Anfang eines Skripts hinzu):

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
}

Dies führt dazu, dass das aktuelle Skript im Administratormodus an einen neuen Powershell-Prozess übergeben wird (wenn der aktuelle Benutzer Zugriff auf den Administratormodus hat und das Skript nicht als Administrator gestartet wird).

pgk
quelle
6
Das hat bei mir funktioniert:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
G. Lombard
Einfach zu ändern, um nur einen Fehler auszulösen, wenn er nicht als Administrator ausgeführt wird. Nehmen Sie einfach die ifAnweisung und setzen Sie ein throwin den then-Block.
jpmc26
2
@ G.Lombards Kommentar hatte einen subtilen Syntaxfehler. Dies ist, was für mich funktioniert hat:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
Angularsen
Die einzige Syntax, die für mich funktioniert hat, ist im Originalbeitrag, nicht die von G.Lombard oder anjdreas
Nicolas Mommaerts
1
Ich bin damit einverstanden, dass die Verwendung von enum value ( [Security.Principal.WindowsBuiltInRole]::Administrator)) dem Zeichenfolgenargument vorgezogen werden sollte "Administrator"- ich bin auf sicherheitshärtete Umgebungen mit umbenannten integrierten Rollen
gestoßen
104

Selbsterhöhendes PowerShell-Skript

Windows 8.1 / PowerShell 4.0 +

Eine Linie :)

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
quelle
141
Nun, technisch gesehen ist alles "eine Zeile", wenn es so formatiert ist, aber das macht es nicht wirklich zu "einer Zeile"
illegaler Einwanderer
3
Nachteil: Wenn Sie in der Eingabeaufforderung einen Nicht-Administrator eingeben, endet die Endlosschleife.
Manuel Faux
3
aber das geht nicht vorbei args
kyb
2
Um Argumente zu übergeben, habe ich es geändert zu: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
Diese Antwort bewahrt das Arbeitsverzeichnis nicht. Sehen Sie hier für eine, die tut: stackoverflow.com/a/57035712/2441655
Venryx
45

Benjamin Armstrong hat einen ausgezeichneten Artikel über selbsterhöhende PowerShell-Skripte veröffentlicht . Es gibt ein paar kleinere Probleme mit seinem Code; Eine modifizierte Version, die auf den im Kommentar vorgeschlagenen Korrekturen basiert, ist unten aufgeführt.

Grundsätzlich wird die dem aktuellen Prozess zugeordnete Identität abgerufen, überprüft, ob es sich um einen Administrator handelt, und wenn dies nicht der Fall ist, wird ein neuer PowerShell-Prozess mit Administratorrechten erstellt und der alte Prozess beendet.

# 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
quelle
Ich habe den Skriptnamen und die Parameter nicht richtig aufgelöst bekommen, also habe ich die Ausführung in cmd.exe / c $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
xverges
Gibt es einen Vorteil, wenn Sie dies anstelle von Start-Process tun? Ich bin neugierig auf die Unterschiede zwischen dieser Methode und den anderen, die oben und in anderen Threads veröffentlicht wurden. Beide verlassen sich auf .NET, aber diese Methode ist stärker ...
ZaxLofful
Ich fand verschiedene Kommentare im Zusammenhang mit dem direkten Link zu Armstrongs Beitrag (erster Satz dieses Beitrags) ebenfalls sehr hilfreich.
BentChainRing
2
Diese Antwort bewahrt das Arbeitsverzeichnis nicht. Sehen Sie hier für eine, die tut: stackoverflow.com/a/57035712/2441655
Venryx
22

Sie können eine Batchdatei ( *.bat) erstellen , die Ihr Powershell-Skript mit Administratorrechten ausführt, wenn Sie darauf doppelklicken. Auf diese Weise müssen Sie nichts an Ihrem Powershell-Skript ändern . Erstellen Sie dazu eine Batch-Datei mit demselben Namen und Speicherort Ihres Powershell-Skripts und fügen Sie den folgenden Inhalt ein:

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

Das ist es!

Hier ist die Erklärung:

Angenommen, Ihr Powershell-Skript befindet sich im Pfad C:\Temp\ScriptTest.ps1, muss Ihre Batchdatei den Pfad enthalten C:\Temp\ScriptTest.bat. Wenn jemand diese Batchdatei ausführt, werden die folgenden Schritte ausgeführt:

  1. Das cmd führt den Befehl aus

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Eine neue Powershell-Sitzung wird geöffnet und der folgende Befehl wird ausgeführt:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. Eine weitere neue Powershell-Sitzung mit Administratorrechten wird im system32Ordner geöffnet und die folgenden Argumente werden an ihn übergeben:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. Der folgende Befehl wird mit Administratorrechten ausgeführt:

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

    Sobald der Skriptpfad und die Namensargumente in doppelte Anführungszeichen gesetzt sind, können sie Leerzeichen oder einfache Anführungszeichen ( ') enthalten.

  5. Der aktuelle Ordner wechselt von system32zu C:\Tempund das Skript ScriptTest.ps1wird ausgeführt. Sobald der Parameter übergeben -NoExitwurde, wird das Fenster nicht geschlossen, selbst wenn Ihr Powershell-Skript eine Ausnahme auslöst.

Rosberg Linhares
quelle
In diesem Fall wird ein Popup-Fenster angezeigt, in dem ich gefragt werde, ob PowerShell Änderungen an meinem System vornehmen darf. Dies macht es für die Automatisierung unbrauchbar.
John Slegers
@ JohnSlegers, wenn Sie es automatisieren müssen, liegt es in Ihrer Verantwortung, sicherzustellen, dass der automatisierte Prozess als Administrator ausgeführt wird. Wenn Sie einen Nicht-Administrator-Prozess ohne Benutzerinteraktion automatisch zu einem Administrator-Prozess erheben könnten, würde dies den Zweck zunichte machen, dass ein Prozess überhaupt über Administratorrechte verfügen muss.
Meustrus
@meustrus: Als Release Engineer besteht meine Aufgabe darin, Build-Prozesse zu erstellen und zu warten, die entweder in regelmäßigen Abständen oder wenn bestimmte Kriterien erfüllt sind, vollautomatisch ausgeführt werden. Einige dieser Prozesse erfordern Administratorrechte, und das Erfordernis von Benutzereingaben macht einen Prozess in diesem Kontext unbrauchbar. - Unter Linux können Sie dies erreichen, indem Sie den sudoBefehl verwenden und den Benutzer konfigurieren, den Sie für den automatisierten Prozess NOPASSWD: ALLin der sudoersDatei verwenden .
John Slegers
1
Dies ist eine bessere Antwort als die anderen, da das Arbeitsverzeichnis erhalten bleibt. Ich habe hier einige einzeilige Varianten dieses Ansatzes zusammengestellt (eine für cmd / batch, eine für Explorer-Kontextmenüeinträge und eine für Powershell): stackoverflow.com/a/57033941/2441655
Venryx
17

Hier ist ein sich selbst erhöhender Ausschnitt für Powershell-Skripte, der das Arbeitsverzeichnis beibehält :

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

Das Beibehalten des Arbeitsverzeichnisses ist wichtig für Skripte, die pfadbezogene Operationen ausführen. Bei fast allen anderen Antworten wird dieser Pfad nicht beibehalten, was zu unerwarteten Fehlern im Rest des Skripts führen kann.

Wenn Sie lieber kein selbsterhöhendes Skript / Snippet verwenden möchten und stattdessen nur eine einfache Möglichkeit zum Starten eines Skripts als Administrator (z. B. über das Explorer-Kontextmenü) wünschen , finden Sie meine andere Antwort hier: https: // stackoverflow .com / a / 57033941/2441655

Venryx
quelle
16

Verwenden von

#Requires -RunAsAdministrator

wurde noch nicht angegeben. Es scheint erst seit PowerShell 4.0 da zu sein.

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

Wenn dieser switch-Parameter zu Ihrer require-Anweisung hinzugefügt wird, gibt er an, dass die Windows PowerShell-Sitzung, in der Sie das Skript ausführen, mit erhöhten Benutzerrechten gestartet werden muss (Als Administrator ausführen).

Für mich scheint dies ein guter Weg zu sein, aber ich bin mir der Erfahrung vor Ort noch nicht sicher. PowerShell 3.0-Laufzeiten ignorieren dies wahrscheinlich oder geben, noch schlimmer, einen Fehler aus.

Wenn das Skript als Nichtadministrator ausgeführt wird, wird der folgende Fehler angezeigt:

Das Skript 'StackOverflow.ps1' kann nicht ausgeführt werden, da es eine Anweisung "#requires" zum Ausführen als Administrator enthält. Die aktuelle Windows PowerShell-Sitzung wird nicht als Administrator ausgeführt. Starten Sie Windows PowerShell mit der Option Als Administrator ausführen und versuchen Sie dann erneut, das Skript auszuführen.

+ CategoryInfo          : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptRequiresElevation
Akauppi
quelle
7
Leider schlägt das Skript nur dann mit einem Fehler fehl, wenn die Shell keine Administratorrechte besitzt. Es erhebt sich nicht von selbst.
Jacek Gorgoń
PS3 scheint wie vorgeschlagen einen Fehler zu geben. Ich verstehe Parameter RunAsAdministrator requires an argument. @akauppi Ich bin nicht überzeugt, dass sie immer denken.
jpmc26
14

Sie können einfach einige Registrierungseinträge hinzufügen, um ein Kontextmenü "Als Administrator ausführen" für .ps1Dateien zu erhalten:

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

(aktualisiert auf ein einfacheres Skript von @Shay)

Grundsätzlich wird HKCR:\Microsoft.PowershellScript.1\Shell\runas\commandder Standardwert festgelegt, um das Skript mit Powershell aufzurufen.

Manojlds
quelle
Es funktioniert nicht, Sie erstellen einen '(Standard)' - Schlüssel und aktualisieren nicht den '(Standard)' - Schlüsselwert. Ich konnte den Code zu einem Einzeiler verdichten, der für mich funktioniert. Kannst du es testen? 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 - Hallo Shay, danke für die Aktualisierung. Ich habe die Antwort damit aktualisiert. Es funktioniert. Aber der, an dem ich auch gearbeitet hatte, obwohl er ausführlich war. Ich hatte mit Powershell nicht viel Reg Edit gemacht, aber es mit "(Standard)" zu machen, war etwas, das ich als Beispiel gesehen hatte. Es wurde kein neuer Schlüssel erstellt (was so etwas wie ein Standardschlüssel hätte), aber der Standardschlüssel wurde wie erwartet aktualisiert. Hast du es ausprobiert oder nur aus dem (default)Teil geraten ?
Manojlds
Ich versuchte es. Es wurde eine '(Standard)' - Taste unter der Befehlstaste erstellt.
Shay Levy
Dies funktionierte für mich nach einigen geringfügigen Änderungen am Registrierungswert: "c: \ windows \ system32 \ windowspowershell \ v1.0 \ Powershell.exe" -ExecutionPolicy RemoteSigned -NoExit "& '% 1'"
MikeBaz - MSFT
1
Der Registrierungswert in der Antwort weist alle Arten von Problemen auf. Der Befehl wird nicht ausgeführt, und der Skriptname wird nicht richtig angegeben (was bedeutet, dass Pfade mit Leerzeichen unterbrochen werden). Ich benutze das folgende erfolgreich:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
Kal Zekdor
10

Der von Jonathan und Shay Levy gepostete Code hat bei mir nicht funktioniert.

Den Arbeitscode finden Sie unten:

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
quelle
2
Sehr nützliche und praktische Lösung: Ich habe es einfach auf mein Skript übertragen und es funktioniert.
CDuv
3
@Abatonime Wie wäre es, wenn Sie auf leicht zu übersehende Unterschiede zum Nutzen Ihrer Leser hinweisen? Ehrlich gesagt ist diese Änderung nicht mehr wert als ein Kommentar zur anderen Antwort.
jpmc26
8

Sie müssen das Skript mit Administratorrechten erneut ausführen und prüfen, ob das Skript in diesem Modus gestartet wurde. Unten habe ich ein Skript geschrieben, das zwei Funktionen hat: DoElevatedOperations und DoStandardOperations . Sie sollten Ihren Code, für den Administratorrechte erforderlich sind, in den ersten und Standardoperationen in den zweiten Code einfügen. Die Variable IsRunAsAdmin wird verwendet, um den Administratormodus zu identifizieren.

Mein Code ist ein vereinfachter Auszug aus dem Microsoft-Skript, der automatisch generiert wird, wenn Sie ein App-Paket für Windows Store-Apps erstellen.

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
}
Rhythmus
quelle
7

Meine 2 Cent hinzufügen. Meine einfache Version basiert auf einer Netzsitzung, die bisher in Windows 7 / Windows 10 immer funktioniert. Warum sollte man sie zu kompliziert machen?

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

Fügen Sie einfach oben im Skript hinzu, und es wird als Administrator ausgeführt.

Rakha
quelle
1
Gibt es eine Möglichkeit, eine Nachricht an den Benutzer zu senden, nachdem "Zugriff verweigert" angezeigt wird?
ycomp
... oder um die Nachricht überhaupt zu vermeiden
Günter Zöchbauer
1
@ GünterZöchbauer if (!(net session 2>&1 | Out-Null)) { ... @ycomp ... } else { echo "your message" }.
Matthieu
Fehler dafür bekommen,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>, Sie können es einstellen bypass Aber bypassgefährlich sein kann. AllSigned
Stellen
5

Dieses Verhalten ist beabsichtigt. Es gibt mehrere Sicherheitsebenen, da Microsoft wirklich nicht wollte, dass .ps1-Dateien der neueste E-Mail-Virus sind. Einige Leute finden, dass dies dem Begriff der Aufgabenautomatisierung widerspricht, der fair ist. Das Vista + -Sicherheitsmodell dient dazu, Dinge zu "de-automatisieren", damit der Benutzer sie in Ordnung bringt.

Ich vermute jedoch, wenn Sie Powershell selbst als erhöht starten, sollte es in der Lage sein, Batch-Dateien auszuführen, ohne das Kennwort erneut anzufordern, bis Sie Powershell schließen.

VoidStar
quelle
5

Sie können das Öffnen der Anwendung auch als Administrator erzwingen, wenn Sie über ein Administratorkonto verfügen.

Geben Sie hier die Bildbeschreibung ein

Suchen Sie die Datei, klicken Sie mit der rechten Maustaste auf> Eigenschaften> Verknüpfung> Erweitert und aktivieren Sie Als Administrator ausführen

Klicken Sie dann auf OK.

Raphie
quelle
1
Wie schreibt man das?
Dieter
4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellHier befindet sich die Verknüpfung von PowerShell. Es geht auch noch an einen anderen Ort, um die eigentliche 'exe' ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe) aufzurufen .

Da PowerShell benutzerprofilgesteuert ist, wenn es um Berechtigungen geht; Wenn Ihr Benutzername / Profil die Berechtigung hat, etwas zu tun, können Sie dies unter diesem Profil in PowerShell im Allgemeinen auch tun. Abgesehen davon ist es sinnvoll, dass Sie beispielsweise die Verknüpfung unter Ihrem Benutzerprofil ändern C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell.

Klicken Sie mit der rechten Maustaste und klicken Sie auf Eigenschaften. Klicken Sie auf die Schaltfläche "Erweitert" unter der Registerkarte "Verknüpfung" direkt unter dem Textfeld "Kommentare" neben den beiden anderen Schaltflächen "Speicherort der Datei öffnen" und "Symbol ändern".

Aktivieren Sie das Kontrollkästchen "Als Administrator ausführen". Klicken Sie OKdann Applyund OK. Klicken Sie erneut mit der rechten Maustaste auf das Symbol mit der Bezeichnung "Windows PowerShell" in C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellund wählen Sie "An Startmenü / Taskleiste anheften".

Wenn Sie jetzt auf dieses Symbol klicken, wird die Benutzerkontensteuerung zur Eskalation aufgerufen. Nach Auswahl von "JA" wird die PowerShell-Konsole geöffnet und oben auf dem Bildschirm mit "Administrator" gekennzeichnet.

Um noch einen Schritt weiter zu gehen ... Sie können mit der rechten Maustaste auf dieselbe Symbolverknüpfung in Ihrem Profilspeicherort von Windows PowerShell klicken und eine Tastenkombination zuweisen, die genau das Gleiche tut, als ob Sie auf das kürzlich hinzugefügte Symbol geklickt hätten. Geben Sie dort, wo "Tastenkombination" steht, eine Kombination aus Tastatur und Taste ein, z. B .: Ctrl+ Alt+ P P(für PowerShell) . Klicken Sie auf Applyund OK.

Jetzt müssen Sie nur noch die von Ihnen zugewiesene Tastenkombination drücken, und die Benutzerkontensteuerung wird aufgerufen. Nachdem Sie "JA" ausgewählt haben, wird eine PowerShell-Konsole angezeigt und "Administrator" in der Titelleiste angezeigt.

ittechandres
quelle
Alter :) Das Schlüsselwort in OPs Frage ist Scripting !! Nicht irgendeine UI-Mausklicklösung.
Christian
3

Ich habe einen Weg gefunden, dies zu tun ...

Erstellen Sie eine Batchdatei, um Ihr Skript zu öffnen:

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

Erstellen Sie dann eine Verknüpfung auf Ihrem Desktop (klicken Sie mit der rechten Maustaste auf Neu -> Verknüpfung ).

Fügen Sie dies dann an der folgenden Stelle ein:

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

Beim ersten Öffnen müssen Sie Ihr Passwort einmal eingeben. Dadurch wird es im Windows-Manager für Anmeldeinformationen gespeichert.

Danach sollten Sie als Administrator ausgeführt werden können, ohne einen Administrator-Benutzernamen oder ein Kennwort eingeben zu müssen.

Jack
quelle
/ savecred ist nicht sicher!
Nathan Goings
Dies ist die einzige Lösung, die nicht die Eingabeaufforderung für die grafische Höhe verwendet, auf die in einer Remotesitzung möglicherweise nicht zugegriffen werden kann.
DustWolf
3

Das Problem mit den Antworten von @pgk und @Andrew Odri besteht darin, dass Sie Skriptparameter haben, insbesondere wenn diese obligatorisch sind. Sie können dieses Problem mit dem folgenden Ansatz lösen:

  1. Der Benutzer klickt mit der rechten Maustaste auf die .ps1- Datei und wählt "Mit PowerShell ausführen " aus: Fragen Sie ihn über Eingabefelder nach den Parametern (dies ist eine viel bessere Option als die Verwendung des HelpMessage- Parameterattributs).
  2. Der Benutzer führt das Skript über die Konsole aus: Erlauben Sie ihm, die gewünschten Parameter zu übergeben, und lassen Sie sich von der Konsole zwingen, die obligatorischen zu informieren.

Wie wäre der Code, wenn das Skript die obligatorischen Parameter Computername und Port hätte :

[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
quelle
3

Einige der Antworten hier sind nah, aber etwas mehr Arbeit als nötig.

Erstellen Sie eine Verknüpfung zu Ihrem Skript und konfigurieren Sie es als "Als Administrator ausführen":

  • Erstellen Sie die Verknüpfung.
  • Klicken Sie mit der rechten Maustaste auf die Verknüpfung und öffnen Sie sie Properties...
  • Bearbeiten Targetvon <script-path>bispowershell <script-path>
  • Klicken Advanced...und aktivierenRun as administrator
Desillusioniert
quelle
2

Eine andere einfachere Lösung besteht darin, dass Sie auch mit der rechten Maustaste auf "C: \ Windows \ System32 \ cmd.exe" klicken und "Als Administrator ausführen" auswählen können. Anschließend können Sie jede App als Administrator ausführen, ohne ein Kennwort anzugeben.

DupDup
quelle
2

Ich verwende die unten stehende Lösung. Es verarbeitet stdout / stderr über die Transkriptionsfunktion und übergibt den Exit-Code korrekt an den übergeordneten Prozess. Sie müssen den Transkriptionspfad / Dateinamen anpassen.

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
quelle
Dies verliert alle Aufrufargumente
Guillermo Prandi
2

Hier erfahren Sie, wie Sie einen erhöhten Powershell-Befehl ausführen und sein Ausgabeformular in einer Windows-Batchdatei in einem einzigen Befehl sammeln (dh kein ps1-Powershell-Skript schreiben).

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'

Oben sehen Sie, dass ich zuerst eine Powershell mit erhöhter Eingabeaufforderung starte und dann darum bitte, eine weitere Powershell (Sub-Shell) zu starten, um den Befehl auszuführen.

hardeep
quelle
1

Befolgen Sie zusätzlich zu Shay Levys Antwort die folgenden Einstellungen (nur einmal).

  1. Starten Sie eine PowerShell mit Administratorrechten.
  2. Befolgen Sie die Frage zum Stapelüberlauf PowerShell sagt, dass die Ausführung von Skripten auf diesem System deaktiviert ist. .
  3. Legen Sie Ihre .ps1-Datei beispielsweise in einen der PATHOrdner. Windows \ System32-Ordner

Nach dem Setup:

  1. Drücken Sie Win+R
  2. Aufrufen powershell Start-Process powershell -Verb runAs <ps1_file>

Sie können jetzt alles in nur einer Befehlszeile ausführen. Das Obige funktioniert unter Windows 8 Basic 64-Bit.

Lee Chee Kiam
quelle
1

Der zuverlässigste Weg, den ich gefunden habe, besteht darin, ihn in eine sich selbst erhebende .bat-Datei zu verpacken:

@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

Die .bat überprüft, ob Sie bereits Administrator sind, und startet das Skript bei Bedarf als Administrator neu. Es verhindert auch, dass sich fremde "cmd" -Fenster mit dem 4. Parameter von ShellExecute()set to öffnen 0.

Joe Coder
quelle
Gute Antwort, aber ich habe es versucht und nicht funktioniert (und die Befehlszeile verlassen, von der ich es aufgerufen habe). Ich habe Folgendes behoben: Ich habe das erste EXITin ein geändert GOTO :EOFund das zweite gelöscht. Außerdem cd %~dp0sollte das cd /d %~dp0UND der erste Befehl nach dem sein @echo off. Auf diese Weise brauchen Sie nicht den absoluten Pfad der.ps1 , sondern legen ihn einfach in demselben Ordner ab wie der .bat. Wenn Sie das Ergebnis sehen möchten, ändern Sie den 4. Parameter in 1.
cdlvcdlv
Welches Betriebssystem und welche Version verwenden Sie?
Joe Coder
Windows 7 SP1 Ultimate. Ich habe System in C: aber auch Daten und tragbare Anwendungen in D: hauptsächlich (und mehrere andere Laufwerke). Übrigens ... was ist, wenn das Programm / Skript Parameter verwendet? Was würde das seinmshta Befehl?
cdlvcdlv
Ich denke, Sie haben sich bei Ihren Tests möglicherweise geirrt, weil das Skript einwandfrei funktioniert. Übrigens soll es den Anruf beendencmd beenden, damit es nicht "repariert" wird, aber ich bin froh, dass Sie es gemäß Ihren Anforderungen ändern konnten.
Joe Coder
Ok, wenn du das verlassen willst cmd(habe ich nicht). Aber in Bezug auf die anderen Änderungen denke ich, dass dies Korrekturen sind, da meine Version für uns beide funktionieren würde, während Ihre für mich nicht funktioniert, dh meine ist allgemeiner (sprechen Sie das Szenario verschiedener Laufwerke an). Wie auch immer, ein sehr kluger Ansatz.
cdlvcdlv
0

Ich habe noch nie meine eigene Art gesehen, also probieren Sie es aus. Es ist viel einfacher zu folgen und hat einen viel kleineren Platzbedarf:

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

Wenn die aktuelle Powershell-Sitzung mit Administratorrechten aufgerufen wurde, wird die bekannte SID der Administratorgruppe ganz einfach in den Gruppen angezeigt, wenn Sie die aktuelle Identität abrufen. Selbst wenn das Konto Mitglied dieser Gruppe ist, wird die SID nur angezeigt, wenn der Prozess mit erhöhten Anmeldeinformationen aufgerufen wurde.

Fast alle diese Antworten sind eine Variation der äußerst beliebten Methode von Ben Armstrong von Microsoft, wie man dies erreicht, ohne wirklich zu verstehen, was es tatsächlich tut und wie man dieselbe Routine sonst emuliert.

Rincewind
quelle
0

Um die Ausgabe des Befehls an einen Textdateinamen anzuhängen, der das aktuelle Datum enthält, können Sie Folgendes tun:

$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
quelle
0

Dies ist eine Klarstellung ...

Der Powershell-Berechtigungsnachweis RUNAS / SAVECRED "ist nicht sicher", hat es versucht und fügt die Administratoridentität und das Kennwort in den Berechtigungsnachweis-Cache ein und kann an anderer Stelle verwendet werden. OOPS!. Wenn Sie dies getan haben, empfehle ich Ihnen, den Eintrag zu überprüfen und zu entfernen.

Überprüfen Sie Ihr Programm oder Ihren Code, da die Microsoft-Richtlinie lautet, dass Sie ohne die Benutzerkontensteuerung (den Einstiegspunkt) keinen gemischten Benutzer- und Administratorcode im selben Code-Blob haben können, um das Programm als Administrator auszuführen. Dies wäre unter Linux sudo (dasselbe).

Die Benutzerkontensteuerung verfügt über drei Typen: Nicht sehen, eine Eingabeaufforderung oder einen Einstiegspunkt, der im Manifest des Programms generiert wird. Das Programm wird nicht erhöht. Wenn also keine Benutzerkontensteuerung vorhanden ist und ein Administrator benötigt wird, schlägt dies fehl. Die Benutzerkontensteuerung ist zwar als Administratoranforderung gut, verhindert jedoch die Codeausführung ohne Authentifizierung und verhindert, dass das Szenario mit gemischten Codes auf Benutzerebene ausgeführt wird.

Mark Diakon
quelle
Dies sollte ein Kommentar sein, es ist keine Lösung für die Frage (genau wie das Forum funktioniert; Ihr Inhalt ist nützlich, aber keine Lösung).
BGMCoder
-2

Es stellte sich heraus, dass es zu einfach war. Sie müssen lediglich einen Cmd als Administrator ausführen. Geben Sie dann ein explorer.exeund drücken Sie die Eingabetaste. Das öffnet den Windows Explorer . Klicken Sie nun mit der rechten Maustaste auf Ihr PowerShell-Skript, das Sie ausführen möchten, und wählen Sie "Mit PowerShell ausführen", um es in PowerShell im Administratormodus zu starten.

Möglicherweise werden Sie aufgefordert, die Ausführung der Richtlinie zu aktivieren, Y einzugeben und die Eingabetaste zu drücken. Jetzt wird das Skript in PowerShell als Administrator ausgeführt. Wenn alles rot angezeigt wird, bedeutet dies, dass Ihre Richtlinie noch nicht wirksam wurde. Dann versuchen Sie es erneut und es sollte gut funktionieren.

bilal-atlanta
quelle