上周我在一家公司進行 Azure Pipelines 的企業內訓,在示範在地端架設 Pipeline Agent 的時候,直接就裝在我的 Windows 10 筆電上,過程也都順利的讓 Agent 上線,也可以把 Pipeline 的 Job 排送到這台執行。不過,在跑 Pipeline 的時候卻出現了一個詭異的錯誤訊息,我最後還是去翻出 Azure Pipelines Tasks 的 CmdLineV2 Task 原始碼才得知真相。今天這篇文章我就來說說這個鮮為人知的地雷!
問題說明
首先,我的 Pipelines 真的就非常簡單,就一個 PowerShell Task 與一個 Command Line Script Task 而已,且內容都非常簡單,只是要做個測試執行而已:
-
PowerShell
echo "Hello World" > G:\hello1.txt
-
Command line
echo Hello World > G:\hello1.txt
就這麼簡單的兩個 Step 執行,怎麼可能會掛掉?結果跑起來,就出現了以下錯誤:
以下是文字版的完整內容:
##[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),而且也確實執行失敗了:
解決方案
因為我測試了兩個 Tasks,兩個無論誰都無法執行:
-
PowerShell task (PowerShellV2
)
在 Linux、macOS 或 Windows 執行 PowerShell 指令碼
Run a PowerShell script on Linux, macOS, or Windows
-
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 的 CmdLineV2 與 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 的版本:
而且點擊 System prerequisites 頁面所顯示的,也只說支援 PowerShell 3.0 or higher
版本,沒說 PowerShell 7.x 以上不支援啊!😒
相關連結