about_Functions_Advanced_Methods
简短说明
描述指定特性的 CmdletBinding
函数如何使用可用于已编译 cmdlet 的方法和属性。
长说明
指定 属性的 CmdletBinding
函数可以通过 变量访问其他方法和属性 $PSCmdlet
。 这些方法包括以下方法:
- 适用于所有函数的相同输入处理方法。
ShouldProcess
用于在执行操作之前获取用户反馈的 和ShouldContinue
方法。ThrowTerminatingError
用于生成错误记录的方法。- 返回不同类型的输出的几种
Write
方法。
PSCmdlet 类的所有方法和属性都可用于高级函数。 有关详细信息,请参阅 System.Management.Automation.PSCmdlet。
有关 属性的详细信息 CmdletBinding
,请参阅 about_Functions_CmdletBindingAttribute。 有关 CmdletBindingAttribute 类,请参阅 System.Management.Automation.Cmdlet.CmdletBindingAttribute。
输入处理方法
本部分所述的方法称为输入处理方法。 对于函数,这三个方法由 函数的 begin
、 process
和 end
块表示。 PowerShell 7.3 添加了块 clean
进程方法。
无需在函数中使用任何这些块。 如果不使用命名块,则 PowerShell 会将代码放在函数的 块中 end
。 但是,如果使用这些命名块中的任何一个 dynamicparam
,或定义块,则必须将所有代码放在命名块中。
以下示例演示函数的轮廓,该函数包含一个 begin
用于一次性预处理的块、 process
用于处理多条记录的块和用于一次性后处理的 end
块。
Function Test-ScriptCmdlet
{
[CmdletBinding(SupportsShouldProcess=$True)]
Param ($Parameter1)
begin{}
process{}
end{}
}
注意
这些块适用于所有函数,而不仅仅是使用 特性的 CmdletBinding
函数。
begin
此块用于为函数提供可选的一次性预处理。 PowerShell 运行时对管道中函数的每个实例使用此块中的代码一次。
process
此块用于为 函数提供逐条记录处理。 可以使用 块 process
,而无需定义其他块。 块执行的次数 process
取决于函数的使用方式以及函数接收的输入。
自动变量 $_
或 $PSItem
包含管道中的当前对象,以便在 块中使用 process
。 自动 $input
变量包含仅适用于函数和脚本块的枚举器。
有关详细信息,请参阅 about_Automatic_Variables。
- 在开头或管道外部调用 函数将执行块一
process
次。 - 在管道中
process
,块对到达函数的每个输入对象执行一次。 - 如果到达函数的管道输入为空,则
process
块不会执行。begin
、end
和clean
块仍会执行。
重要
如果函数参数设置为接受管道输入,并且 process
未定义块,则逐条记录处理将失败。 在这种情况下,无论输入如何,函数都只会执行一次。
创建接受管道输入并使用 CmdletBinding
的函数时, process
块应使用为管道输入定义的参数变量, $_
而不是 或 $PSItem
。 例如:
function Get-SumOfNumbers {
[CmdletBinding()]
param (
[Parameter(Mandatory, Position=0, ValueFromPipeline)]
[int[]]$Numbers
)
begin { $retValue = 0 }
process {
foreach ($n in $Numbers) {
$retValue += $n
}
}
end { $retValue }
}
PS> Get-SumOfNumbers 1,2,3,4
10
PS> 1,2,3,4 | Get-SumOfNumbers
10
end
此块用于为 函数提供可选的一次性后处理。
clean
块 clean
已添加到 PowerShell 7.3 中。
clean
块是一种方便用户清理跨 begin
、process
和 end
块的资源的方法。 它在语义上类似于 finally
块,该块涵盖脚本函数或脚本 cmdlet 的所有其他命名块。 对于以下场景,将强制执行资源清理:
- 管道执行正常完成,没有终止错误
- 管道执行因终止错误而中断
- 通过
Select-Object -First
停止管道 - 通过 Ctrl+c 或
StopProcessing()
停止管道
注意
添加 clean
块属于一项中断性变更。 由于 clean
是作为关键字分析的,因此它可以阻止用户直接调用名为 clean
的命令作为脚本块中的第一个语句。 但是,这不太可能是个问题。 仍可使用调用运算符 (& clean
) 调用命令。
确认方法
ShouldProcess
调用此方法以在函数执行更改系统的操作之前请求用户确认。 函数可以根据 方法返回的布尔值继续运行。 只能从函数的 块内 Process{}
调用此方法。 特性 CmdletBinding
还必须声明函数支持 ShouldProcess
(,如前面的示例) 所示。
有关此方法的详细信息,请参阅 System.Management.Automation.Cmdlet.ShouldProcess。
有关如何请求确认的详细信息,请参阅 请求确认。
ShouldContinue
调用此方法以请求第二条确认消息。 当方法返回 $true
时,ShouldProcess
应调用它。 有关此方法的详细信息,请参阅 System.Management.Automation.Cmdlet.ShouldContinue。
错误方法
发生错误时,函数可以调用两种不同的方法。 发生非终止错误时,函数应调用 WriteError
方法,如方法部分所述 Write
。 当发生终止错误且函数无法继续时,它应调用 ThrowTerminatingError
方法。 还可以将 Throw
语句用于终止错误,将 Write-Error cmdlet 用于非终止错误。
有关详细信息,请参阅 System.Management.Automation.Cmdlet.ThrowTerminatingError。
写入方法
函数可以调用以下方法来返回不同类型的输出。
请注意,并非所有输出都会转到管道中的下一个命令。 还可以使用各种 Write
cmdlet,例如 Write-Error
。
WriteCommandDetail
有关方法的信息 WriteCommandDetails
,请参阅 System.Management.Automation.Cmdlet.WriteCommandDetail。
WriteDebug
若要提供可用于对函数进行故障排除的信息,请使函数调用 WriteDebug
方法。 方法 WriteDebug
向用户显示调试消息。 有关详细信息,请参阅 System.Management.Automation.Cmdlet.WriteDebug。
WriteError
当发生非终止性错误并且函数设计为继续处理记录时,函数应调用此方法。 有关详细信息,请参阅 System.Management.Automation.Cmdlet.WriteError。
注意
如果发生终止错误,该函数应调用 ThrowTerminatingError 方法。
WriteObject
方法 WriteObject
允许函数将对象发送到管道中的下一个命令。 在大多数情况下, WriteObject
是函数返回数据时要使用的 方法。 有关详细信息,请参阅 System.Management.Automation.PSCmdlet.WriteObject。
WriteProgress
对于操作需要很长时间才能完成的函数,此方法允许函数调用 WriteProgress
方法,以便显示进度信息。 例如,可以显示完成百分比。
有关详细信息,请参阅 System.Management.Automation.PSCmdlet.WriteProgress。
WriteVerbose
若要提供有关函数正在执行的操作的详细信息,请使函数调用 WriteVerbose
方法以向用户显示详细消息。 默认情况下,不显示详细消息。 有关详细信息,请参阅 System.Management.Automation.PSCmdlet.WriteVerbose。
WriteWarning
若要提供有关可能导致意外结果的条件的信息,请使函数调用 WriteWarning 方法向用户显示警告消息。 默认情况下,显示警告消息。 有关详细信息,请参阅 System.Management.Automation.PSCmdlet.WriteWarning。
注意
还可以通过配置 $WarningPreference
变量或使用 Verbose
和 Debug
命令行选项来显示警告消息。 有关变量的详细信息 $WarningPreference
,请参阅 about_Preference_Variables。
其他方法和属性
有关可通过 变量访问 $PSCmdlet
的其他方法和属性的信息,请参阅 System.Management.Automation.PSCmdlet。
例如, ParameterSetName 属性允许查看正在使用的参数集。 参数集允许创建一个函数,该函数根据运行函数时指定的参数执行不同任务。