﻿# 如何透過 C# 應用程式執行或呼叫 PowerShell 命令

如果有人嘗試在 ASP.NET 或 Console 應用程式執行 PowerShell 命令，可能會蠻挫折的，因為光是第一步「從專案加入參考」就會卡住，因此今天這篇文章將會按部就班地把專案環境設定好，並且透過一些簡單的範例程式說明如何透過一個 C# 主控台應用程式執行任意 PowerShell 命令。

我們先建立一個主控台應用程式專案，專案名稱設定為：TestPowerShell

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/8a941644dae303583bf2-image_2478.png)

因為我們要加入 System.Management.Automation 這個組件，不過不知為何，我們在 Visual Studio 裡面使用「加入參考」功能，是找不到這個組件的！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/05970f4e4322cafb690f-image_2479.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/8a2fd5f378bcd5479861-image_2480.png)

因此，我們改用土法煉鋼的方式，手動編輯 **TestPowerShell.csproj** 專案定義檔，手動加入這個組件參考，如下圖示： ( 如果不知道怎樣編輯，你也可以用 Notepad 開啟編輯這個檔案 )

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e87f52b5b1a4111207e1-image_2481.png)

這樣就可以成功載入 System.Management.Automation 組件，如下圖示：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/fb645896ad4d6bd34582-image_2482.png "image")

**※其實組件路徑位於** *%ProgramFiles(x86)%\\Reference Assemblies\\Microsoft\\WindowsPowerShell\\3.0*

接著我們在 Program.cs 檔案引用兩個命名空間如下：

```csharp
using System.Management.Automation;
using System.Management.Automation.Runspaces;
```

大功告成，現在你可以將 PowerShell 指令整合到你的 C# 應用程式中了！  
  

以下分享幾個簡單的例子，請將程式碼放進 Main() 方法，按下 Ctrl+F5 即可執行：

1\. 執行 Get-Service 指令 (取得所有 Windows 服務)，透過 .Invoke() 方法執行 PowerShell 命令並取得預設的 PSObject 物件集合 ( Collection<PSObject> )，在迴圈中取得 PSObject 物件的 Name 屬性。

```csharp
using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("Get-Service");

    foreach (PSObject result in powershell.Invoke())
    {
        Console.WriteLine(result.Members["Name"].Value);
    }
}
```

2\. 同上範例，但指令複雜一些，我們取得**已經停止的 Windows 服務名稱**：

```csharp
using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("Get-Service | Where-Object { $_.Status -eq 'Stopped' }");

    foreach (PSObject result in powershell.Invoke())
    {
        Console.WriteLine(result.Members["Name"].Value);
    }
}
```

3\. 執行 Invoke 方法時，可以指定回傳的型別，所以你也可以透過強型別來開發程式。不過要選對型別才能正常運作！這邊我們把指令最後透過 Out-String 指令，將結果轉型成字串，然後用 string 型別來接資料。（這時所接到的資料將會全部都是字串，而且執行結果一樣是一個集合物件，一行文字一個項目）

```csharp
using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("Get-Service | Out-String");

    foreach (string str in powershell.Invoke<string>())
    {
        Console.WriteLine(str);
    }
}
```

4\. 預設 PowerShell 執行過程中所發生的例外，都不會引發應用程式的例外狀況，所以你必須自行抓取這些錯誤資訊，並適時的顯示出來。如下範例：

```csharp
using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("Get-Service99");

    foreach (PSObject result in powershell.Invoke())
    {
        Console.WriteLine(result.Members["Name"].Value);
    }

    Console.WriteLine("執行過程中發生錯誤\n");
    PSDataCollection<ErrorRecord> errors = powershell.Streams.Error;
    if (errors != null && errors.Count > 0)
    {
        foreach (ErrorRecord err in errors)
        {
            System.Console.WriteLine("錯誤: {0}", err.ToString());
        }
    }
}
```

  
  
**注意事項**

有些 PowerShell 的 Module 只有 64 位元版本 ( x64 )，你若要執行 x64 平台才有的那些 Cmdlets 的話，必須修改專案屬性，將目標平台改為 x64 才能正常執行，如下圖示：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/782467cd744002343709-image_2483.png)

※ 例如在 [Manage Azure AD using Windows PowerShell](http://technet.microsoft.com/en-us/library/jj151815.aspx) 文件中提到的 Windows Azure Active Directory Module ( MSOnline 與 MSOnlineExtended 模組 ) 就有區分 x64 與 x86 版本。如果你只有安裝 64-bit 版本的話，預設的專案屬性設定就會無法執行這些 Cmdlets 命令：

-   [Windows Azure Active Directory Module for Windows PowerShell (32-bit version)](https://www.powershellgallery.com/packages/MSOnline/)
-   [Windows Azure Active Directory Module for Windows PowerShell (64-bit version)](http://go.microsoft.com/fwlink/p/?linkid=236297)

  
  
**補充說明**

如果你使用 Windows 8 作業系統，預設已經安裝 Windows PowerShell 3.0 SDK，在 SDK 裡面有非常完整的範例程式，你可以參考以下路徑取得這些範例程式，非常有用！

C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0\\Samples\\sysmgmt\\WindowsPowerShell

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ac5c94087ffe0e7253ae-image_2484.png)

  
  
**相關連結**

-   [Installing the Windows PowerShell SDK](http://msdn.microsoft.com/en-us/library/ff458115\(v=vs.85\).aspx)
-   [Windows PowerShell Documents on MSDN](http://msdn.microsoft.com/en-us/library/dd835506\(v=vs.85\).aspx)
-   [Windows PowerShell 3.0 SDK Sample Pack](https://web.archive.org/web/20130329105759/http://code.msdn.microsoft.com:80/Windows-PowerShell-30-SDK-9a34641d)
-   [Windows PowerShell Reference](https://learn.microsoft.com/en-us/powershell/scripting/developer/windows-powershell)
-   [Windows PowerShell Managed Reference](http://msdn.microsoft.com/en-us/library/powershell_mref_reference_home\(v=vs.85\).aspx)
-   [How to Embed PowerShell Within a C# Application (Channel 9)](http://channel9.msdn.com/Blogs/bruceky/How-to-Embedding-PowerShell-Within-a-C-Application)
-   [How to run PowerShell scripts from C# – CodeProject](http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C)
-   [Importing PowerShell module in C# - Stack Overflow](http://stackoverflow.com/questions/17070747/importing-powershell-module-in-c-sharp)
