您知道如果您是系统的管理员用户,您可以右键单击一个批处理脚本,然后以管理员身份运行它,而无需输入管理员密码?
我想知道如何用PowerShell脚本做到这一点。我不想输入我的密码;我只是想模仿右键单击Run As Administrator方法。
到目前为止,我读到的所有内容都要求您提供管理员密码。
您知道如果您是系统的管理员用户,您可以右键单击一个批处理脚本,然后以管理员身份运行它,而无需输入管理员密码?
我想知道如何用PowerShell脚本做到这一点。我不想输入我的密码;我只是想模仿右键单击Run As Administrator方法。
到目前为止,我读到的所有内容都要求您提供管理员密码。
当前回答
下面是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/a/57033941/2441655
其他回答
另一个更简单的解决方案是,你也可以右键单击“C:\Windows\System32\cmd.exe”,并选择“以管理员身份运行”,然后你就可以以管理员身份运行任何应用程序,而无需提供任何密码。
以下是对Shay Levi建议的补充(只需在脚本开头添加这些行):
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进程(如果当前User具有管理员模式,并且脚本不是以管理员身份启动)。
下面是如何运行一个提升的powershell命令,并在单个命令(i)中收集windows批处理文件中的输出形式。E不写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(子shell)运行命令。
@pgk和@Andrew Odri的回答的问题是当您有脚本参数时,特别是当它们是强制性的时。可以通过以下方法解决此问题:
用户右键单击.ps1文件并选择“使用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
你可以很容易地添加一些注册表项来为.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\命令设置默认值,使用Powershell调用脚本。