﻿# 在 Windows 10 安裝 Azure Pipelines 的 Agent 需注意啟動方式

上周我在一家公司進行 Azure Pipelines 的企業內訓，在示範在地端架設 Pipeline Agent 的時候，直接就裝在我的 Windows 10 筆電上，過程也都順利的讓 Agent 上線，也可以把 Pipeline 的 Job 排送到這台執行。不過，在跑 Pipeline 的時候卻出現了一個詭異的錯誤訊息，我最後還是去翻出 [Azure Pipelines Tasks](https://github.com/microsoft/azure-pipelines-tasks/tree/master) 的 [CmdLineV2](https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/CmdLineV2) Task 原始碼才得知真相。今天這篇文章我就來說說這個鮮為人知的地雷！

![Azure Pipelines and PowerShell](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/3a886c161100b28255b1-209469502-34928441-fd79-44f7-938f-9224f5a8a1fb.png)

### 問題說明

首先，我的 Pipelines 真的就非常簡單，就一個 PowerShell Task 與一個 Command Line Script Task 而已，且內容都非常簡單，只是要做個測試執行而已：

1.  PowerShell
    
    ```powershell
    echo "Hello World" > G:\hello1.txt
    ```
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/61d573ff38911600aa2d-209467229-bdf0e486-e165-4472-8f47-2aae7d379ddc.png)
    
2.  Command line
    
    ```batch
    echo Hello World > G:\hello1.txt
    ```
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/0378b2a397ea2b40f08c-209467178-75c479b6-edf9-4b77-8d94-375eff03c59f.png)
    

就這麼簡單的兩個 Step 執行，怎麼可能會掛掉？結果跑起來，就出現了以下錯誤：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/4215e6068c29c156f090-209466225-a7a92240-5484-43c5-b3a7-7f0b5d21ffc7.png)

以下是文字版的完整內容：

> ##\[error\]The following error occurred while loading the extended type data file: Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member AuditToString is already present.

> ##\[error\]The 'ConvertTo-SecureString' command was found in the module 'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module Microsoft.PowerShell.Security'.

我查了一下，我的 Agent 確實有接聽作業(Job)，而且也確實執行失敗了：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/1e7931b4a9f3788f4212-209467355-55b07ffe-2355-4e3e-9ba7-6755d2011da9.png)

### 解決方案

因為我測試了兩個 Tasks，兩個無論誰都無法執行：

1.  PowerShell task (`PowerShellV2`)
    
    在 Linux、macOS 或 Windows 執行 PowerShell 指令碼
    
    > Run a PowerShell script on Linux, macOS, or Windows
    
2.  Command line task (`CmdLineV2`)
    
    在 Linux 和 macOS 上使用 Bash; 在 Windows 上使用 cmd.exe 來執行命令列指令碼
    
    > Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
    

想也奇怪，我不就是想跑個 `cmd.exe` 而已嗎？錯誤訊息怎麼會跟 PowerShell 有關呢？而且我用這麼多年，之前也都沒有出錯過，怎麼這次就出錯了？

因為我個人不太允許我自己保有太多似是而非的觀念，所以去分析了一下 [Azure Pipelines Tasks](https://github.com/microsoft/azure-pipelines-tasks/tree/master) 的 [CmdLineV2](https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/CmdLineV2) 與 [PowerShellV2](https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/PowerShellV2) 原始碼，這才驚覺，原來這兩個 Tasks 在 Windows 的 Agent 上面，都是先執行一個 PowerShell Script，然後產生一個**指令檔**(`*.cmd` 或 `*.ps1`)，然後再透過 Task 的 PowerShell Script 去執行這個**指令檔**！

知道了運作原理，再回頭看一次錯誤訊息，自然也就清晰多了。原來是 Task 當中用到的 PowerShell cmdlets 有些跟 PowerShell (Core) 是不相容的，因此無法成功執行！

> 這裡請先暫停一下，我們先科普一下，在 Windows 作業系統有兩套 PowerShell 執行環境，一個是傳統的 Windows PowerShell，最新版是 `5.1` 版。而另一個是 PowerShell，早期稱 PowerShell Core，目前的最新版是 `7.3.1` 版。這些命名真的是很亂，很多人很容易被搞混！

所以，為什麼我的 Agent 無法成功執行這些 Jobs 呢？那是因為我是在 PowerShell (Core) 的環境下執行 `.\run.cmd` 的，所以才會掛掉，只要改用 Windows PowerShell 或 Command Prompt 來啟動 Agent，問題就會消失。或者是你跑成背景服務，由服務管理員來啟動程式，也不會有這個問題！

### 總結

結論很簡單，上課的時候不要用 PowerShell (Core) 來啟動 Agent，正式環境安裝時跑成背景服務執行，基本上就沒問題了！ 👍

以上經驗，網路上完全找不到解答，還是要靠自己抽絲剝繭才能找到答案。話說 PowerShell 的相容性這麼差，名字又跟 Windows PowerShell 長的這麼像，像我這樣愛用新版本的人來說，根本就是一種折磨，哈！ XD

你可以看到 `New Agent` 的頁面，根本完全沒有提及 PowerShell 的版本：

![Get the agent](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/639de59161edcd0c3413-209468027-487a1f7c-00ea-4b9c-9bb0-b4534e3850db.png)

而且點擊 [System prerequisites](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/v2-windows?view=azure-devops&WT.mc_id=DT-MVP-4015686#check-prerequisites) 頁面所顯示的，也只說支援 `PowerShell 3.0 or higher` 版本，沒說 PowerShell 7.x 以上不支援啊！😒

![System prerequisites - Deploy an Azure Pipelines agent on Windows - Azure Pipelines | Microsoft Learn](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/5abb8a5f77663e11f237-209468492-f956fd98-7daf-497d-932c-cc087af484c8.png)

### 相關連結

-   [CmdLine@2 - Command line v2 task | Microsoft Learn](https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/cmd-line-v2?view=azure-pipelines&viewFallbackFrom=azure-devops&WT.mc_id=DT-MVP-4015686)
    -   原始碼: [CmdLineV2](https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/CmdLineV2)
-   [PowerShell@2 - PowerShell v2 task | Microsoft Learn](https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/powershell-v2?view=azure-pipelines&WT.mc_id=DT-MVP-4015686)
    -   原始碼: [PowerShellV2](https://github.com/microsoft/azure-pipelines-tasks/tree/master/Tasks/PowerShellV2)
-   [Powershell ConvertTo-SecureString not recognised if run script inline from cmd - Stack Overflow](https://stackoverflow.com/a/74869395/910074)
