Запуск команди в якості адміністратора за допомогою PowerShell?


280

Ви знаєте, як, якщо ви адміністративний користувач системи і можете просто клацнути правою кнопкою миші скажімо, пакетний сценарій і запустити його як адміністратор, не вводячи пароль адміністратора?

Мені цікаво, як це зробити за допомогою сценарію PowerShell. Я не хочу вводити свій пароль; Я просто хочу імітувати метод « Запустити як адміністратор» правою кнопкою миші .

Все, що я читав поки що, вимагає від вас ввести пароль адміністратора.


Спробуйте gsudo. Безкоштовне відкрите джерело sudo для Windows, яке дозволяє виконувати як адміністратор з командного рядка. З'явиться спливаюче вікно UAC.
Джерардо Гриньолі

Відповіді:


312

Якщо поточна консоль не підвищена, і операція, яку ви намагаєтеся зробити, потребує підвищених привілеїв, тоді ви можете запустити shellsll за допомогою Run as administratorпараметра:

PS> Start-Process powershell -Verb runAs

1
Це здається єдиним способом успішного виконання. Однак додане вікно оболонки виявляється проблематичним у багатьох випадках. Я в кінцевому підсумку налаштував те, що викликало сценарій для запуску адміністратора (наприклад, через реєстр).
Jacek Gorgoń

17
Це відкриє нову консоль в іншому місці. Чи є спосіб запуститись як адміністратор у поточній робочій директорії?
Кодований контейнер

11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Дев Ананд Садасівам


1
Ви можете знайти документ тут: docs.microsoft.com/en-us/powershell/module/… для файлу .exe, дієслова можуть бути: Відкрити, RunAs, RunAsUser
Кевін

114

Ось доповнення до пропозиції Шая Леві (просто додайте ці рядки на початку сценарію):

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
}

Це призводить до того, що поточний сценарій передається новому процесу оболонки повноважень в режимі адміністратора (якщо поточний Користувач має доступ до режиму адміністратора і сценарій не запускається як адміністратор).


6
Це працювало для мене:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
Г. Ломбард

Легко модифікується, щоб просто випустити помилку, коли не запускається як адміністратор. Просто візьміть ifзаяву і помістіть throwвсередину тодішній блок.
jpmc26

2
@ Коментар G.Lombard мав тонку помилку синтаксису. Це те, що працювало для мене:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
angularsen

Єдиний синтаксис, який працював на мене, - це оригінальний пост, а не той, який висловив Г.Ломбард, ні андрей
Ніколя Моммаерц,

2
Я погоджуюся з використанням значення enum value ( [Security.Principal.WindowsBuiltInRole]::Administrator)) слід віддати перевагу аргументам рядків "Administrator"- я зіткнувся із захищеними середовищами безпеки із перейменованими вбудованими ролями
eXavier

104

Самостійний підйом сценарію PowerShell

Windows 8.1 / PowerShell 4.0 +

Один рядок :)

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
ну, технічно кажучи, все є "одним рядком", якщо форматувати так, але це не робить його фактичним "одним рядком"
нелегальний іммігрант

3
Відношення: якщо ви введете не-адміністратора в підказку, ви закінчитеся в нескінченному циклі вилки-виходу.
Мануель Фокс

3
але це не проходить аргументи
kyb

2
Для передачі аргументів я змінив її на: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
Ця відповідь не зберігає робочий каталог. Дивіться тут, що робить:
stackoverflow.com/a/57035712/2441655

45

Бенджамін Армстронг опублікував чудову статтю про самовивісні сценарії PowerShell . Є кілька незначних проблем з його кодом; модифікована версія на основі виправлень, запропонованих у коментарі, наведена нижче.

В основному він отримує ідентичність, пов'язану з поточним процесом, перевіряє, чи є він адміністратором, а якщо ні, створює новий процес PowerShell з правами адміністратора та припиняє старий процес.

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

Я не отримував належного вирішення назви сценарію та парами, тому я $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
завернув

Чи є якась перевага зробити це так, а не Start-Process? Мені цікаво відмінності між цим методом та іншими розміщеними вище та іншими темами. Вони обидва покладаються на .NET, але цей метод більш серйозно ...
ZaxLofful

Я виявив, що також дуже корисні різні коментарі, пов'язані з прямим посиланням на пост Армстронга (початкове речення цієї публікації).
BentChainRing

2
Ця відповідь не зберігає робочий каталог. Дивіться тут, що робить:
stackoverflow.com/a/57035712/2441655

22

Ви можете створити пакетний файл ( *.bat), який запускає ваш скрипт повноважень з адміністративними привілеями при двічі клацанні. Таким чином, вам не потрібно нічого змінювати у своєму скрипті повноважень. Для цього створіть пакетний файл з тим самим іменем та місцем розташування вашого скрипта повноважень, а потім помістіть у нього такий вміст:

@echo off

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

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

Це воно!

Ось пояснення:

Якщо припустити, що ваш сценарій повноважень стоїть на шляху C:\Temp\ScriptTest.ps1, ваш пакетний файл повинен мати шлях C:\Temp\ScriptTest.bat. Коли хтось виконає цей пакетний файл, відбудуться наступні дії:

  1. Cmd виконає команду

    powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
  2. Відкриється новий сеанс передачі повноважень, і буде виконана наступна команда:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. Ще один новий сеанс повноважень з адміністративними привілеями відкриється в system32папці і наступні аргументи будуть передані їй:

    -ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
  4. Наступна команда буде виконана з адміністративними привілеями:

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

    Після того, як аргументи шляху та імені сценарію подвійно цитуються, вони можуть містити пробіл або окремі символи лапки ( ').

  5. Поточна папка зміниться з system32на C:\Tempта сценарій ScriptTest.ps1буде виконаний. Після того, як параметр -NoExitбуде передано, вікно не буде закрито, навіть якщо ваш скрипт повноважень передає якийсь виняток.


Якщо я це зроблю, я отримую спливаюче вікно, яке запитує мене, чи дозволяю PowerShell вносити зміни до моєї системи. Це робить його непридатним для автоматизації.
John Slegers

@JohnSlegers, якщо вам потрібно автоматизувати це, ви відповідаєте за те, щоб автоматизований процес виконувався як адміністратор. Якщо ви могли автоматично підняти процес без адміністрування до процесу адміністратора без взаємодії з користувачем, це перешкоджатиме меті вимагати, щоб процес мав в першу чергу права адміністратора.
meustrus

@meustrus: Як інженер випуску , моя робота передбачає створення та підтримку процесів збирання, які запускаються повністю автоматично, періодично, або при дотриманні певних критеріїв. Деякі з цих процесів потребують привілеїв адміністратора, а необхідне введення користувачем робить процес непридатним у цьому контексті. - У Linux ви можете досягти цього за допомогою sudoкоманди та налаштування користувача, якого ви використовуєте для автоматизованого процесу NOPASSWD: ALLу sudoersфайлі .
John Slegers

1
Це краща відповідь, ніж інші, оскільки він зберігає робочий каталог. Я зібрав деякі однорядкові варіанти цього підходу тут (один для CMD / партії, один для запису контекстного меню провідника, і один для PowerShell): stackoverflow.com/a/57033941/2441655
Venryx

17

Ось самовивісний фрагмент сценаріїв Powershell, який зберігає робочий каталог :

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

Збереження робочого каталогу важливо для сценаріїв, які виконують операції відносно шляху. Майже всі інші відповіді не зберігають цей шлях, що може спричинити несподівані помилки в решті сценарію.

Якщо ви краще не використовуєте самовивісний сценарій / фрагмент, а натомість просто хочете простий спосіб запустити сценарій як адміністратор (наприклад, з контекстного меню Explorer), дивіться іншу мою відповідь тут: https: // stackoverflow .com / a / 57033941/2441655


16

Використання

#Requires -RunAsAdministrator

поки не заявлено. Здається, існує лише з моменту PowerShell 4.0.

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

Коли цей параметр перемикання додається до вашої заяви вимагає, він визначає, що сеанс Windows PowerShell, в якому ви запускаєте скрипт, потрібно починати з підвищених прав користувача (Запустити як адміністратор).

Мені це здається гарним способом зробити це, але я ще не впевнений у досвіді на місцях. Програми PowerShell 3.0, ймовірно, ігнорують це, або ще гірше, дають помилку.

Коли сценарій запускається як неадміністратор, надається така помилка:

Сценарій 'StackOverflow.ps1' неможливо запустити, оскільки він містить оператор "#requires" для запуску адміністратора. Поточний сеанс Windows PowerShell не працює як адміністратор. Запустіть Windows PowerShell, скориставшись опцією Запустити як адміністратор, та спробуйте запустити сценарій ще раз.

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

7
На жаль, це все, щоб зробити скрипт з помилкою, якщо оболонка не має права адміністратора. Вона не піднімається сама собою.
Яцек Горгонь

Здається, PS3 видає помилку, як було запропоновано. Я отримую Parameter RunAsAdministrator requires an argument. @akauppi Я не переконаний, що вони завжди думають.
jpmc26

14

Ви можете легко додати деякі записи реєстру, щоб отримати контекстне меню "Запустити як адміністратор" для .ps1файлів:

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)

В основному при HKCR:\Microsoft.PowershellScript.1\Shell\runas\commandвстановленні значення за замовчуванням викликати сценарій за допомогою Powershell.


Це не працює, ви створюєте клавішу "(за замовчуванням)", а не оновлюєте значення ключа "(за замовчуванням)". Мені вдалося конденсувати код до однолінійки, яка працює на мене. Ви можете протестувати? Новий елемент-шлях "Реєстр :: HKEY_CLASSES_ROOT \ Microsoft.PowershellScript.1 \ Shell \ runas \ command" -Force -Name '' -Value '"c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -noexit "% 1" '
Шей Леві

@Shay Levy - Привіт Шай, дякую за оновлений. Я оновив відповідь на це. Це справді працює. Але я працював так само, хоч і був багатослівним. Я не робив багато редагування реєстру з Powershell, але робити це з "(за замовчуванням)" було чимось, що я бачив як приклад. Він не створив новий ключ (який би мав щось на зразок за замовчуванням), але оновив ключ за замовчуванням, як очікувалося. Ви спробували це чи просто здогадалися з (default)частини?
manojlds

Я спробував це. Він створив клавішу "(за замовчуванням)" під командною клавішею.
Шей Леві

Це працювало для мене після незначних змін у значенні реєстру: "c: \ windows \ system32 \ windowspowershell \ v1.0 \ powershell.exe" -ExecutionPolicy RemoteSigned -NoExit "& '% 1'"
MikeBaz - MSFT

1
Значення реєстру у відповіді має всілякі проблеми. Він насправді не виконує команду і не належним чином цитує ім'я скрипта (це означає, що він розбивається на шляхи з пробілами). Я успішно використовую таке:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"
Кал Зекдор

10

Код, розміщений Джонатаном та Шаєм Леві, не працював для мене.

Будь ласка, знайдіть робочий код нижче:

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
Дуже корисне та практичне рішення: просто довірив це моєму сценарію, і воно працює.
CDuv

3
@Abatonime Як щодо того, щоб ви зазначили, що легко пропустити відмінності на користь своїх читачів? Чесно кажучи, ця зміна не варта більше, ніж коментар до іншої відповіді.
jpmc26

8

Потрібно повторно запустити сценарій з адміністративними привілеями та перевірити, чи сценарій був запущений у такому режимі. Нижче я написав сценарій, який має дві функції: DoElevatedOperations і DoStandardOperations . Ви повинні розмістити свій код, який вимагає прав адміністратора, у перший, а стандартний - у другий. IsRunAsAdmin змінна використовується для визначення режиму адміністратора.

Мій код - це спрощений витяг із сценарію Microsoft, який автоматично створюється під час створення пакету програм для додатків Windows Store.

param(
    [switch]$IsRunAsAdmin = $false
)

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

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

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

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

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

function DoStandardOperations
{
    Write-Host "Do standard operations"

    LaunchElevated
}


#
# Main script entry point
#

if ($IsRunAsAdmin)
{
    DoElevatedOperations
}
else
{
    DoStandardOperations
}

7

Додаю мої 2 копійки. Моя проста версія, заснована на чистому сеансі, який працює весь час до цих пір в Windows 7 / Windows 10. Чому над цим ускладнювати?

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

просто додайте до вершини сценарію, і він працюватиме як адміністратор.


1
чи є спосіб надіслати повідомлення користувачеві після того, як на екрані відобразиться повідомлення "Доступ заборонено"?
ycomp

... або взагалі уникати повідомлення
Günter Zöchbauer

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

отримання помилок для цього,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>, Ви можете встановити його на bypass Але це bypassможе бути небезпечно. Встановити йогоAllSigned
AliFurkan

5

Така поведінка за задумом. Існує кілька шарів безпеки, оскільки Microsoft дійсно не хотів, щоб файли .ps1 були останнім вірусом електронної пошти. Деякі люди вважають, що це суперечить самому поняттю автоматизації завдань, що справедливо. Модель безпеки Vista + - це "деавтоматизувати" речі, тим самим зробивши користувачем все в порядку.

Однак, я підозрюю, що якщо ви запустили повноцінний патрон як підвищений, він повинен мати можливість запускати пакетні файли, не вимагаючи пароля ще раз, поки ви не закриєте powerhell.


5

Ви також можете змусити програму відкриватися як адміністратор, якщо у вас, звичайно, є обліковий запис адміністратора.

введіть тут опис зображення

Знайдіть файл, клацніть правою кнопкою миші> властивості> Ярлик> Розширений і поставте прапорець Запустити як адміністратор

Потім натисніть кнопку ОК.


1
Як ви це сценарій?
Дітер

4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShellтам знаходиться ярлик PowerShell. Він також все-таки переходить в інше місце, щоб викликати фактичний 'exe' ( %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe).

Оскільки PowerShell керується профілем користувача, коли стосуються дозволів; якщо ваше ім’я користувача / профіль має дозволи щось робити, то під цим профілем в PowerShell, як правило, ви також можете це зробити. Зважаючи на це, було б доцільно, щоб ви змінили ярлик, який знаходиться під вашим профілем користувача, наприклад,C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell .

Клацніть правою кнопкою миші та натисніть властивості. Натисніть кнопку "Додатково" на вкладці "Ярлик", розташованій прямо під текстовим полем "Коментарі" праворуч від двох інших кнопок "Відкрити розташування файлу" та "Змінити значок" відповідно.

Поставте прапорець "Запустити як адміністратор". Клацніть OK, потім Applyі OK. Ще раз клацніть правою кнопкою миші піктограму з написом "Windows PowerShell", розташовану вC:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell і виберіть "Прикріпити до меню" Пуск "/ панелі завдань".

Тепер, коли ви натискаєте на цю іконку, вона викликатиме UAC для ескалації. Вибравши "ТАК", ви помітите, що консоль PowerShell відкрита, і вона буде позначена "Адміністратор" у верхній частині екрана.

Щоб піти на крок далі ... ви можете клацнути правою кнопкою миші той самий ярлик ярлика у вашому розташуванні профілю Windows PowerShell та призначити ярлик клавіатури, який буде робити те саме, що ви натиснули нещодавно доданий значок. Тож, де написано "Клавіша швидкого доступу", кладіть комбінацію клавіш / клавіш на зразок: Ctrl+ Alt+ P P(для PowerShell) . Клацніть Applyі OK.

Тепер все, що вам потрібно зробити, це натиснути на цю комбінацію кнопок, яку ви призначили, і ви побачите, що вам потрібно викликати UAC, і після вибору "ТАК" ви побачите консоль PowerShell і на заголовку з'явиться "Administrator".


Чувак :) Ключове слово у питанні ОП - сценарій !! Не якесь рішення, що клацнуло мишкою користувача.
Крістіан

3

Я знайшов спосіб це зробити ...

Створіть пакетний файл, щоб відкрити свій сценарій:

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

Потім створіть ярлик, скажіть на робочому столі (клацніть правою кнопкою миші Створити -> Ярлик ).

Потім вставте це в місце:

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

Під час першого відкриття вам доведеться ввести свій пароль один раз. Потім це збереже його в менеджері облікових даних Windows.

Після цього ви зможете запускатися як адміністратор, не вводячи ім’я користувача або пароль адміністратора.


/ savecred не є безпечним!
Натан їде

Це єдине рішення, яке не використовує графічний запит піднесення, який може бути недоступним на віддаленому сеансі.
DustWolf

3

Проблема з відповідями @pgk та @Andrew Odri полягає в тому, коли у вас є параметри сценарію, особливо коли вони є обов'язковими. Вирішити цю проблему можна за допомогою наступного підходу:

  1. Користувач клацає правою кнопкою миші файл .ps1 і вибирає "Запустити з PowerShell": запитайте його про параметри через поля введення (це набагато кращий варіант, ніж використовувати атрибут параметра HelpMessage );
  2. Користувач виконує сценарій через консоль: дозвольте йому передати потрібні параметри і нехай консоль змусить його повідомити про обов'язкові.

Ось як би код, якби сценарій мав обов'язкові параметри ComputerName і 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

Низка відповідей тут близька, але трохи більше роботи, ніж потрібно.

Створіть ярлик для свого сценарію та налаштуйте його на "Запустити як адміністратор":

  • Створіть ярлик.
  • Клацніть ярлик і відкрийте його правою кнопкою миші Properties...
  • Змінити Targetз <script-path>доpowershell <script-path>
  • Клацніть Advanced...та увімкнітьRun as administrator

2

Ще простішим рішенням є те, що ви також можете клацнути правою кнопкою миші на "C: \ Windows \ System32 \ cmd.exe" і вибрати "Запустити як адміністратор", тоді ви можете запустити будь-яку програму як адміністратор, не вводячи пароля.


2

Я використовую рішення нижче. Він обробляє stdout / stderr за допомогою функції транскрипції та правильно передає вихідний код батьківському процесу. Потрібно відкоригувати стежку стежка / ім'я файлу.

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

Це втрачає всі аргументи виклику
Гільєрмо

2

Ось як запустити команду з підвищеними повноваженнями та зібрати її вихідну форму в пакетному файлі Windows в одній команді (тобто, не писати скрипт оболонки з повноваженнями 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'

Зверху ви бачите, що я спершу запускаю оболонку повноважень з підвищеним підказкою, а потім прошу, щоб запустити ще одну команду оболонки (під оболонку) для запуску команди.


1

Поверх відповіді Шей Леві дотримуйтесь наведених нижче налаштувань (лише один раз)

  1. Запустіть PowerShell з правами адміністратора.
  2. Виконайте питання про переповнення стека. PowerShell каже: "виконання скриптів вимкнено в цій системі". .
  3. Помістіть, наприклад, свій .ps1 файл у будь-яку з PATHпапок. Папка Windows \ System32

Після налаштування:

  1. Натисніть Win+R
  2. Викликати powershell Start-Process powershell -Verb runAs <ps1_file>

Тепер ви можете запустити все лише в одному командному рядку. Вищезазначене працює на Windows 8 Basic 64-розрядний.


1

Найнадійніший спосіб, який я знайшов, - це загортати його в самовивісний .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 перевіряє, чи ви вже є адміністратором, і при необхідності повторно запускає сценарій як адміністратор. Це також запобігає відкриттю сторонніх вікон "cmd" за допомогою 4-го параметра ShellExecute()встановити на 0.


Хороша відповідь, але я спробував це і не вийшло (і вийшов із командного рядка, з якого я його викликав). Я виправив це так: я змінив перший EXITна а, GOTO :EOFа другий видалив. Крім того, команда "І" cd %~dp0повинна бути cd /d %~dp0розміщена першою командою після @echo off. Таким чином, вам не потрібен абсолютний шлях того .ps1чи іншого, просто помістіть його в ту саму папку, що і .bat. Якщо вам потрібно побачити результат, змініть четвертий параметр на 1.
cdlvcdlv

Який O / S та версію ви використовуєте?
Джо Кодер,

Windows 7 SP1 Ultimate. У мене є система на C: але також дані та портативні програми в D: головним чином (та декілька інших накопичувачів). До речі ... що робити, якщо програма / скрипт використовують параметри? Яка була б mshtaкоманда?
cdlvcdlv

Я думаю, ви, можливо, помилилися у своєму тестуванні, оскільки сценарій працює просто чудово. До речі, він розроблений для виходу з cmdпроцесу виклику, щоб його не "виправити", але я радий, що ви змогли змінити його відповідно до своїх потреб.
Джо Кодер

Гаразд, якщо ви хочете вийти з cmd(я цього не зробив). Щодо інших змін, я думаю, що це виправлення, тому що моя версія буде працювати для нас обох, тоді як ваша не для мене, тобто моя більш загальна (зверніться до сценарію різних дисків). У будь-якому випадку, дуже розумний підхід.
cdlvcdlv

0

Я не бачив свого способу зробити це раніше, тому спробуйте це. Це легко простежити і має значно менший слід:

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

Дуже просто, якщо поточний сеанс Powershell був викликаний з правами адміністратора, відомий SID групи адміністраторів з’явиться в групах, коли ви захопите поточну особу. Навіть якщо обліковий запис є членом цієї групи, SID не з’явиться, якщо процес не буде викликано підвищеними обліковими записами.

Майже всі ці відповіді є варіантом надзвичайно популярного методу Бен Армстронга від Microsoft, як його досягти, але насправді не розуміючи, що він насправді робить, і як інакше наслідувати ту саму процедуру.


0

Щоб додати вихід команди до імені текстового файлу, який включає поточну дату, ви можете зробити щось подібне:

$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

Це уточнення ...

Вхідний обліковий запис RUNAS / SAVECRED "не є безпечним", спробував його, і він додає ідентифікатор і пароль адміністратора в кеш-пам'ять облікових даних і може використовуватися в іншому місці OOPS !. Якщо ви зробили це, я пропоную вам перевірити та видалити запис.

Перегляньте свою програму чи код, оскільки політика Microsoft полягає в тому, що ви не можете змішати код користувача та адміністратора в одній і тій же кодовій точці без UAC (точки входу) для виконання програми як адміністратора. Це було б судо (те саме) в Linux.

UAC має 3 типи: dont'see, підказка або точка входу, сформована в маніфесті програми. Він не піднімає програму, тому якщо немає UAC і йому потрібен адміністратор, він вийде з ладу. Хоча UAC як вимога адміністратора є хорошою, він запобігає виконанню коду без автентифікації та запобігає виконанню змішаного коду на рівні користувача.


Це має бути коментар, це не вирішення питання (саме те, як працює форум; ваш вміст корисний, але не є рішенням).
bgmCoder

-2

Виявляється, це було занадто просто. Все, що вам потрібно зробити, це запустити cmd як адміністратор. Потім введіть explorer.exeі натисніть клавішу Enter. Це відкриває Провідник Windows . Тепер клацніть правою кнопкою миші на вашому скрипті PowerShell, який ви хочете запустити, виберіть "запустити з PowerShell", який запустить його в PowerShell в режимі адміністратора.

Він може попросити увімкнути політику для запуску, введіть Y та натисніть клавішу Enter. Тепер сценарій працюватиме в PowerShell як адміністратор. Якщо вона працює в червоному кольорі, це означає, що ваша політика ще не вплинула. Потім спробуйте ще раз, і це повинно працювати добре.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.