以管理員身份執行 PowerShell 指令碼

Marion Paul Kenneth Mendoza 2023年1月30日 2022年5月16日
  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