Uruchamianie polecenia jako administrator przy użyciu programu PowerShell?


280

Wiesz jak, jeśli jesteś administratorem systemu i możesz po prostu kliknąć prawym przyciskiem myszy powiedz, skrypt wsadowy i uruchomić go jako Administrator bez podawania hasła administratora?

Zastanawiam się, jak to zrobić za pomocą skryptu PowerShell. Nie chcę wprowadzać hasła; Chcę tylko naśladować metodę Uruchom jako administrator prawym przyciskiem myszy .

Wszystko, co do tej pory czytałem, wymaga podania hasła administratora.


Spróbować gsudo. Bezpłatne sudo typu open-source dla systemu Windows, które pozwala na uruchamianie jako administrator z wiersza poleceń. Pojawi się wyskakujące okienko UAC.
— Gerardo Grignoli

Odpowiedzi:


312

Jeśli bieżąca konsola nie jest podniesiona, a operacja, którą próbujesz wykonać, wymaga podniesionych uprawnień, możesz uruchomić PowerShell z Run as administratoropcją:

PS> Start-Process powershell -Verb runAs

1
To chyba jedyny sposób, aby zrobić to z powodzeniem. Jednak dodane okno powłoki okazuje się problematyczne w wielu przypadkach. Skończyłem konfigurowanie wszystkiego, co wywoływało skrypt, aby działał jako administrator (np. Przez rejestr).
— Jacek Gorgoń

17
Spowoduje to otwarcie nowej konsoli w innym miejscu. Czy istnieje sposób działania jako administrator w bieżącym katalogu roboczym?
— Kontener kodowany

11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
— Dev Anand Sadasivam


1
dokument można znaleźć tutaj: docs.microsoft.com/en-us/powershell/module/... dla pliku .exe, czasowniki mogą być: Otwarte, RunAs, RunAsUser
— Kevin Xiong

114

Oto dodatek do sugestii Shay Levi (wystarczy dodać te wiersze na początku skryptu):

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
}

Powoduje to, że bieżący skrypt jest przekazywany do nowego procesu PowerShell w trybie administratora (jeśli bieżący użytkownik ma dostęp do trybu administratora, a skrypt nie jest uruchamiany jako administrator).


6
To zadziałało dla mnie:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
— G. Lombard

Łatwo modyfikowany, aby po prostu wyświetlał błąd, gdy nie jest uruchamiany jako administrator. Po prostu weź ifoświadczenie i umieść throwwewnątrz tego bloku.
— jpmc26

2
W komentarzu G.Lombarda wystąpił subtelny błąd składniowy. Właśnie to działało dla mnie:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
— angularsen

Jedyną składnią, która działała dla mnie, jest oryginalny post, nie ten autorstwa G.Lombarda ani anjdreasa
— Nicolas Mommaerts

2
Zgadzam się, że [Security.Principal.WindowsBuiltInRole]::Administrator)"Administrator"
— zamiast

104

Samopodnoszący się skrypt PowerShell

Windows 8.1 / PowerShell 4.0 +

Jedna linia :)

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

143
cóż, technicznie rzecz biorąc, wszystko jest „jedna linia”, jeśli jest tak sformatowana, ale to nie czyni z niej faktycznej „jednej linii”
— nielegalnie-imigrant

3
Wada: jeśli wpiszesz nie-admin w pytaniu, zakończysz w niekończącej się pętli wyjścia z widelca.
— Manuel Faux

3
ale to nie mija argumentów
— Kyb

2
Aby przekazać argumenty, zmodyfikowałem go do: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
Ta odpowiedź nie zachowuje katalogu roboczego. Zobacz tutaj, który robi: stackoverflow.com/a/57035712/2441655
— Venryx

45

Benjamin Armstrong opublikował doskonały artykuł o samodoskonalących się skryptach PowerShell . Jest kilka drobnych problemów z jego kodem; zmodyfikowana wersja oparta na poprawkach sugerowanych w komentarzu znajduje się poniżej.

Zasadniczo pobiera tożsamość powiązaną z bieżącym procesem, sprawdza, czy jest administratorem, a jeśli nie jest, tworzy nowy proces PowerShell z uprawnieniami administratora i kończy stary proces.

# 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");

Nie otrzymałem poprawnie nazwy skryptu i parametrów, więc $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
— zawarłem

Czy jest jakaś korzyść z robienia tego w ten sposób zamiast Start-Process? Jestem ciekawy różnic między tą metodą a innymi zamieszczonymi powyżej oraz w innych wątkach. Oba polegają na .NET, ale ta metoda jest bardziej obciążona ...
— ZaxLofful,

Bardzo pomocne okazały się również różne komentarze związane z bezpośrednim linkiem do postu Armstronga (pierwsze zdanie tego postu).
— BentChainRing

2
Ta odpowiedź nie zachowuje katalogu roboczego. Zobacz tutaj, który robi: stackoverflow.com/a/57035712/2441655
— Venryx

22

Możesz utworzyć plik wsadowy ( *.bat), który uruchamia skrypt PowerShell z uprawnieniami administratora po dwukrotnym kliknięciu. W ten sposób nie musisz nic zmieniać w skrypcie PowerShell. Aby to zrobić, utwórz plik wsadowy o tej samej nazwie i położeniu skryptu PowerShell, a następnie umieść w nim następującą treść:

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

Otóż ​​to!

Oto wyjaśnienie:

Zakładając, że skrypt PowerShell znajduje się na ścieżce C:\Temp\ScriptTest.ps1, plik wsadowy musi mieć ścieżkę C:\Temp\ScriptTest.bat. Gdy ktoś uruchomi ten plik wsadowy, zostaną wykonane następujące kroki:

  1. Polecenie cmd wykona polecenie

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Otworzy się nowa sesja PowerShell i zostanie wykonana następująca komenda:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. W system32folderze otworzy się kolejna nowa sesja PowerShell z uprawnieniami administracyjnymi, do której zostaną przekazane następujące argumenty:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. Następujące polecenie zostanie wykonane z uprawnieniami administratora:

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

    Gdy argumenty ścieżki i nazwy są podwójnie cytowane, mogą zawierać spacje lub znaki pojedynczego cudzysłowu ( ').

  5. Bieżący folder zmieni się z system32na C:\Tempi skrypt ScriptTest.ps1zostanie wykonany. Po przekazaniu parametru -NoExitokno nie zostanie zamknięte, nawet jeśli skrypt PowerShell zgłasza wyjątek.


Jeśli to zrobię, pojawi się wyskakujące okienko z pytaniem, czy zezwalam programowi PowerShell na wprowadzanie zmian w moim systemie. To sprawia, że ​​nie nadaje się do automatyzacji.
— John Slegers

@JohnSlegers, jeśli musisz to zautomatyzować, Twoim obowiązkiem jest upewnić się, że zautomatyzowany proces działa jako administrator. Jeśli mógłbyś automatycznie podnieść proces nieadministracyjny do procesu administracyjnego bez interakcji użytkownika, byłoby to sprzeczne z celem polegającym na tym, że proces musi mieć uprawnienia administratora.
— meustrus

@meustrus: Jako inżynier ds. wydań moim zadaniem jest tworzenie i utrzymywanie procesów kompilacji, które działają w pełni automatycznie, okresowo lub po spełnieniu określonych kryteriów. Niektóre z tych procesów wymagają uprawnień administratora, a wymaganie od użytkownika danych sprawia, że ​​proces nie nadaje się do użytku w tym kontekście. - W systemie Linux można to osiągnąć, używając sudopolecenia i konfigurując użytkownika używanego do automatycznego procesu NOPASSWD: ALLw sudoerspliku .
— John Slegers,

1
To lepsza odpowiedź niż inne, ponieważ zachowuje katalog roboczy.
— Złożyłem tutaj jednowierszowe

17

Oto samopodnoszący się fragment dla skryptów Powershell, który zachowuje katalog roboczy :

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

Zachowanie katalogu roboczego jest ważne dla skryptów wykonujących operacje względne względem ścieżki. Prawie wszystkie inne odpowiedzi nie zachowują tej ścieżki, co może powodować nieoczekiwane błędy w pozostałej części skryptu.

Jeśli wolisz nie używać samowznoszącego się skryptu / fragmentu, a zamiast tego chcesz po prostu w łatwy sposób uruchomić skrypt jako administrator (np. Z menu kontekstowego Eksploratora), zobacz moją inną odpowiedź tutaj: https: // stackoverflow .pl / a / 57033941/2441655


16

Za pomocą

#Requires -RunAsAdministrator

jeszcze nie zostało powiedziane. Wydaje się, że istnieje tylko od wersji PowerShell 4.0.

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

Gdy ten parametr przełącznika zostanie dodany do instrukcji wymaganej, określa, że ​​sesja Windows PowerShell, w której uruchamiany jest skrypt, musi zostać uruchomiona z podwyższonymi uprawnieniami użytkownika (Uruchom jako administrator).

Wydaje mi się, że to dobry sposób, ale nie jestem jeszcze pewien doświadczenia w terenie. Środowiska wykonawcze PowerShell 3.0 prawdopodobnie ignorują to, lub nawet gorzej, powodują błąd.

Gdy skrypt jest uruchamiany jako użytkownik inny niż administrator, pojawia się następujący błąd:

Nie można uruchomić skryptu „StackOverflow.ps1”, ponieważ zawiera on instrukcję „#requires” do działania jako administrator. Bieżąca sesja Windows PowerShell nie działa jako administrator. Uruchom program Windows PowerShell, używając opcji Uruchom jako administrator, a następnie spróbuj ponownie uruchomić skrypt.

+ CategoryInfo          : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ScriptRequiresElevation

7
Niestety, powoduje tylko awarię skryptu z błędem, jeśli powłoka nie ma uprawnień administratora. Sam się nie podnosi.
— Jacek Gorgoń

PS3 wydaje się sugerować błąd. I dostać Parameter RunAsAdministrator requires an argument. @akauppi Nie jestem przekonany, że zawsze myślą.
— jpmc26

14

Możesz łatwo dodać niektóre wpisy rejestru, aby uzyskać menu kontekstowe „Uruchom jako administrator” dla .ps1plików:

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

(zaktualizowany do prostszego skryptu z @Shay)

Zasadniczo w HKCR:\Microsoft.PowershellScript.1\Shell\runas\commandustaw wartość domyślną, aby wywołać skrypt za pomocą programu PowerShell.


To nie działa, tworzysz klucz „(domyślny)”, nie aktualizujesz wartości klucza „(domyślny)”. Byłem w stanie skondensować kod do jednej linijki, która działa dla mnie. Czy możesz to przetestować? 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 - Cześć Shay, dziękuję za aktualizację. Zaktualizowałem o to odpowiedź. To działa. Ale ten, nad którym również pracowałem, choć był pełny. Nie zrobiłem wiele edycji reg z Powershell, ale robienie tego z „(domyślnie)” było czymś, co widziałem jako przykład. Nie utworzył nowego klucza (który miałby coś domyślnego), ale zaktualizował klucz domyślny zgodnie z oczekiwaniami. Wypróbowałeś to, czy po prostu zgadłeś na podstawie tej (default)części?
— manojlds

Próbowałem tego. Utworzono klawisz „(domyślny)” pod klawiszem poleceń.
— Shay Levy,

Działa to dla mnie po kilku drobnych zmianach wartości rejestru: „c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe” -ExecutionPolicy RemoteSigned -NoExit „& '% 1'”
— MikeBaz - MSFT

1
Wartość rejestru w odpowiedzi ma wiele problemów. W rzeczywistości nie uruchamia polecenia i nie podaje poprawnie nazwy skryptu (co oznacza, że ​​łamie się na ścieżkach ze spacjami). Z powodzeniem używam:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
— Kal Zekdor

10

Kod opublikowany przez Jonathana i Shay Levy nie działał dla mnie.

Poniżej znajdziesz działający kod:

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"

2
Bardzo przydatne i praktyczne rozwiązanie: po prostu dostosowałem go do mojego skryptu i działa.
— CDuv

3
@Abatonime Co powiesz na wskazanie łatwych do przeoczenia różnic z korzyścią dla czytelników? Szczerze mówiąc, ta zmiana nie jest warta więcej niż komentarz do drugiej odpowiedzi.
— jpmc26 12.04.17

8

Musisz ponownie uruchomić skrypt z uprawnieniami administracyjnymi i sprawdzić, czy skrypt został uruchomiony w tym trybie. Poniżej napisałem skrypt, który ma dwie funkcje: DoElevatedOperations i DoStandardOperations . Powinieneś umieścić swój kod, który wymaga uprawnień administratora w pierwszym, a standardowe operacje w drugim. IsRunAsAdmin zmienna jest używana do określenia trybu administratora.

Mój kod to uproszczony wyciąg ze skryptu Microsoft, który jest generowany automatycznie podczas tworzenia pakietu aplikacji dla aplikacji ze Sklepu Windows.

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
}

7

Dodając moje 2 centy. Moja prosta wersja oparta na sesji sieciowej, która do tej pory działa w systemie Windows 7 / Windows 10. Po co to komplikować?

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

po prostu dodaj na górę skryptu, a uruchomi się on jako administrator.


1
Czy istnieje sposób, aby wysłać wiadomość do użytkownika po wyświetleniu komunikatu „Odmowa dostępu”?
— ycomp

... lub w ogóle uniknąć wiadomości
— Günter Zöchbauer

1
@ GünterZöchbauer if (!(net session 2>&1 | Out-Null)) { ... @ycomp ... } else { echo "your message" }.
— Matthieu

otrzymuję błędy z tego powodu,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>, Możesz ustawić to bypass Ale bypassmoże być niebezpieczne. Ustaw naAllSigned
— AliFurkan

5

To zachowanie jest zgodne z projektem. Istnieje wiele warstw zabezpieczeń, ponieważ Microsoft naprawdę nie chciał, aby pliki .ps1 były najnowszymi wirusami pocztowymi. Niektórzy uważają, że jest to sprzeczne z samym pojęciem automatyzacji zadań, co jest sprawiedliwe. Model bezpieczeństwa Vista + ma na celu „zautomatyzowanie” rzeczy, dzięki czemu użytkownik jest w porządku.

Podejrzewam jednak, że jeśli sam uruchomisz PowerShell jako podniesiony, powinien on być w stanie uruchamiać pliki wsadowe bez żądania hasła, dopóki nie zamkniesz PowerShell.


5

Możesz również zmusić aplikację do otwarcia jako administrator, jeśli oczywiście masz konto administratora.

wprowadź opis zdjęcia tutaj

Znajdź plik, kliknij prawym przyciskiem myszy> właściwości> Skrót> Zaawansowane i sprawdź Uruchom jako administrator

Następnie kliknij OK.


1
Jak to napisać?
— Dieter

4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShelljest miejscem, w którym znajduje się skrót PowerShell. On również nadal udaje się w inne miejsce, aby wywołać rzeczywiste „exe” (%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe ).

Ponieważ PowerShell jest oparty na profilu użytkownika, jeśli chodzi o uprawnienia; jeśli twoja nazwa użytkownika / profil ma uprawnienia do zrobienia czegoś, to pod tym profilem w PowerShell na ogół będziesz mógł to zrobić. Biorąc to pod uwagę, sensowne byłoby zmodyfikowanie skrótu znajdującego się pod Twoim profilem użytkownika, na przykładC:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell .

Kliknij prawym przyciskiem myszy i kliknij właściwości. Kliknij przycisk „Zaawansowane” pod zakładką „Skrót” znajdującą się tuż pod polem tekstowym „Komentarze” sąsiadującym z prawej strony dwóch innych przycisków, odpowiednio „Otwórz lokalizację pliku” i „Zmień ikonę”.

Zaznacz pole wyboru brzmi „Uruchom jako administrator”. Kliknij OK, a następnie Applyi OK. Ponownie kliknij prawym przyciskiem myszy ikonę „Windows PowerShell” znajdującą się wC:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell i wybierz „Przypnij do menu Start / paska zadań”.

Teraz za każdym razem, gdy klikniesz tę ikonę, wywoła ona UAC w celu eskalacji. Po wybraniu „TAK” zauważysz, że konsola PowerShell jest otwarta, a na górze ekranu będzie oznaczona etykietą „Administrator”.

Aby pójść o krok dalej ... możesz kliknąć prawym przyciskiem myszy ten sam skrót ikony w lokalizacji profilu Windows PowerShell i przypisać skrót klawiaturowy, który zrobi dokładnie to samo, jakbyś kliknął ostatnio dodaną ikonę. Więc tam, gdzie jest napisane „Klawisz skrótu”, wstaw kombinację klawiszy / przycisków, na przykład: Ctrl+ Alt+ P P(dla PowerShell) . Kliknij Applyi OK.

Teraz wystarczy nacisnąć przypisaną kombinację przycisków, a zobaczysz wywołanie UAC, a po wybraniu „TAK” zobaczysz konsolę PowerShell, a na pasku tytułu wyświetli się „Administrator”.


Koleś :) Słowem kluczowym w pytaniu OP jest skryptowanie !! Nie niektóre rozwiązania kliknięcia myszą interfejsu użytkownika.
— Christian

3

Znalazłem sposób, aby to zrobić ...

Utwórz plik wsadowy, aby otworzyć skrypt:

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

Następnie utwórz skrót, powiedz na pulpicie (kliknij prawym przyciskiem myszy Nowy -> Skrót ).

Następnie wklej to do lokalizacji:

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

Przy pierwszym otwarciu musisz raz wpisać hasło. Spowoduje to zapisanie go w menedżerze poświadczeń systemu Windows.

Po tym powinieneś być w stanie uruchomić się jako administrator bez konieczności wprowadzania nazwy użytkownika lub hasła administratora.


/ savecred nie jest bezpieczny!
— Nathan Goings

To jedyne rozwiązanie, które nie korzysta z graficznego monitu o podniesienie uprawnień, które może być niedostępne w sesji zdalnej.
— DustWolf

3

Problem z odpowiedziami @pgk i @Andrew Odri polega na tym, że masz parametry skryptu, zwłaszcza gdy są one obowiązkowe. Możesz rozwiązać ten problem, stosując następujące podejście:

  1. Użytkownik kliknie prawym przyciskiem myszy plik .ps1 i wybierze „Uruchom za pomocą programu PowerShell”: zapytaj go o parametry w polach wejściowych (jest to znacznie lepsza opcja niż użycie HelpMessage parametru );
  2. Użytkownik wykonuje skrypt za pośrednictwem konsoli: pozwól mu przekazać pożądane parametry i pozwól konsoli zmusić go do poinformowania o obowiązkowych.

Oto, jak wyglądałby kod, gdyby skrypt miał obowiązkowe parametry ComputerName i 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

3

Wiele odpowiedzi tutaj jest blisko, ale trochę więcej pracy niż potrzeba.

Utwórz skrót do skryptu i skonfiguruj go do „Uruchom jako administrator”:

  • Utwórz skrót.
  • Kliknij skrót prawym przyciskiem myszy i otwórz Properties...
  • Edytuj Targetod <script-path>dopowershell <script-path>
  • Kliknij Advanced...i włączRun as administrator

2

Innym prostszym rozwiązaniem jest to, że możesz także kliknąć prawym przyciskiem myszy „C: \ Windows \ System32 \ cmd.exe” i wybrać „Uruchom jako administrator”, a następnie możesz uruchomić dowolną aplikację jako administrator bez podawania hasła.


2

Korzystam z rozwiązania poniżej. Obsługuje stdout / stderr poprzez funkcję transkrypcji i poprawnie przekazuje kod wyjścia do procesu nadrzędnego. Musisz dostosować ścieżkę / nazwę pliku transkrypcji.

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

To traci wszystkie argumenty wywołania
— Guillermo Prandi

2

Oto jak uruchomić podniesioną komendę PowerShell i zebrać jej formę wyjściową w pliku wsadowym Windows w jednym poleceniu (tj. Nie pisać skryptu PowerShell dla 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'

Powyżej widać, że najpierw uruchamiam PowerShell z podwyższonym monitem, a następnie pytam, aby uruchomić inną PowerShell (podpowłoka), aby uruchomić polecenie.


1

Oprócz odpowiedzi Shay Levy, wykonaj poniższe ustawienia (tylko raz)

  1. Uruchom PowerShell z uprawnieniami administratora.
  2. Podążaj za pytaniem o przepełnienie stosu PowerShell mówi: „wykonywanie skryptów jest wyłączone w tym systemie”. .
  3. Umieść na przykład plik .ps1 w dowolnym folderze PATH. Folder Windows \ System32

Po instalacji:

  1. Naciśnij Win+R
  2. Odwołać się powershell Start-Process powershell -Verb runAs <ps1_file>

Możesz teraz uruchomić wszystko w jednym wierszu poleceń. Powyższe działa w systemie Windows 8 Basic w wersji 64-bitowej.


1

Najbardziej niezawodny sposób, jaki znalazłem, to zawinięcie go w samopodnoszący się plik .bat:

@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

.Bat sprawdza, czy jesteś już administratorem i w razie potrzeby ponownie uruchamia skrypt jako Administrator. Zapobiega również otwieraniu zewnętrznych okien „cmd” przy czwartym parametrze ShellExecute()ustawionym na 0.


Dobra odpowiedź, ale próbowałem i nie działałem (i wyszedłem z wiersza poleceń, z którego je wywołałem). Naprawiłem w ten sposób: zmieniłem pierwszy EXITna a GOTO :EOFi usunąłem drugi. Ponadto, cd %~dp0należy umieścić cd /d %~dp0ORAZ pierwszą komendę po @echo off. W ten sposób nie potrzebujesz bezwzględnej ścieżki .ps1żadnej z nich, po prostu umieść ją w tym samym folderze, co .bat. Jeśli chcesz zobaczyć wynik, zmień 4. parametr na 1.
— cdlvcdlv

Które systemy operacyjne i wersje są uruchomione?
— Joe Coder,

Windows 7 SP1 Ultimate. Mam system w C: ale także dane i aplikacje przenośne w D: głównie (i kilka innych dysków). Przy okazji ... co jeśli program / skrypt używa parametrów? Jakie byłoby mshtapolecenie?
— cdlvcdlv 12.01.2018

Myślę, że mogłeś pomylić się podczas testowania, ponieważ skrypt działa dobrze. Nawiasem mówiąc, został zaprojektowany, aby wyjść z cmdprocesu wywoływania , więc nie jest to „naprawianie”, ale cieszę się, że mogłeś go zmodyfikować zgodnie z własnymi potrzebami.
— Joe Coder

Ok, jeśli chcesz wyjść z cmd(ja nie). Ale jeśli chodzi o inne zmiany, myślę, że są to poprawki, ponieważ moja wersja działałaby dla nas obojga, a twoja nie dla mnie, tj. Moja jest bardziej ogólna (omów scenariusz różnych dysków). W każdym razie bardzo sprytne podejście.
— cdlvcdlv

0

Nie widziałem wcześniej swojego sposobu, więc wypróbuj to. Jest o wiele łatwiejszy do naśladowania i ma znacznie mniejszą powierzchnię:

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

Bardzo prosto, jeśli bieżąca sesja PowerShell została wywołana z uprawnieniami administratora, dobrze znany identyfikator SID grupy administratorów pojawi się w grupach, gdy pobierzesz bieżącą tożsamość. Nawet jeśli konto należy do tej grupy, identyfikator SID nie pojawi się, chyba że proces został wywołany z podwyższonymi referencjami.

Prawie wszystkie te odpowiedzi są odmianą niezwykle popularnej metody Bena Armstronga Microsoftu, w jaki sposób to osiągnąć, nie tak naprawdę pojmując, co faktycznie robi i jak inaczej naśladować tę samą procedurę.


0

Aby dołączyć wynik polecenia do pliku tekstowego zawierającego bieżącą datę, możesz zrobić coś takiego:

$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 }

0

To jest wyjaśnienie ...

Poświadczenie PowerShell RUNAS / SAVECRED „nie jest bezpieczny”, wypróbował go i dodaje tożsamość administratora oraz hasło do pamięci podręcznej poświadczeń i może być używany w innym miejscu OOPS !. Jeśli to zrobiłeś, sugeruję sprawdzenie i usunięcie wpisu.

Przejrzyj swój program lub kod, ponieważ zgodnie z zasadą Microsoft nie można mieszać kodu użytkownika i administratora w tym samym obiekcie blob bez UAC (punktu wejścia), aby uruchomić program jako administrator. To byłoby sudo (to samo) w systemie Linux.

UAC ma 3 typy, nie patrz, monit lub punkt wejścia wygenerowany w manifeście programu. Nie podnosi poziomu programu, więc jeśli nie ma UAC i potrzebuje administratora, zakończy się niepowodzeniem. Kontrola konta użytkownika, choć jako wymóg administratora, jest dobra, zapobiega wykonywaniu kodu bez uwierzytelnienia i zapobiega wykonaniu scenariusza z mieszanymi kodami na poziomie użytkownika.


To powinien być komentarz, nie jest to rozwiązanie pytania (tylko sposób działania forum; treść jest przydatna, ale nie jest rozwiązaniem).
— bgmCoder

-2

Okazuje się, że było to zbyt łatwe. Wszystko, co musisz zrobić, to uruchomić cmd jako administrator. Następnie wpisz explorer.exei naciśnij klawisz Enter. To otwiera Eksploratora Windows . Teraz kliknij prawym przyciskiem myszy skrypt PowerShell, który chcesz uruchomić, wybierz „uruchom z PowerShell”, który uruchomi go w PowerShell w trybie administratora.

Może pojawić się prośba o włączenie zasad do uruchomienia, wpisz Y i wciśnij Enter. Teraz skrypt będzie działał w PowerShell jako administrator. W przypadku, gdy świeci na czerwono, oznacza to, że Twoje zasady jeszcze nie wpłynęły. Następnie spróbuj ponownie i powinno działać dobrze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.