PSScriptAnalyzer 使用 托管扩展性框架 (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结尾。
Param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Management.Automation.Language.Token[]]
$testToken
)
DiagnosticRecord 应具有所需的属性
DiagnosticRecord 应至少具有四个属性:
- Message
- 程度
- RuleName
- 严重性
$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 文件夹中找到。