分享最近的學會的 PowerShell 技巧兩則。

第一個是如何為 ps1 腳本加上啟用特定功能的開關。我以前比較笨,都是另設字串參數預設為 N,要啟用就傳入 Y,例如:-IncludeSubFolder Y。但 PowerShell 有較優雅的做法 - 沒給參數代表不啟用,附加參數則是啟用,以 Get-Content 為例:

其中只需寫出參數名稱不用給參數值的 -Force、-UseTransaction、-Wait、-Raw 即是所謂的 - 開關參數 Switch Parameters。要宣告成開關參數的方法很簡單,撰寫 .ps1 宣告 Param($變數名稱) 時,在變數名稱前方加上 [Switch] 即可。開關參數也可用於一般函式,由於其型別為布林值,故亦可明確寫成 -EnableSomething:$true 或 -EnableSomething:$false 進行切換,此一特性可用於以變數決定啟用與否,寫成 -EnableSomething:$boolVariable。

另外,希望為 .ps1 加上詳細使用說明讓它看起來更專業嗎?像是這樣:

做法是在 .ps1 用 <# ... #> 包含特定格式的註解,術語叫做 Comment-Based Help,概念就像 .NET 的 XML Documentation

註解式說明包含以下常用項目:

  • SYNOPSIS 概要
    簡要說明
  • DESCRIPTION 描述
    較完整的說明
  • EXAMPLE 範例
    語法參數範例,可以列舉多則
  • PARAMETER <參數名稱> 參數說明
    每個參數一則,或是用 # ... 寫在 Param 參數宣告上方(見下方範例)更直覺一些
  • INPUTS
    說明以 | 串接時可接收的 .NET 型別要求
  • OUTPUTS
    說明輸出的 .NET 物件型別
  • NOTES
    備註說明
  • LINK
    可指向說明網頁 URL
  • EXTERNALHELP
    額外提供 XML 說明文件

以下範例改寫自之前 tree.exe 產生資料夾樹狀結構中的 PowerShell 程式,為它加上 -ShowFile 開關參數及詳細說明:

<# 
.SYNOPSIS 
    tree 指令美化版 
.DESCRIPTION
    為 tree 的樹狀顯示加上花俏顏色,其實沒什麼意義啦
.EXAMPLE
    PS C:\>.\tree.ps1
    查詢當前資料夾結構
.EXAMPLE
    PS C:\>.\tree.ps1 D:\Temp -ShowFile
    查詢 D:\Temp 結構,包含檔案
#>
Param (
    # 要查詢的資料夾,未指定時為目前所在資料夾
    [string] $Path,
    # 是否顯示檔案
    [Switch]
    [bool] $ShowFile 
)
$arg = @($Path, '/a')
if ($ShowFile) {
    $arg += '/f'
}
& tree $arg | Select-Object -Skip 2 | ForEach-Object {
    if ($_.Contains(':\')) {
        Write-Host $_ -ForegroundColor Cyan
    }
    elseif ($_.StartsWith('+') -or $_.StartsWith('\')) { 
        $m = [System.Text.RegularExpressions.Regex]::Match($_, '^(?<l>[+\\]-+)(?<n>.+)')
        Write-Host $m.Groups["l"] -NoNewline
        Write-Host " $($m.Groups["n"].Value) " -BackgroundColor DarkYellow -ForegroundColor Black
    }
    else {
        Write-Host $_
    }
}

使用指令 get-help .\tree.ps1 可檢視說明。加上 -detail 參數會顯示參數說明及範例,加上 -full 則再增加輸入輸出型別及額外說明,-examples 則是只顯示範例。這樣子,自製 PowerShell 小工具看起來就更專業囉。

Intruduction to PowerShell switch parameter and how to use comment-based help to provide detail instruction.


Comments

Be the first to post a comment

Post a comment