Запускать команду от имени администратора с помощью PowerShell?


280

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

Мне интересно, как это сделать с помощью скрипта PowerShell. Я не хочу вводить свой пароль; Я просто хочу имитировать метод запуска от имени администратора .

Все, что я прочитал, требует от вас ввода пароля администратора.


Попробуй gsudo. Бесплатный sudo с открытым исходным кодом для Windows, который позволяет запускать от имени администратора из командной строки. Появится всплывающее окно UAC.
Герардо Гриньоли

Ответы:


313

Если текущая консоль не имеет повышенных прав и для операции, которую вы пытаетесь выполнить, требуются повышенные привилегии, вы можете запустить powershell с Run as administratorпараметром:

PS> Start-Process powershell -Verb runAs

1
Кажется, это единственный способ сделать это успешно. Тем не менее, добавленное окно оболочки оказывается проблематичным во многих случаях. В итоге я настроил все, что вызывало скрипт для запуска от имени администратора (например, через реестр).
Яцек Горгонь

17
Это откроет новую консоль в другом месте. Есть ли способ работать от имени администратора в текущем рабочем каталоге?
Кодированный контейнер

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


1
Вы можете найти документ здесь: docs.microsoft.com/en-us/powershell/module/… для файла .exe, глаголы могут быть следующими: Open, RunAs, RunAsUser
Kevin Xiong

115

Вот дополнение к предложению Шей Леви (просто добавьте эти строки в начале сценария):

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
}

Это приводит к тому, что текущий сценарий передается новому процессу powershell в режиме администратора (если текущий пользователь имеет доступ к режиму администратора и сценарий не запускается от имени администратора).


6
Это сработало для меня:if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
Г. Ломбард

Легко модифицируется, чтобы просто выдать ошибку, когда не запускается от имени администратора. Просто возьмите ifутверждение и вставьте throwвнутрь блока then.
jpmc26

2
В комментарии @ G.Lombard была небольшая синтаксическая ошибка. Вот что сработало для меня:if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
angularsen

Только синтаксис , который работал для меня в исходное сообщение, а не один на G.Lombard ни anjdreas
Николя Mommaerts

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

105

Самоподъемный скрипт 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

145
Ну, технически говоря, все это «одна строка», если она отформатирована таким образом, но это не делает ее реальной «одной строкой»
нелегальный иммигрант

3
Недостаток: если вы введете не-администратора в приглашении, вы закончите бесконечным циклом разветвления-выхода.
Мануэль Фо

3
но это не проходит args
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
Venryx

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

Я не получал правильное разрешение имени скрипта и параметров, поэтому обернул выполнение в cmd.exe / c $newProcess = new-object System.Diagnostics.ProcessStartInfo “cmd.exe” $newProcess.Arguments = ‘/c ‘ + [System.Environment]::GetCommandLineArgs() $newProcess.WorkingDirectory = [environment]::CurrentDirectory
xverges

Есть ли какое-то преимущество в том, чтобы делать это вместо Start-Process? Мне любопытно о различиях между этим методом и другими, опубликованными выше, и в других темах. Они оба полагаются на .NET, но этот метод в большей степени ...
ZaxLofful

Мне также очень помогли различные комментарии, связанные с прямой ссылкой на пост Армстронга (первоначальное предложение этого поста).
BentChainRing

2
Этот ответ не сохраняет рабочий каталог. Смотрите здесь для того, который делает: stackoverflow.com/a/57035712/2441655
Venryx

22

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

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

Это оно!

Вот объяснение:

Предполагая, что ваш скрипт powershell находится в пути 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. Откроется новый сеанс powershell, и будет выполнена следующая команда:

    Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
  3. В system32папке откроется еще один новый сеанс PowerShell с правами администратора, и ему будут переданы следующие аргументы:

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

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

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

  5. Текущая папка изменится с system32на C:\Tempи скрипт ScriptTest.ps1будет выполнен. Как только параметр -NoExitбыл передан, окно не будет закрыто, даже если ваш скрипт powershell выдает какое-то исключение.


Если я сделаю это, я получу всплывающее окно с вопросом, разрешить ли PowerShell вносить изменения в мою систему. Это делает его непригодным для автоматизации.
Джон

@JohnSlegers, если вам нужно автоматизировать его, вы обязаны убедиться, что автоматизированный процесс запущен от имени администратора. Если бы вы могли автоматически повышать уровень неадминистративного процесса до админ-процесса без взаимодействия с пользователем, это поставило бы под угрозу цель требования, чтобы процесс имел права администратора в первую очередь.
meustrus

@meustrus: Как инженер по выпуску , моя работа заключается в создании и поддержке процессов сборки, которые выполняются полностью автоматически, либо периодически, либо при выполнении определенных критериев. Некоторые из этих процессов нуждаются в привилегиях администратора, и требование ввода пользователя делает процесс непригодным для использования в этом контексте. - В Linux, вы можете добиться этого с помощью sudoкоманды и настройки пользователя , используемый для автоматизированного процесса с NOPASSWD: ALLв sudoersфайле .
Джон

1
Это лучший ответ, чем другие, потому что он сохраняет рабочий каталог. Здесь я собрал несколько однострочных вариантов этого подхода (один для cmd / batch, один для записей контекстного меню Explorer и один для 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

Сохранение рабочего каталога важно для сценариев, которые выполняют операции, связанные с путем. Почти все другие ответы не сохраняют этот путь, что может привести к непредвиденным ошибкам в остальной части сценария.

Если вы не хотите использовать самоподъемный сценарий / фрагмент и вместо этого просто хотите легко запустить сценарий в качестве администратора (например, из контекстного меню Проводника), см. Мой другой ответ здесь: https: // stackoverflow .com / а / 57033941/2441655


16

С помощью

#Requires -RunAsAdministrator

пока не заявлено. Вроде бы там только начиная с PowerShell 4.0.

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

Когда этот параметр переключателя добавляется в ваш оператор require, он указывает, что сеанс 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.


Это не работает, вы создаете ключ (по умолчанию), а не обновляете значение ключа (по умолчанию). Мне удалось сжать код до одной строки, которая работает для меня. Вы можете проверить это? Новый элемент -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 - Привет, Шей, спасибо за обновленный. Я обновил ответ с этим. Это работает. Но тот, с которым я работал, хотя и был многословным. Я не слишком много редактировал с Powershell, но в качестве примера я сделал это с «(по умолчанию)». Он не создал новый ключ (который имел бы что-то вроде default), но обновил ключ по умолчанию, как и ожидалось. Вы попробовали это или только догадались из (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'"
Kal Zekdor

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.

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

... или вообще избежать сообщения
Гюнтер Цохбауэр

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 + состоит в том, чтобы «деавтоматизировать» вещи, тем самым заставляя пользователя их устраивать.

Однако я подозреваю, что если вы запустите сам PowerShell с повышенными правами, он сможет запускать пакетные файлы без повторного запроса пароля, пока вы не закроете PowerShell.


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, а в строке заголовка отобразится «Администратор».


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

3

Я нашел способ сделать это ...

Создайте командный файл, чтобы открыть ваш скрипт:

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

Затем создайте ярлык, на рабочем столе произнесите (щелкните правой кнопкой мыши New -> Shortcut ).

Затем вставьте это в место:

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

При первом открытии вам нужно будет один раз ввести пароль. Затем он сохранится в диспетчере учетных данных Windows.

После этого вы сможете работать от имени администратора без необходимости ввода имени пользователя или пароля администратора.


/ savecred не является безопасным!
Натан Гоингс

Это единственное решение, которое не использует графическое приглашение на повышение прав, которое может быть недоступно в удаленном сеансе.
DustWolf

3

Проблема с @pgk и @ Андрей Odri ответов «s, когда у вас есть параметры сценария, особенно когда они являются обязательными. Вы можете решить эту проблему, используя следующий подход:

  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

Ниже описано, как выполнить команду повышенного уровня powershell и собрать ее выходную форму в пакетном файле Windows в одну команду (т.е. без написания сценария ps1 powershell).

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'

Выше вы видите, что я сначала запускаю PowerShell с повышенными привилегиями, а затем запрашиваю, чтобы запустить еще один PowerShell (субоболочка) для запуска команды.


1

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

  1. Запустите PowerShell с правами администратора.
  2. Следуйте за вопросом переполнения стека PowerShell говорит: «В этой системе отключено выполнение сценариев». ,
  3. Поместите файл .ps1 в любую из PATHпапок, например. Папка Windows \ System32

После настройки:

  1. Нажмите Win+R
  2. Invoke powershell Start-Process powershell -Verb runAs <ps1_file>

Теперь вы можете запустить все в одной командной строке. Вышеуказанное работает на Windows 8 Basic 64-bit.


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на a GOTO :EOFи удалил второе. Кроме того, cd %~dp0должна быть cd /d %~dp0И помещена первая команда после @echo off. Таким образом, вам не нужен абсолютный путь .ps1, просто поместите его в ту же папку, что и .bat. Если вам нужно увидеть результат, измените 4-й параметр на 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 группы администраторов будет отображаться в группах при получении текущего идентификатора. Даже если учетная запись является членом этой группы, идентификатор безопасности не будет отображаться, если процесс не был вызван с повышенными учетными данными.

Почти все эти ответы представляют собой вариацию чрезвычайно популярного метода 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

Это уточнение ...

Учетные данные PowerShill RUNAS / SAVECRED «небезопасны», пробовали, и они добавляют идентификационные данные администратора и пароль в кэш учетных данных и могут использоваться в других местах OOPS !. Если вы сделали это, я предлагаю вам проверить и удалить запись.

Просмотрите вашу программу или код, поскольку в соответствии с политикой Microsoft вы не можете смешивать код пользователя и администратора в одном и том же двоичном объекте без UAC (точки входа) для выполнения программы от имени администратора. Это будет sudo (то же самое) в Linux.

UAC имеет 3 типа, dont'see, приглашение или точку входа, сгенерированные в манифесте программы. Это не повышает уровень программы, поэтому, если UAC отсутствует и требуется администратор, произойдет сбой. Хотя UAC является хорошим требованием администратора, он предотвращает выполнение кода без аутентификации и предотвращает выполнение сценария смешанного кода на уровне пользователя.


Это должен быть комментарий, это не решение вопроса (просто то, как работает форум; ваш контент полезен, но не является решением).
bgmCoder

-2

Оказывается, это было слишком легко. Все, что вам нужно сделать, это запустить cmd от имени администратора. Затем введите explorer.exeи нажмите Enter. Это открывает Windows Explorer . Теперь щелкните правой кнопкой мыши на сценарии PowerShell, который вы хотите запустить, выберите «запускать с PowerShell», который запустит его в PowerShell в режиме администратора.

Может потребоваться включить политику, введите Y и нажмите ввод. Теперь скрипт будет запускаться в PowerShell от имени администратора. Если он работает красным, это означает, что ваша политика еще не вступила в силу. Затем попробуйте еще раз, и он должен работать нормально.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.