使用PowerShell以管理员身份运行命令?


280

您知道如果您是系统的管理用户,并且可以右键单击说一个批处理脚本并以管理员身份运行它,而无需输入管理员密码吗?

我想知道如何使用PowerShell脚本执行此操作。我不想输入密码;我只想模仿右键单击“以管理员身份运行”方法。

到目前为止,我阅读的所有内容都需要您提供管理员密码。


尝试gsudo。适用于Windows的免费开源sudo,可从命令行以admin身份执行。将出现一个UAC弹出窗口。
Gerardo Grignoli

Answers:


310

如果当前控制台未提升,而您要执行的操作需要提升的特权,则可以使用以下Run as administrator选项启动powershell :

PS> Start-Process powershell -Verb runAs

1
那似乎是成功做到这一点的唯一方法。但是,在很多情况下,添加的外壳窗口被证明是有问题的。我最终配置了调用脚本以管理员身份运行的任何内容(例如,通过注册表)。
JacekGorgoń15年

17
这将在其他位置打开一个新的控制台。有没有办法在当前工作目录中以管理员身份运行?
编码容器

11
start-process -verb runAs "<cmd>" -argumentlist "<args1> <args2>";)
Dev Anand Sadasivam


1
您可以在这里找到该文档:docs.microsoft.com/en-us/powershell/module/…对于.exe文件,这些动词可以是:Open,RunAs,RunAsUser
Kevin Xiong

114

这是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进程(如果当前用户有权访问管理员模式,并且脚本未以管理员身份启动)。


6
这对我if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
G. Lombard 2012年

轻松修改为不以管理员身份运行时仅抛出错误。只需接受该if语句,throw然后在then块中放入一个。
jpmc26 2014年

2
@ G.Lombard的注释有一个微妙的语法错误。这是对我if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
有用的

唯一对我有用的语法是在原始帖子中,而不是G.Lombard或anjdreas所使用的语法
Nicolas Mommaerts 2015年

1
我同意使用枚举值([Security.Principal.WindowsBuiltInRole]::Administrator))而不是字符串参数"Administrator"-我遇到了具有重命名内置角色的安全性
增强

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

142
好吧,从技术上讲,如果采用这种格式,则所有内容都是“一行”,但这并不能使其成为真正的“一行”
非法移民

3
缺点:如果在提示中输入非管理员用户,则将导致无休止的fork-exit循环。
Manuel Faux

3
但这不会通过args
kyb

2
为了传递args,我将其修改为: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

本杰明·阿姆斯特朗(Benjamin Armstrong)发表了一篇关于自提升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

我发现与直接链接到Armstrong的帖子(此帖子的初始句子)​​相关的各种评论也非常有帮助。
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. 当前文件夹将从更改system32C:\Temp,脚本ScriptTest.ps1将被执行。-NoExit传递参数后,即使您的Powershell脚本抛出某些异常,也不会关闭该窗口。


如果执行此操作,则会弹出一个对话框,询问我是否允许PowerShell对系统进行更改。这使其无法用于自动化。
John Slegers

@JohnSlegers,如果需要使其自动化,则有责任确保自动化过程以管理员身份运行。如果您可以在没有用户交互的情况下将非管理员进程自动提升为管理员进程,那将使要求进程首先具有管理员权限的目的无法实现。
meustrus

@meustrus:作为发布工程师,我的工作涉及创建和维护构建流程,这些构建流程可以定期或在满足某些条件时全自动运行。其中一些进程需要管理员权限,并且需要用户输入才能使该进程在这种情况下不可用。—在Linux中,您可以通过使用sudo命令并文件中配置用于自动过程的用户来实现NOPASSWD: ALLsudoers
John Slegers

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 / a / 57033941/2441655


16

使用

#Requires -RunAsAdministrator

尚未说明。它似乎仅在PowerShell 4.0之后才存在。

http://technet.microsoft.com/zh-CN/library/hh847765.aspx

当将此switch参数添加到require语句时,它指定必须以提升的用户权限(以管理员身份运行)启动运行脚本的Windows PowerShell会话。

对我来说,这似乎是解决问题的一种好方法,但是我不确定现场经验。PowerShell 3.0运行时可能会忽略此错误,或者更糟的是会给出错误。

当脚本以非管理员身份运行时,会出现以下错误:

无法运行脚本“ StackOverflow.ps1”,因为该脚本包含用于以管理员身份运行的“ #requires”语句。当前的Windows PowerShell会话未以管理员身份运行。使用“以管理员身份运行”选项启动Windows PowerShell,然后再次尝试运行脚本。

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

7
不幸的是,如果shell没有管理员权限,它只会使脚本失败并显示错误。它本身不会升高。
JacekGorgoń15年

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

@Shay Levy-嗨Shay,感谢您的更新。我已经用它更新了答案。确实有效。但是我工作的也很好,尽管它很冗长。我没有使用Powershell进行过多的注册表编辑,但我以“(默认)”为例进行了编辑。它没有创建新密钥(类似default的东西),但是确实按预期更新了默认密钥。您尝试过还是只是从(default)零件中猜测出来?
manojlds 2011年

我尝试过这个。它在命令键下创建了一个“(默认)”键。
谢伊·利维

在对注册表值进行一些细微更改后,这对我有用:“ 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

Jonathan和Shay Levy发布的代码对我不起作用。

请在下面找到工作代码:

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

您需要使用管理特权重新运行该脚本,并检查该脚本是否以该模式启动。下面,我编写了一个具有两个功能的脚本:DoElevatedOperationsDoStandardOperations。您应该将需要管理员权限的代码放入第一个,并将标准操作放入第二个。所述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

...或从根本上避免了消息
君特Zöchbauer

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

为此获取错误,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 19/12/28

1
@ user2305193 Set-ExecutionPolicy -ExecutionPolicy <PolicyName>,您可以将其设置为,bypass 但是bypass可能很危险。将其设置为AllSigned
AliFurkan

5

此行为是设计使然。由于Microsoft确实不希望.ps1文件成为最新的电子邮件病毒,因此存在多层安全保护。有些人发现这与任务自动化的概念背道而驰,这很公平。Vista +安全模型将使事物“自动化”,从而使用户可以接受。

但是,我怀疑如果将Powershell本身启动为提升版本,它应该能够运行批处理文件,而无需再次请求密码,直到关闭Powershell。


5

当然,如果您有管理员帐户,也可以强制应用程序以管理员身份打开。

在此处输入图片说明

找到文件,右键单击>属性>快捷方式>高级,然后选中以管理员身份运行

然后单击“确定”。


1
您如何编写脚本?
Dieter '18

4

C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell是PowerShell 快捷方式所在的位置。它也仍然转到另一个位置来调用实际的“ exe”(%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe)。

由于考虑到权限,PowerShell是由用户配置文件驱动的;如果您的用户名/配置文件有权执行某项操作,则可以在该配置文件下执行操作。话虽如此,您应该更改位于用户配置文件下的快捷方式,例如,这是很有意义的C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell

右键单击,然后单击属性。单击“快捷方式”选项卡下的“高级”按钮,该选项卡位于与其他两个按钮(分别为“打开文件位置”和“更改图标”)右侧相邻的“注释”文本字段下方。

选中显示为“以管理员身份运行”的复选框。单击OK,然后单击ApplyOK。再次右键单击位于其中的标有“ Windows PowerShell”的图标,C:\Users\"username"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Windows PowerShell然后选择“固定到开始菜单/任务栏”。

现在,无论何时单击该图标,它都会调用UAC进行升级。选择“是”后,您会注意到PowerShell控制台已打开,并且在屏幕顶部将其标记为“管理员”。

要更进一步...,您可以在Windows PowerShell的配置文件位置中右键单击相同的图标快捷方式,然后分配一个键盘快捷方式,其作用与单击最近添加的图标完全相同。因此,在显示“快捷键”的地方,将键盘键/按钮组合如下:Ctrl+ Alt+ P P(对于PowerShell)。点击ApplyOK

现在,您所要做的就是按下分配给您的按钮组合,您将看到UAC被调用,选择“是”后,您将看到一个PowerShell控制台,并且在标题栏上显示“管理员”。


杜德:) OP问题中的关键字是脚本!没有一些UI鼠标单击解决方案。
克里斯蒂安

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@Andrew Odri的答案是当你有脚本参数,特别是当他们是强制性的。您可以使用以下方法解决此问题:

  1. 用户右键单击.ps1文件,然后选择“使用PowerShell运行”:通过输入框询问他的参数(这比使用HelpMessage参数属性要好得多);
  2. 用户通过控制台执行脚本:允许他传递所需的参数,然后让控制台强制他通知必需的参数。

如果脚本具有ComputerNamePort强制参数,则代码如下:

[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

这丢失了所有调用争论
Guillermo Prandi

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(子Shell)来运行命令。


1

在Shay Levy的答案之上,请遵循以下设置(仅一次)

  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检查您是否已经是管理员,并在需要时以管理员身份重新启动脚本。它还可以防止使用ShellExecute()设置为的第4个参数打开无关的“ cmd”窗口0


很好的答案,但是我尝试了一下却没有用(退出了我从中调用它的命令行)。我以这种方式解决了:我将第EXIT一个更改为a,GOTO :EOF然后删除了第二个。另外,cd %~dp0应该将cd /d %~dp0AND与第一个命令放在后@echo off。这样,您就不需要两者的绝对路径.ps1,只需将其放置在与相同的文件夹中即可.bat。如果需要查看结果,请将第4个参数更改为1
cdlvcdlv

您正在运行哪个O / S和版本?
Joe Coder

Windows 7 SP1 Ultimate。我在C:中有系统,但在D:中主要有数据和可移植应用程序(以及其他几个驱动器)。顺便说一下...如果程序/脚本使用参数怎么办?会是什么mshta命令?
cdlvcdlv

我认为您可能在测试中出错,因为脚本可以正常工作。顺便说一句,它旨在退出调用cmd过程,因此不会“修复”它,但是我很高兴您能够根据需要对其进行修改。
Joe Coder

好的,如果您想退出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 Ben Armstrong的一种非常流行的方法的变体,该方法在不真正掌握其实际功能以及如何模仿同一例程的情况下如何完成它。


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

这是一个澄清...

Powershell RUNAS / SAVECRED凭证“不安全”,尝试了一下,并将管理员身份和密码添加到了凭证缓存中,并且可以在其他OOPS中使用。如果执行了此操作,建议您检查并删除该条目。

请复查您的程序或代码,因为Microsoft策略是,如果没有UAC(入口点)以admin身份执行程序,则不能在同一代码blob中混合用户代码和管理员代码。在Linux上这将是sudo(相同的东西)。

UAC具有3种类型,即“不可见”,在程序清单中生成的提示或入口点。它不会提升程序,因此,如果没有UAC并且需要管理员,它将失败。尽管作为管理员的要求,UAC很好,但是它阻止了未经身份验证的代码执行,并阻止了在用户级别执行混合代码方案。


这应该是评论,不是问题的解决方案(只是论坛的工作方式;您的内容有用,但不是解决方案)。
bgmCoder

-2

事实证明,这太简单了。您要做的就是以管理员身份运行cmd。然后输入explorer.exe并按Enter。这将打开Windows资源管理器。现在,右键单击要运行的PowerShell脚本,选择“使用PowerShell运行”,它将以管理员模式在PowerShell中启动。

它可能会要求您启用该策略以运行,键入Y并按Enter。现在,脚本将以管理员身份在PowerShell中运行。万一它全部变成红色,这意味着您的策略尚未生效。然后重试,它应该可以正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.