在 PowerShell 腳本開發中,經常需要將動態生成的腳本內容輸出到檔案,或在 ISE/VS Code 中編輯時保持語法高亮。本文介紹使用「大括號語法」替代傳統 Here-String 的技巧,解決變數展開控制、編輯器高亮、原始碼保真度等痛點。
$code = @"
Invoke-WebRequest 'https://example.com'
Get-Service -Name AdobeARMservice
$name = 'Mosser Lee'
"@
$name 會被自動展開,若需保留原樣需用單引號包裹整個字串,但內部若有單引號則需大量跳脫{
Invoke-WebRequest 'https://www.jb51.net'
Get-Service -Name AdobeARMservice
$name = 'Mosser Lee'
} | Out-File 'my.ps1'
param(
[string]$Url = 'https://default.com',
[string]$ServiceName = 'wuauserv'
)
$generatedScript = {
param($TargetUrl, $SvcName)
Invoke-WebRequest -Uri $TargetUrl -OutFile 'response.html'
Restart-Service -Name $SvcName -Force
}
# 將參數化腳本存檔
$generatedScript | Out-File 'deploy.ps1' -Encoding UTF8
# 執行時傳入參數
& '.\deploy.ps1' -TargetUrl $Url -SvcName $ServiceName
$scriptBlock = [ScriptBlock]::Create(@"
Write-Host "動態生成時間: $(Get-Date)"
$env:COMPUTERNAME
"@)
# 立即執行
& $scriptBlock
# 或存檔
$scriptBlock.ToString() | Out-File 'dynamic.ps1'
function Get-CommonHeader {
return {
#Requires -Version 5.1
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
}
}
function Get-MainLogic {
return {
Write-Host "執行主要邏輯..."
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
}
}
# 組合生成完整腳本
$fullScript = {
$(Get-CommonHeader)
$(Get-MainLogic)
Write-Host "完成"
}
$fullScript | Out-File 'modular.ps1'
| 場景 | Here-String (@" "@) | 大括號 { } |
|---|---|---|
| 編輯器高亮 | 無 | 完整支援 |
| 變數展開控制 | 單引號完全不展開,雙引號全展開 | 不展開 (除非用 $() 強制) |
| 巢狀引號處理 | 需跳脫 | 原生支援 |
| 輸出到檔案 | 需注意編碼 | Out-File 直接輸出 |
| 除錯便利性 | 低 | 高 (可複製到編輯器獨立執行) |
| 作用域隔離 | 無 | 自動建立子作用域 |
ToString()$($var) 語法Out-File 預設編碼為 UTF-16LE (Windows PowerShell) 或 UTF-8 (PowerShell 7+),建議顯式指定 -Encoding UTF8return/break/continue 只影響 ScriptBlock 內部流程