cmdlet和函数之间有什么区别?

maz*_*zzy 7 powershell cmdlets function

模块清单中有两个元素:cmdlet和function.

cmdlet和函数之间有什么区别?

Bru*_*tte 9

cmdlet是一个用C#或其他.NET语言编写的.NET类,包含在.dll中(即在二进制模块中).函数在PowerShell中直接在脚本,脚本模块或命令行中指定.模块清单可能包括脚本和二进制模块,因此清单需要能够导出cmdlet和函数.甚至可以同时从单个清单中导出cmdlet和具有相同名称的函数,尽管通常不建议这样做.

  • 还值得强调的是,许多社区模块提供的 cmdlet 编写为函数,但其​​行为(从用户角度)与上述实际 cmdlet 完全相同。 (2认同)
  • 请注意,PowerShell 团队已正式更改了 cmdlet 一词的定义,以包括“高级功能”等。请参阅 https://github.com/MicrosoftDocs/PowerShell-Docs/issues/6105 (2认同)

mkl*_*nt0 9

补充Bruce Payette的有用答案:

并非所有函数在PowerShell中都是相同的:

  • 一个高级功能是写入的-PowerShell中一个的模拟小命令(其如所述的那样,被编译从.NET语言); param(...)使用[CmdletBinding()]属性装饰一个函数块或者[Parameter()]属性 感谢装饰至少一个参数,Ansgar Wiechers 是一个先进的参数 ; 因此,它支持某些标准行为:

    • 您可以自动支持常见参数,例如-Verbose,-OutVariable和,如果相应地实现了该功能,则为-WhatIf-Confirm.
    • 未绑定到显式声明的参数的参数会导致调用错误.
    • 通常,但不是必须的,高级功能通过process { ... }脚本块,通过用ValueFromPipeline和/或装饰的参数绑定参数支持逐个流水线输入处理ValueFromPipelineByPropertyName.

    • 不幸的是,即使高级函数和cmdlet也不是完全相同的:

  • 相比之下,一个简单的功能:

    • 适合于脚本-和模块内部的辅助功能
    • 需要较少的"仪式"(没有参数属性的简单语法,单脚本块体)
    • 但是,如果需要,仍然可以通过自动变量$Input或甚至通过process { ... }块处理管道输入.
    • 请注意,还有一个专门但很少使用的简单函数变体,该函数针对使用Filter关键字定义的流水线处理进行了优化.它的主体是为每个管道输入对象隐式调用的,反映在自动变量中$_.

虽然导出函数作为模块的一部分 - 最好通过其模块manifest(*.psd1) - 不强制执行高级函数,但最好只导出高级函数.

  • _“高级函数在子变量作用域中运行,与 cmdlet 不同”_ -- 确实如此,但是有一种方法可以通过 `$PSCmdlet.SessionState.PSVariable` 访问父(调用者)作用域中的变量](https:// stackoverflow.com/a/46718967/7571258)。 (2认同)