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

时间:2015-06-09 16:14:06

标签: function powershell pipeline cmdlet

我正在编写一个脚本,我想使用PowerShell的CmdletBinding()。 有没有办法在脚本中定义函数?当我尝试时,PowerShell抱怨"意想不到的功能'在表达或陈述中#34;

以下是我尝试做的简单示例。

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

BEGIN {
    f("Begin")
}

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

END {
    f("End")
}

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

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

1 个答案:

答案 0 :(得分:6)

当您的代码应该处理管道输入时,您使用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

  

将对象管道化为功能

     

任何函数都可以从管道获取输入。您可以使用Begin,Process和End关键字控制函数如何处理来自管道的输入。以下示例语法显示了三个关键字:

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

Begin语句列表仅在函数开头运行一次。

     

Process语句列表为管道中的每个对象运行一次。当Process块正在运行时,每个管道对象都被分配给$ _自动变量,一次一个管道对象。

     

函数收到管道中的所有对象后,End语句列表运行一次。如果没有使用Begin,Process或End关键字,则所有语句都被视为End语句列表。

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

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

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

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

编辑:如果要将f的定义放在脚本的末尾,则需要将其余代码定义为worker / main /无论函数和调用脚本末尾的那个函数,例如:

[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