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

5
我正在编写一个脚本,希望使用PowerShell的CmdletBinding()。在脚本中是否有定义函数的方法?当我尝试时,PowerShell会抱怨“表达式或语句中的意外标记'function'”。以下是我正在尝试的简化示例。
[CmdletBinding()]
param(
    [String]
    $Value
)

BEGIN {
    f("Begin")
}

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

END {
    f("End")
}

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

在我的情况下,编写一个模块是浪费开销的。这些函数只需要在这个脚本中可用。我不想去处理模块路径或脚本位置。我只想运行一个脚本,并在其中定义函数。

6
BEGIN块内定义它。 - user4003407
1个回答

9
您在处理管道输入时使用beginprocessend块。 begin块用于预处理,并在处理输入开始之前运行一次。 end块用于后处理,并在处理输入完成后仅运行一次。如果您想要在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

我最初希望将函数定义放在程序的末尾,这样它们就不会混乱程序的顶部,而“主”程序会立即可见和可读。 - mojo
你可以(有点)通过将主要代码放在一个单独的函数中来实现。 - Ansgar Wiechers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接