PowerShell 函數參數: 建立更好功能的實用指南

在 PowerShell 中建立函數是一種使您的腳本模組化和可重用的好方法。但是如果您希望這些函數能夠適應不同的場景,添加函數參數可以將它們提升到一個新的水平。

在本教程中,我們將通過添加參數來控制日誌消息、文件路徑和驗證,擴展一個基本的日誌記錄函數。

到最後,您將看到參數如何使您的函數變得多功能、抗錯誤和強大的 PowerShell 工具包補充。

定義基本的 Write-Log 函數

我們將從一個基本函數開始,該函數接受一個日誌消息的輸入參數,並將其附加到帶有時間戳的標準日誌文件中。

在這個例子中:

  • $LogMessage 參數被標記為必填,因此如果您未提供值,PowerShell 將提示您輸入。
  • 每個日誌條目都包含一個格式為 HH:mm:ss 的時間戳。
function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$LogMessage
    )
    $timeGenerated = Get-Date -Format HH:mm:ss
    Add-Content -Path "C:\Scripts\software_installer.log" -Value "$timeGenerated - $LogMessage"
}

測試 Write-Log 函數

現在 Write-Log 函數已經有了基本結構並接受參數,是時候測試它的功能了。測試有助於確保函數的每個方面,從默認設置到自定義輸入,都能按預期執行並優雅地處理錯誤。

通過使用自定義消息調用 Write-Log 函數來測試:

Write-Log -LogMessage 'Testing a new log message'

此命令將帶有時間戳的新條目添加到日誌文件中 (C:\Scripts\software_installer.log)。

關於 Write-Log 函數,有幾件事需要注意:

Standardized Information Logging By setting a default path for the log file, you don’t have to specify the file name every time you call the function. This standardizes all log information to a single file, keeping your logs organized.
簡化記錄過程 該函數將獲取當前日期和時間以及附加內容等細節抽象出來,使用者可以專注於將消息寫入日誌文件,而無需記住這些細節。
提高代碼可讀性 該函數明確將消息記錄到指定的日誌文件中,使其清楚表明目的是日誌記錄,而不僅僅是寫入到一個通用文本文件中。這使得代碼更加自解釋,更容易一目了然。

通過這些改進,Write-Log 函數有助於優化日誌記錄任務,使腳本更加清潔和易於維護。

您可以通過檢查日誌文件的內容來查看最新的日誌消息:

Get-Content -Path "C:\Scripts\software_installer.log"

此命令顯示所有日誌項,包括您最新的帶有時間戳記的消息。

但也許您不小心調用了沒有 LogMessage 參數的 Write-Log

Write-Log

您會注意到,由於 LogMessage 是必需的,PowerShell 將防止函數運行。但如果 LogMessage 不是必填的,將寫入一個空消息,從而創建一個意外的“oops”條目。

通過重新檢查日誌文件來驗證結果:

Get-Content -Path "C:\Scripts\software_installer.log"

通過自定義日誌文件路徑增加靈活性

雖然這個函數運作得很好,但我們可以通過新增一個 $LogFilePath 參數來使它更加靈活。這個參數允許您指定自定義文件路徑,同時提供一個默認路徑。

function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$LogMessage,

        [Parameter()]
        [string]$LogFilePath = 'C:\Scripts\software_installer.log'
    )
    $timeGenerated = Get-Date -Format HH:mm:ss
    Add-Content -Path $LogFilePath -Value "$timeGenerated - $LogMessage"
}

請注意,$LogFilePath 的默認路徑是 C:\Scripts\software_installer.log,但您可以提供任何有效的路徑。

要指定不同的文件路徑,請像這樣調用 Write-Log

Write-Log -LogMessage 'Custom path log message' -LogFilePath 'C:\Scripts\custom_log.log'

使用 ValidateScript 強制文件路徑

您不希望您的函數記錄不存在的文件。為此,您可以使用 ValidateScript 參數屬性在記錄前驗證文件是否存在。這個屬性允許您對參數的值運行代碼,驗證後再運行函數。

function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$LogMessage,

        [Parameter()]
        [ValidateScript({ Test-Path -Path $_ })]
        [string]$LogFilePath = 'C:\Scripts\software_installer.log'
    )
    $timeGenerated = Get-Date -Format HH:mm:ss
    Add-Content -Path $LogFilePath -Value "$timeGenerated - $LogMessage"
}

通過 ValidateScriptWrite-Log 檢查您提供的文件路徑是否存在。如果文件不存在,PowerShell 將停止並返回錯誤。

您可以在調用前創建一個空文件,以確保函數按預期運行:

Set-Content -Path 'C:\Scripts\softwarex_installer.log' -Value ''
Write-Log -LogMessage 'Log entry in a new file' -LogFilePath 'C:\Scripts\softwarex_installer.log'

測試 Write-Log 功能和驗證

在為函數添加靈活性後,測試它是否按預期運行是很自然的。您必須通過檢查 ValidateScript 屬性來確保強大的記錄功能,並查看它如何增強您的 Write-Log 函數。

讓我們看看 ValidateScript 的運作方式,嘗試記錄到一個不存在的文件中:

Write-Log -LogMessage 'Finishing install...' -LogFilePath 'C:\Scripts\softwarex_installer.log'

在這種情況下,ValidateScript 屬性通過調用 Test-Path 來檢查指定的日誌文件路徑是否存在。如果路徑不存在,函數將返回錯誤。

函數失敗是因為 C:\Scripts\softwarex_installer.log 不存在。您可以通過運行 Test-Path 來驗證這一點:

Test-Path 'C:\Scripts\softwarex_installer.log'

由於 Test-Path 返回 $false,這個文件確實丟失了。

為了解決這個問題,創建一個空的日誌文件並重新測試。

Set-Content -Path 'C:\Scripts\softwarex_installer.log' -Value ''
Write-Log -LogMessage 'Finishing install...' -LogFilePath 'C:\Scripts\softwarex_installer.log'

現在,該函數按預期運行。

通過查看日誌文件來確認結果:

Get-Content -Path 'C:\Scripts\softwarex_installer.log'

使用 ValidateScript 和其他參數驗證屬性來強制執行函數參數的正確使用,減少錯誤,使您的 PowerShell 函數更可靠。

結論

將參數添加到 PowerShell 函數中,大大增強了其靈活性和實用性。通過組合默認值、必填屬性和驗證,您的函數可以處理各種輸入,同時保持可靠性。

使用這些技術,您現在可以構建可擴展、用戶友好的函數,無縫地適應各種腳本。

在創建更多高級 PowerShell 工具時,擴展這些技能,以簡化和增強您的工作流程。查看這個 PowerShell Parameters 教程,深入了解函數參數!

Source:
https://adamtheautomator.com/powershell-function-parameters/