# 如何在 Windows 的 PowerShell 模擬 Linux 環境下的 sudo 命令

前天看到[黑暗執行緒](https://blog.darkthread.net/)分享了一篇[以管理者身分重新執行 .NET 命令列程式](https://blog.darkthread.net/blog/restart-dotnet-as-admin/)文章，發現在 Windows 變身為系統管理員身份執行程式真的很簡單，今天這篇文章我打算分享一個我寫的 PowerShell 腳本，讓你可以在 Windows 透過 PowerShell 隨時可以改**以系統管理員身份**執行**任意程式**，並且可以模擬 Linux 常見的 `sudo` 命令。

![Windows PowerShell sudo](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/60c89f36236fe23e2953-204344873-f4379643-deaf-4864-b3e3-8d18a48d91c7.png)

### PowerShell 如何強制以系統管理員身份執行程式

如果我們在一個 Windows PowerShell 視窗 (並非以系統管理員開啟) 執行一個應用程式，正常的啟動方法如下：

```powershell
& notepad
```

也可以這樣執行：

```powershell
notepad.exe
```

> 使用 `notepad` 可能會跟現有的 Cmdlets 衝突，所以執行應用程式時通常會建議加上 `.exe` 結尾。

也可以這樣執行：

```powershell
Start-Process notepad
```

像我自己以往就寫了一個 `function` 叫 `hosts` 可以快速開啟 Windows 常見的 `hosts` 檔：

```powershell
function hosts { notepad c:\windows\system32\drivers\etc\hosts }
```

不過這個 `function` 有個小問題，就是我每次都要先**以系統管理員身份**啟動 `powershell.exe` 或 `pwsh.exe` 才能執行這個 `function`，顯得有點不便。我之前就想，如果 Windows 也有 `sudo` 命令那該有多好！

今天我就研究出了這個方法，真的非常簡單，只要加上一個 `-Verb runAs` 參數即可！

```powershell
Start-Process 'notepad' -Verb runAs -ArgumentList c:\windows\system32\drivers\etc\hosts
```

所以我就重寫 `hosts` 函式了：

```powershell
function hosts { Start-Process notepad -Verb runAs -ArgumentList c:\windows\system32\drivers\etc\hosts }
```

以後就直接打 `hosts` 就可以立即**以系統管理員身份**執行 `notepad.exe` 並開啟我想編輯的 `hosts` 檔案了！

### 在 Windows 模擬 sudo 的 PowerShell Cmdlet

我們在 Linux 作業系統下操作管理命令，通常都很習慣用 `sudo` 來執行需要提權的程式，但是在 Windows 一直都沒有這麼簡便的工具可用。所以我寫了一段 PowerShell Function 可以做到幾乎一樣的事，而且也可以支援任意程式執行！

```powershell
function sudo
{
  if ($args.Count -gt 0)
  {
    $lastIndex = $args.Count-1
    $programName = $args[0]
    if ($args.Count -gt 1)
    {
      $programArgs = $args[1 .. $lastIndex]
    }
    Start-Process $programName -Verb runAs -ArgumentList $programArgs
  }
  else
  {
    if ($env:WT_SESSION) {
      Start-Process "wt.exe" -Verb runAs
    }
    elseif ($PSVersionTable.PSEdition -eq 'Core')
    {
      Start-Process "$PSHOME\pwsh.exe" -Verb runAs
    }
    elseif ($PSVersionTable.PSEdition -eq 'Desktop')
    {
      Start-Process "$PSHOME\powershell.exe" -Verb runAs
    }
  }
}

# 設定一個 su 別名並執行 sudo 函式
Set-Alias -Name su -Value sudo
```

> 你可以將上述指令加入到 `$PROFILE` 啟動設定檔中！

使用方式超簡單：

-   直接透過 `su` 將目前的 Terminal 環境變身成以系統管理員身份執行
    
    ```powershell
    su
    ```
    
    > 此命令支援自動判斷 Windows PowerShell、PowerShell Core 與 Windows Terminal 👍
    
-   透過 `sudo` 啟動 Command Prompt 命令提示字元
    
    ```powershell
    sudo cmd
    ```
    
-   透過 `sudo` 編輯 `C:\windows\system32\drivers\etc\hosts` 檔案
    
    ```powershell
    sudo notepad C:\windows\system32\drivers\etc\hosts
    ```
    

整個使用體驗跟 Linux 相當一致，是不是覺得很讚阿！😃

### 相關連結

-   [以管理者身分重新執行 .NET 命令列程式](https://blog.darkthread.net/blog/restart-dotnet-as-admin/)
-   [Start-Process (Microsoft.PowerShell.Management) - PowerShell | Microsoft Learn](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.3&WT.mc_id=DT-MVP-4015686)
-   [Windows Terminal command line arguments | Microsoft Learn](https://learn.microsoft.com/en-us/windows/terminal/command-line-arguments?tabs=windows&WT.mc_id=DT-MVP-4015686)
