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.