如何在CmdletBinding()脚本中定义函数? [英] How do I define functions within a CmdletBinding() script?

查看:204
本文介绍了如何在CmdletBinding()脚本中定义函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本,我想使用PowerShell的CmdletBinding()。
是否有方法可以在脚本中定义函数?当我尝试时,PowerShell抱怨表达式或语句中的Unexpected toke'函数



下面是我试图做的简单示例。


$ b

  [CmdletBinding()] 
param(
[String]
$价值


BEGIN {
f(开始)
}

过程{
f(过程:+ $ Value)
}

END {
f(End)
}

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

在我的情况下,编写一个模块浪费在头顶上。这些功能只需要可用于这一个脚本。我不想弄乱模块路径或脚本位置。我只想运行一个带有定义在其中的函数的脚本。 c $ c>, process end 块代码应该处理管道输入。 begin 块用于预处理,并在输入开始处理之前运行一次。 end 块用于后处理,并在输入处理完成后运行一次。如果你想在 end 块以外的地方调用一个函数,你可以在 begin 块中定义它(重新定义它在进程块中一遍又一遍会浪费资源,即使你没有在 begin 中使用它($ c> block)。




$ b

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


BEGIN {
函数f(){
param([String] $ m )
写入主机$ m
}

f(开始)
}

过程{
f(Process :+ $ Value)
}

END {
f(End)
}

about_Functions


将对象映射到函数



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


$ b

  function< name> {
begin {<语句列表>}
过程{<语句列表>}
结束{<语句列表>}
}

Begin语句列表只运行一次,在函数的开头。



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



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







如果你的代码没有处理管道输入,你可以删除 begin process end 完全阻止并将所有内容放在脚本正文中: $ b

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


函数f(){
param([字符串] $ m)
写主机$ m
}

f(开始)
f(Process:+ $ Value)
f End)






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

  [CmdletBinding()] 
参数(
[Stri ng] $ Value


函数Main {
[CmdletBinding()]
param(
[String] $ Param


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

函数f(){
param([String] $ m)
写主机$ m
}

Main $价值


I'm writing a script that I'd like to use PowerShell's CmdletBinding() with. Is there a way to define functions in the script? When I try, PowerShell complains about "Unexpected toke 'function' in expression or statement"

Here's a simplified example of what I'm trying to do.

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

BEGIN {
    f("Begin")
}

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

END {
    f("End")
}

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

In my case, writing a module is wasted overhead. The functions only need to be available to this one script. I don't want to have to mess with the module path or the script location. I just want to run a script with functions defined in it.

解决方案

You use begin, process, and end blocks when your code is supposed to process pipeline input. The begin block is for pre-processing and runs a single time before processing of the input starts. The end block is for post-processing and runs a single time after processing of the input is completed. If you want to call a function anywhere other than the end block you define it in the begin block (re-defining it over and over again in the process block would be a waste of resources, even if you didn't use it in the begin block).

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

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

    f("Begin")
}

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

END {
    f("End")
}

Quoting from 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.


If your code doesn't process pipeline input you can drop begin, process, and end blocks entirely and put everything in the script body:

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

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

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


Edit: If you want to put the definition of f at the end of your script you need to define the rest of your code as a worker/main/whatever function and call that function at the end of your script, e.g.:

[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

这篇关于如何在CmdletBinding()脚本中定义函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆