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

Posted

技术标签:

【中文标题】使用 PowerShell 以管理员身份运行命令?【英文标题】:Running a command as Administrator using PowerShell? 【发布时间】:2011-12-03 05:01:17 【问题描述】:

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

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

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

【问题讨论】:

试试gsudo。适用于 Windows 的免费开源 sudo,允许从命令行以管理员身份执行。将出现一个 UAC 弹出窗口。 【参考方案1】:

如果当前控制台未提升并且您尝试执行的操作需要提升权限,那么您可以使用 以管理员身份运行 选项启动 powershell

PS> Start-Process powershell -Verb runAs

Microsoft Docs: Start-Process

【讨论】:

这是一个以管理员身份运行它的好方法。 CMD 窗口中,最短的版本是:powershell start cmd -v runas。要验证新获得的权限,请运行:net sess【参考方案2】:

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

【讨论】:

很容易修改为只在不以管理员身份运行时抛出错误。只需使用 if 语句并将 throw 放入 then 块中。 对我有用的唯一语法是在原始帖子中,而不是 G.Lombard 或 anjdreas 的语法 如果你想以管理员身份运行powershell,有没有办法抑制windows?对于需要静默运行的应用程序,让用户询问可能会很麻烦。 这个答案不保留工作目录。请参阅此处了解其中一个:***.com/a/57035712/2441655 当它在函数定义中时会失败。必须在外面,否则会打开一个新的管理窗口并立即关闭。【参考方案3】:

自提升 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

【讨论】:

好吧,从技术上讲,如果像这样格式化,一切都是“一行”,但这并不能使它成为真正的“一行” 缺点:如果你在提示符中输入非管理员,你会以无休止的 fork-exit 循环结束。 但这不通过参数 为了传递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 这个答案不保留工作目录。请参阅此处了解其中一个:***.com/a/57035712/2441655【参考方案4】:

Benjamin Armstrong 发布了excellent article about self-elevating PowerShell scripts。他的代码有一些小问题;下面是基于评论中建议的修复的修改版本。

基本上它获取与当前进程关联的身份,检查它是否是管理员,如果不是,则创建一个具有管理员权限的新 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 这样做而不是 Start-Process 有什么好处吗?我很好奇这种方法与上面和其他线程上发布的其他方法之间的差异。他们都依赖.NET,但这种方法更重...... 我发现与 Armstrong 帖子的直接链接相关的各种 cmets(本文的首句)也非常有帮助。 此答案不保留工作目录。请参阅此处了解其中一个:***.com/a/57035712/2441655【参考方案5】:

这是一个用于 Powershell 脚本的自升式 sn-p 保留工作目录

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

保留工作目录对于执行路径相关操作的脚本很重要。几乎所有其他答案都不保留此路径,这可能会导致脚本其余部分出现意外错误。

如果您不想使用自提升脚本/sn-p,而只是想要一种简单的方法以管理员身份启动脚本(例如,从资源管理器上下文菜单中),请在此处查看我的其他答案: https://***.com/a/57033941/2441655

【讨论】:

【参考方案6】:

您可以创建一个批处理文件 (*.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 更改为 C:\Temp 并且脚本ScriptTest.ps1 将被执行。一旦参数-NoExit被传递,窗口不会关闭,即使你的powershell脚本抛出了一些异常。

【讨论】:

如果我这样做,我会收到一个弹出窗口,询问我是否允许 PowerShell 对我的系统进行更改。这使得它无法用于自动化。 @JohnSlegers,如果您需要自动化,您有责任确保自动化流程以管理员身份运行。如果您可以在没有用户交互的情况下自动将非管理员进程提升为管理员进程,那将违背要求进程首先具有管理员权限的目的。 @meustrus :作为release engineer,我的工作涉及创建和维护完全自动运行的构建过程,无论是定期运行,还是在满足某些条件时运行。其中一些进程需要管理员权限,并且要求用户输入会使进程在此上下文中不可用。 — 在 Linux 中,您可以使用sudo 命令和configuring the user you use for automated process with NOPASSWD: ALL in the sudoers file 来实现此目的。 这是一个比其他答案更好的答案,因为它保留了工作目录。我在这里汇总了这种方法的一些单行变体(一个用于 cmd/batch,一个用于 Explorer 上下文菜单条目,一个用于 powershell):***.com/a/57033941/2441655 FWIW,@mems 编辑 #5 对我来说是错误的。 %scriptFolderPath% 之后添加的反斜杠对我造成了错误。【参考方案7】:

使用

#Requires -RunAsAdministrator

尚未说明。它似乎只存在于 PowerShell 4.0 之后。

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

当这个 switch 参数被添加到你的 requires 语句中时, 它指定您所在的 Windows PowerShell 会话 运行脚本必须以提升的用户权限启动 (以管理员身份运行)。

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

以非管理员身份运行脚本时,报错如下:

脚本“***.ps1”无法运行,因为它包含 以管理员身份运行的“#requires”语句。目前的 Windows PowerShell 会话未以管理员身份运行。开始 Windows PowerShell 使用“以管理员身份运行”选项,然后 尝试再次运行脚本。

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

【讨论】:

不幸的是,如果 shell 没有管理员权限,它所做的只是使脚本失败并出现错误。它不会自行升高。 PS3 似乎给出了建议的错误。我得到Parameter RunAsAdministrator requires an argument。 @akauppi 我不相信他们一直在思考。【参考方案8】:

您可以轻松添加一些注册表项以获得.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 调用脚本。

【讨论】:

它不起作用,您正在创建一个“(默认)”键,而不是更新“(默认)”键值。我能够将代码压缩为适合我的单行代码。你能测试一下吗?新项目-路径“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,感谢更新。我已经用它更新了答案。它确实有效。但我也曾使用过的那个,虽然它很冗长。我没有使用 Powershell 进行过多的 reg 编辑,但是使用“(默认)”进行编辑是我所看到的示例。它没有创建新密钥(类似于默认密钥),但确实按预期更新了默认密钥。您是尝试过还是只是从(default) 部分猜到了? 我试过了。它在命令键下创建了一个“(默认)”键。 在对注册表值进行一些小的更改后,这对我有用:“c:\windows\system32\windowspowershell\v1.0\powershell.exe”-ExecutionPolicy RemoteSigned -NoExit“&'%1' " 答案中的注册表值有各种问题。它实际上并没有运行命令,也没有正确引用脚本名称(这意味着它在带有空格的路径上中断)。我正在成功使用以下内容:"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit -command "& '%1'"【参考方案9】:

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"

【讨论】:

非常有用且实用的解决方案:只需将其附加到我的脚本中即可。 @Abatonime 为了读者的利益,您如何指出容易忽略的差异?老实说,这种变化不比对另一个答案的评论更有价值。【参考方案10】:

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

【讨论】:

【参考方案11】:

加上我的 2 美分。我的基于网络会话的简单版本目前在 Windows 7 / Windows 10 中一直有效。为什么过于复杂?

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

只需添加到脚本的顶部,它就会以管理员身份运行。

【讨论】:

有没有办法在显示“访问被拒绝”后向用户发送消息? ...或完全避免该消息 @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 Set-ExecutionPolicy -ExecutionPolicy <PolicyName>, 你可以设置成bypass 但是bypass 可能有危险。将其设置为AllSigned【参考方案12】:

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

找到文件,右键单击>属性>快捷方式>高级并检查以管理员身份运行

然后点击确定。

【讨论】:

如何编写脚本?【参考方案13】:

此行为是设计使然。由于 Microsoft 确实不希望 .ps1 文件成为最新的电子邮件病毒,因此存在多层安全性。有些人发现这与任务自动化的概念背道而驰,这是公平的。 Vista+ 安全模型是为了“去自动化”事物,从而让用户对它们感到满意。

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

【讨论】:

【参考方案14】:

这里的一些答案很接近,但比需要的工作多一点。

创建脚本的快捷方式并将其配置为“以管理员身份运行”:

创建快捷方式。 右键快捷方式打开Properties...Target<script-path> 编辑为powershell <script-path> 点击高级...并启用Run as administrator

【讨论】:

【参考方案15】:

以下是如何在单个命令中运行提升的 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)来运行命令。

【讨论】:

【参考方案16】:

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

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

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

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

更进一步...您可以在 Windows PowerShell 的配置文件位置右键单击相同的图标快捷方式,并分配一个键盘快捷方式,该快捷方式的作用与单击最近添加的图标完全相同。因此,在上面写着“快捷键”的地方,请输入键盘键/按钮组合,例如: Ctrl + Alt + PP (对于PowerShell)。单击应用确定

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

【讨论】:

Dude :) OP 问题中的关键字是脚本!不是一些 UI 鼠标点击解决方案。【参考方案17】:

我已经找到了一种方法……

创建一个批处理文件来打开你的脚本:

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

然后在桌面上创建一个快捷方式(右键单击新建 -> 快捷方式)。

然后将其粘贴到该位置:

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

首次打开时,您必须输入一次密码。然后将其保存在 Windows 凭据管理器中。

在此之后,您应该能够以管理员身份运行,而无需输入管理员用户名或密码。

【讨论】:

/savecred 不安全! 这是唯一不使用远程会话可能无法访问的图形提升提示的解决方案。【参考方案18】:

我正在使用以下解决方案。它通过转录功能处理标准输出/标准错误,并将退出代码正确传递给父进程。您需要调整脚本路径/文件名。

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

【讨论】:

这会丢失所有调用参数【参考方案19】:

另一个更简单的解决方案是,您也可以右键单击“C:\Windows\System32\cmd.exe”并选择“以管理员身份运行”,然后您可以在不提供任何密码的情况下以管理员身份运行任何应用程序。

【讨论】:

【参考方案20】:

@pgk 和@Andrew Odri 的答案的问题是当你有脚本参数时,特别是当它们是强制性的时。您可以使用以下方法解决此问题:

    用户右键单击 .ps1 文件并选择“使用 PowerShell 运行”:通过输入框向他询问参数(这比使用 HelpMessage 参数属性); 用户通过控制台执行脚本:让他传递想要的参数,让控制台强制他通知强制的参数。

如果脚本具有 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

【讨论】:

【参考方案21】:

我发现最可靠的方法是将其包装在一个自升式 .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 个参数设置为 0 时打开无关的“cmd”窗口。

【讨论】:

很好的答案,但我试过了但没有用(并退出了我调用它的命令行)。我这样修复:我将第一个 EXIT 更改为 GOTO :EOF 并删除了第二个。此外,cd %~dp0 应该是cd /d %~dp0 并将第一个命令放在@echo off 之后。这样您也不需要.ps1 的绝对路径,只需将其放在与.bat 相同的文件夹中即可。如果需要看结果,把第4个参数改成1 您运行的是哪个操作系统和版本? Windows 7 SP1 旗舰版。我在 C: 中有系统,但在 D: 中也有数据和便携式应用程序(以及其他几个驱动器)。顺便说一句……如果程序/脚本使用参数怎么办? mshta 命令是什么? 我认为您可能在测试中出错了,因为脚本运行良好。顺便说一句,它旨在退出调用cmd 进程,因此这不是“修复”它,但我很高兴您能够根据需要对其进行修改。 好的,如果你想退出cmd(我没有)。但关于其他更改,我认为是修复,因为我的版本适用于我们双方,而你的版本不适用于我,即我的更通用(解决不同驱动器的情况)。无论如何,这是一个非常聪明的方法。【参考方案22】:

在 Shay Levy 的回答之上,遵循以下设置(只需一次)

    使用管理员权限启动 PowerShell。 关注堆栈溢出问题PowerShell says “execution of scripts is disabled on this system.”。 例如,将您的 .ps1 文件放在任何 PATH 文件夹中。 Windows\System32 文件夹

设置后:

    Win + R 调用powershell Start-Process powershell -Verb runAs <ps1_file>

您现在可以在一个命令行中运行所有内容。以上适用于 Windows 8 Basic 64 位。

【讨论】:

【参考方案23】:

我以前没有见过自己的做法,所以,试试这个。它更容易遵循并且占用空间更小:

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

非常简单,如果当前的 Powershell 会话是以管理员权限调用的,那么当您获取当前身份时,管理员组众所周知的 SID 将显示在组中。即使帐户是该组的成员,SID 也不会显示,除非使用提升的凭据调用该进程。

几乎所有这些答案都是微软 Ben Armstrong 非常流行的方法的一种变体,该方法是如何完成它而不真正掌握它实际在做什么以及如何模拟相同的例程。

【讨论】:

【参考方案24】:

要将命令的输出附加到包含当前日期的文本文件名,您可以执行以下操作:

$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 

【讨论】:

【参考方案25】:

这是一个澄清......

powershell RUNAS / SAVECRED 凭据“不安全”,试了一下,它将管理员身份和密码添加到凭据缓存中,并且可以在其他地方使用 OOPS!。如果您已经这样做了,我建议您检查并删除该条目。

检查您的程序或代码,因为 Microsoft 的政策是,如果没有 UAC(入口点)以管理员身份执行程序,您不能在同一代码块中混合用户和管理员代码。这将是 Linux 上的 sudo(同样的事情)。

UAC 有 3 种类型,don't'see、prompt 或在程序清单中生成的入口点。它不会提升程序,因此如果没有 UAC 并且需要管理员,它将失败。 UAC虽然作为管理员的要求很好,但它可以防止未经身份验证的代码执行,并防止在用户级别执行混合代码场景。

【讨论】:

这应该是一个评论,它不是问题的解决方案(就像论坛的工作方式;您的内容很有用,但不是解决方案)。【参考方案26】:

我最近需要这个来在 ansible 上构建环境。我马上说——决定不是我的,但我不记得我从哪里得到的。看起来像这样:

powershell.exe -NoProfile -ExecutionPolicy Unrestricted -Command "& Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Unrestricted -Command Get-Service -Name ssh-agent | Set-Service -StartupType Automatic' -Verb RunAs";

此示例启用 ssh-agent 自动启动。 所需的命令在 -Command 之后指定。唯一的问题是启动发生在一个新的 PS 实例上,但到目前为止,这是我知道以管理员身份执行命令而无需额外步骤的唯一方法。

【讨论】:

【参考方案27】:

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

它可能会要求您启用策略以运行,键入 Y 并按 Enter。现在脚本将以管理员身份在 PowerShell 中运行。如果它全红,则意味着您的政策尚未生效。然后再试一次,应该可以正常工作了。

【讨论】:

以上是关于使用 PowerShell 以管理员身份运行命令?的主要内容,如果未能解决你的问题,请参考以下文章

Powershell 以管理员用户身份运行命令行

用于检查应用程序是不是以提升的权限运行的 PowerShell 命令

哪些注册表命令允许我从包含撇号的文件夹的右键单击上下文菜单中以管理员身份运行 PowerShell 5 / CMD?

如何以管理员身份运行cmd

怎么在powershell里面运行cmd命令

powershell 通过Powershell禁用/启用Hyper-V(“以管理员身份运行”)