以管理员身份运行 PowerShell 脚本

Marion Paul Kenneth Mendoza 2023年1月30日
  1. 使用 Start-Process Cmdlet 以管理员身份运行 PowerShell 脚本
  2. 以管理员身份运行带参数的 PowerShell 脚本
  3. 以管理员身份运行 PowerShell 脚本,同时保留工作目录
以管理员身份运行 PowerShell 脚本

我们编写和执行的大多数脚本都需要权限,导致管理员从提升的 PowerShell 提示符运行脚本。在 PowerShell 中,我们通过以管理员权限运行 Windows PowerShell 并输入我们的管理员凭据来提升我们的权限。

但是,我们可能需要在不输入管理员凭据的情况下针对特定情况无缝运行我们的脚本。因此,我们可以在脚本开头集成各种自提升命令,我们将在本文中向你展示如何操作。

使用 Start-Process Cmdlet 以管理员身份运行 PowerShell 脚本

Start-Process cmdlet 启动一个或多个进程、可执行文件或脚本文件,或已安装软件可以在本地计算机上打开的任何文件,包括 Windows PowerShell。

使用此 cmdlet 和一组参数,我们可以以管理员身份运行 Windows PowerShell。

对于这个例子,我们创建了一个 Hello_World.ps1 脚本,它将在我们的控制台中输出一个简单的 Hello World 字符串。

Hello_World.ps1

Write-Output 'Hello World!'

我们可以使用上面的 PowerShell 文件作为示例来检查和验证我们是否以管理员权限运行我们的脚本。首先,运行下面的代码片段。

注意
由于本地计算机的用户帐户控制 (UAC),Windows PowerShell 可能仍需要要求你确认。出于安全目的,我们不建议完全禁用 UAC。
Start-Process powershell -verb RunAs -ArgumentList ".\Hello_World.ps1"

运行上述脚本后,它将生成一个具有管理权限的新 Windows PowerShell 实例。上面运行的脚本的唯一警告是,如果我们需要将参数传递给 PowerShell 文件,我们不会将参数传递到新生成的管理控制台。

以管理员身份运行带参数的 PowerShell 脚本

此示例可以采用我们之前的单行脚本并在多个条件语句中对其进行修改。

# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        $Command = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb RunAs -ArgumentList $Command
        Exit
 }
}

# Place your script here
Write-Output 'Hello World!'

以前,我们通过调用一个单独的文件来运行我们的 PowerShell 脚本,但我们可以简单地将我们的脚本(例如,Hello_World.ps1)放在这个示例的这个片段下方。

以下是代码段的工作原理。

  • 第一个 if 语句检查执行的脚本是否已经在具有管理权限的 Windows PowerShell 中运行。
  • 第二个 if 语句检查 Windows 操作系统内部版本号是否为 6000 或更高。 (Windows Vista 或 Windows Server 2008 或更高版本)
  • $Command 变量检索并保存用于运行脚本的命令,包括参数。
  • Start-Process 使用提升的权限启动一个新的 Windows PowerShell 实例,并像我们之前的脚本一样重新运行该脚本。

以管理员身份运行 PowerShell 脚本,同时保留工作目录

我们可能需要为特定情况保留脚本的工作目录。因此,这是一个将维护工作目录的自升式代码段:

if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        Start-Process PowerShell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
        Exit;
    }
}
# Place your script here
Write-Output 'Hello World!'

在此代码段中,我们将 $PSCommandPath 作为 Start-Process cmdlet 中的参数之一传递,以保留脚本执行的工作目录。

保留工作目录对于执行路径相关操作至关重要。不幸的是,我们之前展示的前几个片段不会保持它们的路径,这可能会导致意外错误。因此,你可以使用上面修改后的语法。

Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn