本文說明 PSScriptAnalyzer 的各種功能,以及如何使用它們。
剖析器錯誤
從 1.18.0 版開始, PSScriptAnalyzer 會發出剖析器錯誤作為輸出資料流程中的診斷記錄。
Invoke-ScriptAnalyzer -ScriptDefinition '"b" = "b"; function eliminate-file () { }'
RuleName Severity ScriptName Line Message
-------- -------- ---------- ---- -------
InvalidLeftHandSide ParseError 1 The assignment expression isn't
valid. The input to an
assignment operator must be an
object that's able to accept
assignments, such as a variable
or a property.
PSUseApprovedVerbs Warning 1 The cmdlet 'eliminate-file' uses an
unapproved verb.
RuleName 會設定為剖析器錯誤的 ErrorId。
若要隱藏 ParseErrors,請勿將它作為 Severity 參數中的值包含在中。
$invokeScriptAnalyzerSplat = @{
ScriptDefinition = '"b" = "b"; function eliminate-file () { }'
Severity = 'Warning'
}
Invoke-ScriptAnalyzer @invokeScriptAnalyzerSplat
RuleName Severity ScriptName Line Message
-------- -------- ---------- ---- -------
PSUseApprovedVerbs Warning 1 The cmdlet 'eliminate-file' uses an
unapproved verb.
抑制規則
您可以用 裝飾指令碼、函數或參數來隱藏規則。NET 的 SuppressMessageAttribute。 SuppressMessageAttribute 的建構函式會採用兩個參數:類別和檢查標識碼。 將 categoryID 參數設定為您要隱藏的規則名稱,並將 checkID 參數設定為空值或空字串。 您可以選擇性地新增第三個具名參數,其中包含隱藏訊息的理由:
function SuppressMe()
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '',
Justification='Just an example')]
param()
Write-Verbose -Message "I'm making a difference!"
}
在您裝飾的指令碼、函數或參數範圍內,會抑制所有規則違規。
若要隱藏特定參數上的訊息,請將 SuppressMessageAttribute 的 CheckId 參數設定為參數的名稱:
function SuppressTwoVariables()
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParameterValue', 'b')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideDefaultParameterValue', 'a')]
param([string]$a, [int]$b)
{
}
}
使用 SuppressMessageAttribute 的 Scope 屬性,將規則隱藏限制為屬性範圍內的函式或類別。
使用值 Function 來隱藏屬性範圍內所有函式的違規。 使用值 Class 來隱藏屬性範圍內所有類別的違規:
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSProvideCommentHelp', '', Scope='Function')]
param()
function InternalFunction
{
param()
Write-Verbose -Message "I am invincible!"
}
你還可以透過將 SuppressMessageAttribute 的 Target 屬性設為正則表達式或萬用字元模式,進一步限制基於函式、參數、類別、變數或物件名稱的抑制。
例如,若要隱藏 和 中 start-bar 規則違規,但不是 和 start-baz中start-foostart-bam:
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
Scope='Function', Target='start-ba[rz]')]
param()
function start-foo {
write-host "start-foo"
}
function start-bar {
write-host "start-bar"
}
function start-baz {
write-host "start-baz"
}
function start-bam {
write-host "start-bam"
}
若要隱藏所有函式中的違規行為:
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
Scope='Function', Target='*')]
Param()
若要隱藏 中的違規行為,但不會start-bar抑制 中的start-bazstart-bam違規行為start-foo:
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '',
Scope='Function', Target='start-b*')]
Param()
備註
無法使用 SuppressMessageAttribute 隱藏剖析器錯誤。
ScriptAnalyzer 中的設定支援
您可以建立設定來描述要根據 嚴重性包含或排除的 ScriptAnalyzer 規則。 使用 設定 參數Invoke-ScriptAnalyzer來指定組態。
設定參數允許你為特定環境建立自訂設定。
ScriptAnalyzer 支援以下設定檔案的指定模式:
內建預設
ScriptAnalyzer 隨附一組內建預設集,可用來分析腳本。 例如,如果您想要在模組上執行 PowerShell 資源庫 規則,請使用下列命令:
Invoke-ScriptAnalyzer -Path /path/to/module/ -Settings PSGallery -Recurse
此外,您還可以使用其他內建預設,包括 DSC 和 CodeFormatting。 這些預設集可以針對 「設定 」參數完成標籤。
Explicit
下列範例會從預設規則集中排除兩個規則,以及嚴重性不是 「錯誤」 和 「警告」的任何規則。
# PSScriptAnalyzerSettings.psd1
@{
Severity=@('Error','Warning')
ExcludeRules=@('PSAvoidUsingCmdletAliases', 'PSAvoidUsingWriteHost')
}
然後,您可以使用下列方式呼叫 Invoke-ScriptAnalyzer該設定檔案:
Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings PSScriptAnalyzerSettings.psd1
下一個範例會選取幾個要執行的規則,而不是所有預設規則。
# PSScriptAnalyzerSettings.psd1
@{
IncludeRules=@('PSAvoidUsingPlainTextForPassword',
'PSAvoidUsingConvertToSecureStringWithPlainText')
}
然後,您可以叫用該設定檔案:
Invoke-ScriptAnalyzer -Path MyScript.ps1 -Settings PSScriptAnalyzerSettings.psd1
隱含
如果您將名為PSScriptAnalyzerSettings.psd1的設定檔案放在專案根目錄中,當您將專案根目錄作為 Path 參數傳遞時,PSScriptAnalyzer 會探索它。
Invoke-ScriptAnalyzer -Path "C:\path\to\project" -Recurse
明確提供設定優先權高於此隱含模式。 你可以在 SettingsPSScriptAnalyzer 模組的資料夾中找到範例設定檔案。
檢查 PowerShell 版本相容性
PSScriptAnalyzer 可以檢查 PowerShell 腳本是否與其他 PowerShell 版本和環境不相容。 PSScriptAnalyzer 包含四個規則來檢查相容性問題:
- PSUseCompatibleCmdlet 會檢查腳本中使用的 Cmdlet 是否可在其他 PowerShell 環境中使用
- PSUseCompatibleCommands 會檢查腳本中使用的命令是否可在其他 PowerShell 環境中使用
- PSUseCompatibleSyntax 會檢查腳本中使用的語法是否與其他版本的 PowerShell 相容
- PSUseCompatibleTypes 會檢查 .NET 類型和靜態方法或屬性是否適用於其他 PowerShell 環境
如需如何使用這些規則的詳細資訊,請參閱 PowerShell 小組部落格上的使用 PSScriptAnalyzer 檢查 PowerShell 版本相容性 。
自訂規則
您可以在設定檔案中提供自訂規則的一或多個路徑。 請務必指出這些路徑指向模組的資料夾 (隱含使用模組資訊清單) 或模組的指令碼檔案 (.psm1)。 模組必須匯出自訂規則函式 Export-ModuleMember ,才能供 PSScriptAnalyzer 使用。
在這個例子中, CustomRulePath 屬性指向兩個不同的模組。 這兩個模組都會匯出具有動詞 Measure 的規則函式,因此 Measure-* 用於內容 IncludeRules。
@{
CustomRulePath = @(
'.\output\RequiredModules\DscResource.AnalyzerRules'
'.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
)
IncludeRules = @(
'Measure-*'
)
}
您也可以在 IncludeRules 屬性中列出規則,以新增預設規則。 包含預設規則時,請務必將 IncludeDefaultRules 屬性設定為 $true;否則會使用預設規則。
@{
CustomRulePath = @(
'.\output\RequiredModules\DscResource.AnalyzerRules'
'.\tests\QA\AnalyzerRules\SqlServerDsc.AnalyzerRules.psm1'
)
IncludeDefaultRules = $true
IncludeRules = @(
# Default rules
'PSAvoidDefaultValueForMandatoryParameter'
'PSAvoidDefaultValueSwitchParameter'
# Custom rules
'Measure-*'
)
}
在 Visual Studio Code 中使用自訂規則(VS Code)
你也可以使用VS Code設定檔裡提供的自訂規則。 新增一個 VS Code 工作區設定檔案(),.vscode/settings.json內容如下。
{
"powershell.scriptAnalysis.settingsPath": ".vscode/analyzersettings.psd1",
"powershell.scriptAnalysis.enable": true,
}
ScriptAnalyzer 作為 .NET 程式庫
您可以直接將 ScriptAnalyzer 的引擎和功能作為程式庫使用。
以下是公共介面:
using Microsoft.Windows.PowerShell.ScriptAnalyzer;
public void Initialize(System.Management.Automation.Runspaces.Runspace runspace,
Microsoft.Windows.PowerShell.ScriptAnalyzer.IOutputWriter outputWriter,
[string[] customizedRulePath = null],
[string[] includeRuleNames = null],
[string[] excludeRuleNames = null],
[string[] severity = null],
[bool suppressedOnly = false],
[string profile = null])
public System.Collections.Generic.IEnumerable<DiagnosticRecord> AnalyzePath(string path,
[bool searchRecursively = false])
public System.Collections.Generic.IEnumerable<IRule> GetRule(string[] moduleNames,
string[] ruleNames)
違規糾正
你可以使用 修正 開關自動替換違規內容,並以建議的替代方案取代違規內容。 此外,由於實作 Invoke-ScriptAnalyzer,您可以使用 WhatIf 或 Confirm 來找出要套用哪些更正。 你在套用修正時應該使用原始碼控制,因為有些變更,例如 AvoidUsingPlainTextForPassword,可能需要其他無法自動完成的腳本修改。 當你自動套用建議時,初始編碼並不一定能被保留。
如果你的腳本依賴特定編碼,你應該檢查檔案編碼。
錯誤紀錄的 SuggestedCorrections 屬性使得像 VS Code 這類編輯器能快速修正。 我們為下列規則提供有效的 SuggestedCorrection :
- 避免別名
- 避免使用PlainTextForPassword
- 誤導性反引號
- MissingModuleManifestField
- UseToExportFieldsInManifest