PowerShell: запуск команды от имени администратора
вы знаете, как, если вы являетесь административным пользователем системы, и вы можете просто щелкнуть правой кнопкой мыши, скажем, пакетный скрипт и запустить его как администратор без ввода пароля администратора?
Мне интересно, как это сделать со сценарием PowerShell. Я не хочу вводить свой пароль; я просто хочу имитировать щелчок правой кнопкой мыши Запуск От Имени Администратора метод.
все, что я читал до сих пор требует от вас ввести пароль администратора.
24 ответов
если текущая консоль не повышена, а операция, которую вы пытаетесь выполнить, требует повышенных привилегий, вы можете запустить powershell с опцией "Запуск от имени администратора"
PS> Start-Process powershell -Verb runAs
вот дополнение к предложению Шая Леви (просто добавьте эти строки в начале скрипта):
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 в режиме администратора (если текущий пользователь имеет доступ к режиму администратора, а сценарий не запускается как администратор).
Самоподъемный сценарий 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
Бенджамин Армстронг опубликовал отличная статья о самоподъемных сценариях 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");
вы можете создать пакетный файл (*.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
. При выполнении этого пакетного файла выполняются следующие действия:
-
cmd выполнит команду
powershell -Command "Start-Process powershell \"-ExecutionPolicy Bypass -NoProfile -NoExit -Command `\"cd \`\"C:\Temp\`\"; & \`\".\ScriptTest.ps1\`\"`\"\" -Verb RunAs"
-
откроется новый сеанс powershell и будет выполнена следующая команда:
Start-Process powershell "-ExecutionPolicy Bypass -NoProfile -NoExit -Command `"cd \`"C:\Temp\`"; & \`".\ScriptTest.ps1\`"`"" -Verb RunAs
-
еще один новый сеанс powershell с правами администратора откроется в
system32
папка и следующее ему будут переданы аргументы:-ExecutionPolicy Bypass -NoProfile -NoExit -Command "cd \"C:\Temp\"; & \".\ScriptTest.ps1\""
-
следующая команда будет выполнена с правами администратора:
cd "C:\Temp"; & ".\ScriptTest.ps1"
после того, как путь к сценарию и имя аргументов двойные кавычки, они могут содержать пробелы или одинарные кавычки символов (
'
). текущая папка изменится с
system32
toC:\Temp
и скриптScriptTest.ps1
будет выполнен. После параметра-NoExit
было передано, окно не будет закрыто, даже если сценарий powershell создает некоторое исключение.
вы можете легко добавить некоторые записи реестра, чтобы получить контекстное меню "запуск от имени администратора" для .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.
используя
#Requires -RunAsAdministrator
пока не указано. Кажется, он существует только с PowerShell 4.0.
http://technet.microsoft.com/en-us/library/hh847765.aspx
когда этот параметр коммутатора добавляется в инструкцию requires, он указывает, что сеанс Windows PowerShell, в котором вы находитесь запустив скрипт должен быть запущен с повышенными правами пользователя (Run as Администратор.)
когда скрипт запускается как неадминистратор, выдается следующая ошибка:
скрипт ' StackOverflow.ps1 ' не может быть запущен, потому что он содержит "#необходима" инструкция для запуска от имени администратора. Электрический ток оболочка Windows PowerShell сеанс выполняется не от имени администратора. Начать Windows PowerShell с помощью параметра Запуск от имени администратора, а затем попробуйте запустить сценарий еще раз.
+ CategoryInfo : PermissionDenied: (StackOverflow.ps1:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : ScriptRequiresElevation
код, опубликованный Джонатаном и Шей Леви, не работал для меня.
пожалуйста, найдите рабочий код ниже:
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"
вам нужно перезапустить сценарий с правами администратора и проверить, был ли сценарий запущен в этом режиме. Ниже я написал скрипт, который имеет две функции:DoElevatedOperations и стандартные операции. Вы должны поместить свой код, требующий прав администратора, в первую и стандартные операции во вторую. The 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
}
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, потом применить и OK. Еще раз щелкните правой кнопкой мыши значок с надписью "Windows PowerShell" расположен в C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell
и выберите "Pin to Start Menu / Taskbar".
теперь всякий раз, когда вы нажимаете этот значок, он будет вызывать УАК для эскалации. После выбора " да "вы заметите, что консоль PowerShell открыта, и в верхней части экрана она будет помечена как" администратор".
чтобы сделать шаг дальше... вы можете щелкнуть правой кнопкой мыши тот же ярлык значка в вашем профиле Windows PowerShell и назначить сочетание клавиш, которое будет делать то же самое как будто вы нажали на недавно добавленный значок. Так что где написано "горячую клавишу" на клавиатуре сочетание кнопка/как: Ctrl + Alt + PP (для PowerShell). Нажмите применить и OK.
теперь все, что вам нужно сделать, это нажать эту комбинацию кнопок, которую вы назначили, и вы увидите, что UAC вызывается, и после выбора "да" вы увидите консоль PowerShell и " администратор" отображается в строке заголовка.
вы также можете заставить приложение открыться как администратор. Если у вас есть учетная запись администратора, конечно.
найдите файл, щелкните правой кнопкой мыши > Свойства > ярлык > Дополнительно и проверьте Запуск от имени администратора
затем нажмите OK.
ряд ответов здесь близки, но немного больше работы, чем нужно.
создайте ярлык для своего скрипта и настройте его на "запуск от имени администратора":
- создать ярлык.
- щелкните правой кнопкой мыши ярлык и откройте
Properties...
- редактировать
Target
С<script-path>
topowershell <script-path>
- клик дополнительно... и включения
Run as administrator
Это поведение по дизайну. Существует несколько уровней безопасности, так как Microsoft действительно не хотела .ps1 файлы, чтобы быть последним вирусом электронной почты. Некоторые люди считают, что это противоречит самому понятию автоматизации задач, что справедливо. Модель безопасности Vista+ заключается в" деавтоматизации " вещей, что делает их приемлемыми для пользователя.
однако я подозреваю, что если вы запустите powershell как повышенный, он должен иметь возможность запускать пакетные файлы без запроса пароля снова, пока вы закройте powershell.
другое более простое решение заключается в том, что вы также можете щелкнуть правой кнопкой мыши "C:\Windows\System32\cmd - ... exe "и выберите" Запуск от имени администратора", то вы можете запустить любое приложение от имени администратора без предоставления пароля.
Я нашел способ сделать это...
создайте пакетный файл, чтобы открыть скрипт:
@echo off
START "" "C:\Scripts\ScriptName.ps1"
затем создайте ярлык на рабочем столе, скажем (щелкните правой кнопкой мыши новая ->ярлык).
затем вставьте это в местоположение:
C:\Windows\System32\runas.exe /savecred /user:*DOMAIN*\*ADMIN USERNAME* C:\Scripts\BatchFileName.bat
при первом открытии вам нужно будет ввести пароль один раз. Затем он будет сохранен в диспетчере учетных данных Windows.
после этого вы должны иметь возможность работать как администратор без необходимости вводить имя пользователя или пароль администратора.
проблема с @pgk и @Andrew Odriответы-это когда у вас есть параметры скрипта, особенно когда они обязательны. Вы можете решить эту проблему, используя следующий подход:
- пользователь щелкает правой кнопкой мыши.ps1 file и выбирает "Run with PowerShell": спросите его о параметрах через поля ввода (это гораздо лучший вариант, чем использовать HelpMessage атрибут параметр);
- в пользователь выполняет скрипт через консоль: позволяет ему передавать нужные параметры, а консоль вынуждает его сообщать обязательные.
вот как был бы код, если бы скрипт имел Имя_компьютера: и порт обязательные параметры:
[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
поверх ответа Шей Леви следуйте приведенной ниже настройке (только один раз)
- запустите PowerShell с правами администратора.
- следуйте за вопросом переполнения стека PowerShell говорит: "выполнение сценариев отключено в этой системе.".
- положите ваш .ps1 файл в любом из
PATH
папки, например. Папка Windows\System32
после настройки:
- пресс Win + R
- Invoke
powershell Start-Process powershell -Verb runAs <ps1_file>
теперь вы можете запустить все в одной командной строке. Вышеизложенное работает на 64-разрядной версии Windows 8 Basic.
самый надежный способ, который я нашел, это обернуть его в самоподъемный .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
The .bat проверяет, являетесь ли вы администратором, и при необходимости перезапускает сценарий как администратор. Это также предотвращает открытие посторонних окон " cmd " с 4-м параметром ShellExecute()
значение 0
.
Я использую Решение ниже. Он обрабатывает 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
Я не видел своего собственного способа сделать это раньше, поэтому попробуйте это. Это намного легче следовать, и имеет гораздо меньший след:
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 Бена Армстронга о том, как его выполнить, не понимая, что он на самом деле делает, и как еще эмулировать ту же самую процедуру.
чтобы добавить вывод команды в текстовое имя файла, которое включает текущую дату, вы можете сделать что-то вроде этого:
$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 }
это разъяснение ...
учетные данные powershell RUNAS / SAVECRED "небезопасны", попробовали, и он добавляет удостоверение администратора и пароль в кэш учетных данных и может использоваться в другом месте OOPS!. Если вы сделали это, я предлагаю вам проверить и удалить запись.
просмотрите свою программу или код, потому что политика Microsoft заключается в том, что вы не можете смешивать код пользователя и администратора в одном и том же blob-коде без UAC (точки входа) для выполнения программы как администратора. Это будет sudo (то же самое) в Linux.
UAC имеет 3 типа, dont'see, приглашение или точку входа, сгенерированную в манифесте программы. Он не поднимает программу, поэтому, если нет UAC, и ему нужен администратор, он потерпит неудачу. Хотя UAC как требование администратора хорош, он предотвращает выполнение кода без аутентификации и предотвращает выполнение сценария смешанных кодов на уровне пользователя.
добавить мои 2 цента. Моя простая версия на основе net session, которая работает все время до сих пор в Windows 7 / Windows 10. Почему более усложнять?
if (!(net session)) {$path = "& '" + $myinvocation.mycommand.definition + "'" ; Start-Process powershell -Verb runAs -ArgumentList $path ; exit}
просто добавьте в верхнюю часть скрипта, и он будет работать как администратор.
оказывается, это было слишком легко. Все, что вам нужно сделать, это запустить cmd от имени администратора. Затем введите explorer.exe
и нажмите enter. Это открывает Проводник Windows.
Теперь щелкните правой кнопкой мыши на сценарии PowerShell, который вы хотите запустить, выберите "Запустить с PowerShell", который запустит его в PowerShell в режиме администратора.
он может попросить вас включить политику для запуска, введите Y и нажмите enter. Теперь скрипт будет работать в PowerShell от имени администратора. В случае, если он работает весь красный, это означает ваша политика еще не вступила в силу. Затем попробуйте еще раз, и он должен работать нормально.