cmdlet 和函数之间有什么区别?
What is the difference between a cmdlet and a function?
module manifest 中有两个元素:cmdlet 和函数。
cmdlet 和函数有什么区别?
cmdlet 是用 C# 或其他 .NET 语言编写并包含在 .dll 中(即二进制模块)的 .NET class。函数直接在 PowerShell 中的脚本、脚本模块或命令行中指定。模块清单可能包括脚本和二进制模块,因此清单需要能够导出 cmdlet 和函数。甚至可以从单个清单导出具有相同名称的 cmdlet 和函数,但通常不推荐这样做。
补充:
并非所有函数在 PowerShell 中都是平等创建的:
一个advanced function is the written-in-PowerShell analog of a (binary) cmdlet (which, as stated, is compiled from a .NET language); decorating a function's param(...)
block with the [CmdletBinding()]
attribute or decorating at least one parameter with a [Parameter()]
attribute thanks, Ansgar Wiechers
是什么使它成为高级;因此,它支持某些 标准行为:
您获得对 common parameters 的自动支持,例如 -Verbose
和 -OutVariable
,并且在选择加入的基础上,对 -WhatIf
和-Confirm
.
无法绑定到显式声明的参数的参数会导致调用错误。
通常,但不一定,高级函数通过 process { ... }
脚本块,通过用 ValueFromPipeline
装饰的参数绑定参数支持一对一的管道输入处理and/or ValueFromPipelineByPropertyName
.
不幸的是,即使 高级功能和 cmdlet 也不是完全平等的:
高级函数 运行 在 子变量范围 中,与 cmdlet 不同。
- 但是,即使在 模块 中的函数中也可以访问调用者的变量(对于模块外的函数,默认情况下调用者的变量是可见的,由于 PowerShell 的动态作用域),通过
$PSCmdlet.SessionState.PSVariable
对象,如 this answer. 所示
高级功能apply culture-invariant parameter conversions, unlike cmdlets.
高级函数,在 Windows PowerShell、handle ValueFromRemainingArguments
differently than cmdlets.
中
一个simple function,相比之下:
- 适用于脚本和模块内部的 helper 函数
- 需要更少的“仪式”(没有参数属性的更简单的语法,单脚本块主体)
- 注意:与高级函数和 cmdlet 不同,简单函数接受任意参数,无论它们是否绑定到已声明的参数;未绑定的参数在 automatic
$args
variable; see this answer 中反映了如何 防止 传递未绑定(意外)参数。
- 但是,如果需要,仍然可以通过自动变量
$Input
甚至通过 process { ... }
块处理管道输入。
默认情况下,- 在 子范围 中也有 运行;在模块之外(无论如何都不应该从中导出简单函数),由于 PowerShell 的动态范围,调用者的变量是 可见的 ; 修改它们(通常应该避免)需要用
-Scope 1
调用Set-Variable
。
- 请注意,还有一个专门但很少使用的 变体 是为流水线处理优化的简单函数,使用
Filter
关键字定义。它的主体为每个管道输入对象隐式调用,反映在自动变量 $_
.
虽然 将功能导出为模块的一部分 - 最好通过其模块清单 (*.psd1
) - 不会 强制执行 函数是 高级 函数,好的做法是只导出 高级 函数.
module manifest 中有两个元素:cmdlet 和函数。
cmdlet 和函数有什么区别?
cmdlet 是用 C# 或其他 .NET 语言编写并包含在 .dll 中(即二进制模块)的 .NET class。函数直接在 PowerShell 中的脚本、脚本模块或命令行中指定。模块清单可能包括脚本和二进制模块,因此清单需要能够导出 cmdlet 和函数。甚至可以从单个清单导出具有相同名称的 cmdlet 和函数,但通常不推荐这样做。
补充
并非所有函数在 PowerShell 中都是平等创建的:
一个advanced function is the written-in-PowerShell analog of a (binary) cmdlet (which, as stated, is compiled from a .NET language); decorating a function's
param(...)
block with the[CmdletBinding()]
attribute or decorating at least one parameter with a[Parameter()]
attribute thanks, Ansgar Wiechers 是什么使它成为高级;因此,它支持某些 标准行为:您获得对 common parameters 的自动支持,例如
-Verbose
和-OutVariable
,并且在选择加入的基础上,对-WhatIf
和-Confirm
.无法绑定到显式声明的参数的参数会导致调用错误。
通常,但不一定,高级函数通过
process { ... }
脚本块,通过用ValueFromPipeline
装饰的参数绑定参数支持一对一的管道输入处理and/orValueFromPipelineByPropertyName
.不幸的是,即使 高级功能和 cmdlet 也不是完全平等的:
高级函数 运行 在 子变量范围 中,与 cmdlet 不同。
- 但是,即使在 模块 中的函数中也可以访问调用者的变量(对于模块外的函数,默认情况下调用者的变量是可见的,由于 PowerShell 的动态作用域),通过
$PSCmdlet.SessionState.PSVariable
对象,如 this answer. 所示
- 但是,即使在 模块 中的函数中也可以访问调用者的变量(对于模块外的函数,默认情况下调用者的变量是可见的,由于 PowerShell 的动态作用域),通过
高级功能apply culture-invariant parameter conversions, unlike cmdlets.
高级函数,在 Windows PowerShell、handle
中ValueFromRemainingArguments
differently than cmdlets.
一个simple function,相比之下:
- 适用于脚本和模块内部的 helper 函数
- 需要更少的“仪式”(没有参数属性的更简单的语法,单脚本块主体)
- 注意:与高级函数和 cmdlet 不同,简单函数接受任意参数,无论它们是否绑定到已声明的参数;未绑定的参数在 automatic
$args
variable; see this answer 中反映了如何 防止 传递未绑定(意外)参数。
- 注意:与高级函数和 cmdlet 不同,简单函数接受任意参数,无论它们是否绑定到已声明的参数;未绑定的参数在 automatic
- 但是,如果需要,仍然可以通过自动变量
$Input
甚至通过process { ... }
块处理管道输入。
默认情况下, - 在 子范围 中也有 运行;在模块之外(无论如何都不应该从中导出简单函数),由于 PowerShell 的动态范围,调用者的变量是 可见的 ; 修改它们(通常应该避免)需要用
-Scope 1
调用Set-Variable
。 - 请注意,还有一个专门但很少使用的 变体 是为流水线处理优化的简单函数,使用
Filter
关键字定义。它的主体为每个管道输入对象隐式调用,反映在自动变量$_
.
虽然 将功能导出为模块的一部分 - 最好通过其模块清单 (*.psd1
) - 不会 强制执行 函数是 高级 函数,好的做法是只导出 高级 函数.