在之前的章節中,我們已經成功將產出物派送到 Windows 伺服器,也寫好了部署用的 PowerShell。但在最後一步「執行」時,許多工程師會遇到瓶頸:為什麼透過 SSH 遠端執行的腳本無法啟動 IIS 或操作特定權限目錄?這就是著名的 SSH 權限委派 (Double-Hop) 與 Session 隔離問題。
當你透過 SSH 連入 Windows 時,系統為你分配的是一個非互動式的(Non-interactive)Session。這類 Session 存在諸多限制:
我們的策略是:在目標主機預先建立一個名為 DeploySite 的 Windows 工作排程 (Task Scheduler)。
SYSTEM 或 Service Account 執行。您可以在伺服器上手動建立,或透過 PowerShell 一次性建立:
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-File D:\Scripts\DeploySite.ps1'
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType S4U -RunLevel Highest
Register-ScheduledTask -TaskName "DeploySite" -Action $action -Principal $principal
在 Jenkins Pipeline 中,我們不只是觸發,還需要監控任務是否執行成功。
script {
// 1. 觸發任務 (schtasks /run)
sh "sshpass -p '${SSH_PASS}' ssh administrator@<IP> 'schtasks /run /tn DeploySite'"
// 2. 輪詢狀態 (schtasks /query)
def status = ""
timeout(time: 10, unit: 'MINUTES') {
while (true) {
// 取得最後一次執行結果 (Last Result),0 代表成功
status = sh(script: "sshpass -p '${SSH_PASS}' ssh administrator@<IP> \"schtasks /query /tn DeploySite /fo csv\" | select-string 'DeploySite' ", returnStdout: true).trim()
if (status.contains(',"0"')) {
echo "Deployment Successful!"
break
} else if (status.contains(',"Ready"')) {
// 如果任務回到 Ready 狀態但 Last Result 非 0,代表失敗
error "Deployment failed according to Task Scheduler status."
}
sleep 10
}
}
}
透過「工作排程器作為網關」的架構,我們優雅地解決了 Windows 權限限制與 Session 隔離問題。這是 Windows CI/CD 自動化實踐中最關鍵的一環。
至此,部署動作已完整。明天,我們將討論如何在部署完成後,透過監控系統(Prometheus & Grafana)獲取即時的系統健康回饋。