PSScriptAnalyzer 會使用 Managed Extensibility Framework (MEF) 來匯入元件中定義的所有規則。 它也可以取用 PowerShell 腳本撰寫的規則。
使用者可利用 cmdlet 中的 Invoke-ScriptAnalyzer 參數來指定自訂規則。
本文提供建立您自己的自訂規則的基本指南。
基本要求
函數應該有基於註釋的幫助
包括欄位 .DESCRIPTION 。 此欄位成為自訂規則的描述。
<#
.SYNOPSIS
Name of your rule.
.DESCRIPTION
This would be the description of your rule. Please refer to Rule Documentation
for consistent rule messages.
.EXAMPLE
.INPUTS
.OUTPUTS
.NOTES
#>
輸出型態應該是 DiagnosticRecord 物件的陣列
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
每個函式都必須有一個 Token 陣列或 Ast 參數
Ast 參數名稱的名稱必須以 Ast結尾。
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$testAst
)
Token 參數名稱必須以 結尾。Token
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.Token[]]
$testToken
)
DiagnosticRecord 應該具有必要的屬性
DiagnosticRecord 至少應該有四個屬性:
- Message
- 程度
- RuleName
- Severity
$result = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]@{
Message = 'This is a sample rule'
Extent = $ast.Extent
RuleName = $PSCmdlet.MyInvocation.InvocationName
Severity = 'Warning'
}
從 1.17.0 版開始,您可以包含 類型的 < 屬性。 請務必指定正確的類型。 例如:
$startLineNumber = $ast.Extent.StartLineNumber
$endLineNumber = $ast.Extent.EndLineNumber
$startColumnNumber = $ast.Extent.StartColumnNumber
$endColumnNumber = $ast.Extent.EndColumnNumber
$correction = 'Correct text that replaces Extent text'
$file = $MyInvocation.MyCommand.Definition
$optionalDescription = 'Useful but optional description text'
$objParams = @{
TypeName = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent'
ArgumentList = $startLineNumber, $endLineNumber, $startColumnNumber,
$endColumnNumber, $correction, $file, $optionalDescription
}
$correctionExtent = New-Object @objParams
$suggestedCorrections = New-Object System.Collections.ObjectModel.Collection[$($objParams.TypeName)]
$suggestedCorrections.add($correctionExtent) | Out-Null
[Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
Message = 'This is a rule with a suggested correction'
Extent = $ast.Extent
RuleName = $PSCmdlet.MyInvocation.InvocationName
Severity = 'Warning'
RuleSuppressionID = 'MyRuleSuppressionID'
SuggestedCorrections = $suggestedCorrections
}
務必匯出函式
你必須匯出你所建立的函式,讓 PSScriptAnalyzer 能找到它們。
Export-ModuleMember -Function (FunctionName)
規則函式範例
<#
.SYNOPSIS
Uses #Requires -RunAsAdministrator instead of your own methods.
.DESCRIPTION
The #Requires statement prevents a script from running unless the Windows PowerShell
version, modules, snap-ins, and module and snap-in version prerequisites are met.
Since Windows PowerShell 4.0, the #Requires statement lets script developers require that
sessions be run with elevated user rights (run as Administrator). Script developers do
not need to write their own methods any more. To fix a violation of this rule, please
consider using #Requires -RunAsAdministrator instead of your own methods.
.EXAMPLE
Measure-RequiresRunAsAdministrator -ScriptBlockAst $ScriptBlockAst
.INPUTS
[System.Management.Automation.Language.ScriptBlockAst]
.OUTPUTS
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
.NOTES
None
#>
function Measure-RequiresRunAsAdministrator {
[CmdletBinding()]
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.ScriptBlockAst]
$ScriptBlockAst
)
begin {
$MeasureRequiresAdmin = @(
'The #Requires statement prevents a script from running unless the PowerShell version,'
'modules, snap-ins, and module and snap-in version prerequisites are met. Since'
'Windows PowerShell 4.0, the #Requires statement lets script developers require that'
'sessions be run with elevated user rights (run as Administrator). Script developers'
'don''t need to write their own methods to test for elevated rights. To fix a violation'
'of this rule, use #Requires -RunAsAdministrator instead of your own methods.'
) -join ' '
# Finds specific method, IsInRole.
[ScriptBlock]$predicate = {
param($Ast)
return $Ast.Member.Value -eq 'IsInRole'
}
}
process {
# Exit early if the script block has a #Requires -RunAsAdministrator statement.
if ($ScriptBlockAst.ScriptRequirements.IsElevationRequired) {
return
}
# Test for calls to IsInRole() method
[System.Management.Automation.Language.Ast]$methodAst = $ScriptBlockAst.Find($predicate, $true)
if ($methodAst) {
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{
Message = $MeasureRequiresAdmin
Extent = $methodAst.Extent
RuleName = $PSCmdlet.MyInvocation.InvocationName
Severity = 'Information'
}
}
}
}
更多範例可以在 GitHub 上的 CommunityAnalyzerRules 資料夾中找到。