如何在 CmdletBinding() 脚本中定义函数?

How do I define functions within a CmdletBinding() script?

我正在编写一个脚本,我想将其与 PowerShell 的 CmdletBinding() 结合使用。 有没有办法在脚本中定义函数?当我尝试时,PowerShell 抱怨 "Unexpected toke 'function' in expression or statement"

这是我正在尝试做的事情的简化示例。

[CmdletBinding()]
param(
    [String]
    $Value
)

BEGIN {
    f("Begin")
}

PROCESS {
    f("Process:" + $Value)
}

END {
    f("End")
}

Function f() {
    param([String]$m)
    Write-Host $m
}

就我而言,编写模块是浪费开销。这些功能只需要对这个脚本可用。我不想弄乱模块路径或脚本位置。我只想 运行 一个定义了函数的脚本。

当您的代码应该处理管道输入时,您使用 beginprocessend 块。 begin 块用于预处理,在开始处理输入之前运行一次。 end 块用于 post 处理,并在输入处理完成后运行一次。如果你想在 end 块之外的任何地方调用一个函数,你可以在 begin 块中定义它(在 process 块中一遍又一遍地重新定义它会浪费资源,即使您没有在 begin 块中使用它)。

[CmdletBinding()]
param(
    [String]$Value
)

BEGIN {
    Function f() {
        param([String]$m)
        Write-Host $m
    }

    f("Begin")
}

PROCESS {
    f("Process:" + $Value)
}

END {
    f("End")
}

引用自about_Functions

Piping Objects to Functions

Any function can take input from the pipeline. You can control how a function processes input from the pipeline using Begin, Process, and End keywords. The following sample syntax shows the three keywords:

function <name> { 
    begin {<statement list>}
    process {<statement list>}
    end {<statement list>}
}

The Begin statement list runs one time only, at the beginning of the function.

The Process statement list runs one time for each object in the pipeline. While the Process block is running, each pipeline object is assigned to the $_ automatic variable, one pipeline object at a time.

After the function receives all the objects in the pipeline, the End statement list runs one time. If no Begin, Process, or End keywords are used, all the statements are treated like an End statement list.


如果您的代码不处理管道输入,您可以完全删除 beginprocessend 块并将所有内容放在脚本主体中:

[CmdletBinding()]
param(
    [String]$Value
)

Function f() {
    param([String]$m)
    Write-Host $m
}

f("Begin")
f("Process:" + $Value)
f("End")

编辑: 如果您想将 f 的定义放在脚本的末尾,您需要将其余代码定义为 worker/main/whatever 函数并在脚本末尾调用该函数,例如:

[CmdletBinding()]
param(
    [String]$Value
)

function Main {
    [CmdletBinding()]
    param(
        [String]$Param
    )

    BEGIN   { f("Begin") }
    PROCESS { f("Process:" + $Param) }
    END     { f("End") }
}

Function f() {
    param([String]$m)
    Write-Host $m
}

Main $Value