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{}
    clean{}
}

注意

这些块适用于所有函数,而不仅仅是使用 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

PowerShell 7.3 中添加了 clean 块。

clean 块是用户清理跨 begin、process和 end 块的资源的便捷方式。 其语义上类似于涵盖脚本函数或脚本 cmdlet 的所有其他命名块的 finally 块。 针对以下方案强制实施资源清理:

  1. 当管道执行正常完成而不终止错误时
  2. 管道执行因终止错误而中断时
  3. 当管道被 Select-Object -First 停止时
  4. 当管道停止时,Ctrl+c 或 StopProcessing()

清理块将丢弃写入 Success 流的任何输出。

谨慎

添加 clean 块是一项重大更改。 由于 clean 分析为关键字,因此它阻止用户直接调用名为 clean scriptblock 中的第一条语句的命令。 然而,这不太可能是个问题。 仍然可以使用调用运算符(& clean)调用该命令。

确认方法

ShouldProcess

在函数执行将更改系统的作之前,调用此方法以请求用户确认。 该函数可以基于方法返回的布尔值继续。 只能从函数的 process {} 块内调用此方法。 CmdletBinding 属性还必须声明该函数支持 ShouldProcess(如前面的示例所示)。

有关此方法的详细信息,请参阅 System.Management.Automation.Cmdlet.ShouldProcess。

有关如何请求确认的详细信息,请参阅 请求确认。

ShouldContinue

调用此方法以请求第二条确认消息。 当 ShouldProcess 方法返回 $true时,应调用它。 有关此方法的详细信息,请参阅 System.Management.Automation.Cmdlet.ShouldContinue。

错误方法

当发生错误时,函数可以调用两种不同的方法。 发生非终止错误时,该函数应调用 WriteError 方法,如 Write 方法部分所述。 当发生终止错误并且函数无法继续时,它应调用 ThrowTerminatingError 方法。 还可以将 throw 语句用于终止错误,写错误 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 属性允许查看正在使用的参数集。 通过参数集,可以创建基于运行函数时指定的参数执行不同任务的函数。

另请参阅