What is the difference between a cmdlet and a function?

会有一股神秘感。 提交于 2020-05-11 05:22:54

问题


There are two elements in a module manifest: cmdlet and function.

What is the difference between a cmdlet and a function?


回答1:


A cmdlet is a .NET class written in C# or other .NET language and contained in a .dll (i.e. in a binary module). A function is specified directly in PowerShell in a script, script module or at the command line. A module manifest may include both script and binary modules so the manifest needs to be able to export both cmdlets and functions. It's even possible to have both a cmdlet and a function with the same name exported from a single manifest though that's generally not recommended.




回答2:


To complement Bruce Payette's helpful answer:

Not all functions are created equal in PowerShell:

  • An advanced function is the written-in-PowerShell analog of a 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 is what makes it an advanced one; as such, it supports certain standard behaviors:

    • You gain automatic support for common parameters such as -Verbose, and -OutVariable and, if the function is implemented accordingly, for -WhatIf and -Confirm.
    • Arguments not bound to explicitly declared parameters result in an error on invocation.
    • Typically, but not necessarily, advanced functions support one-by-one pipeline-input processing via a process { ... } script block, via parameter-binding parameters decorated with ValueFromPipeline and/or ValueFromPipelineByPropertyName.

    • Unfortunately, even advanced functions and cmdlets aren't created fully equal:

      • Advanced functions run in a child variable scope, unlike cmdlets.

        • However, it is possible to gain access to the caller's variables even in functions placed in modules (to functions outside of modules the caller's variables are visible by default, owing to PowerShell's dynamic scoping), via the $PSCmdlet.SessionState.PSVariable object, as shown in this answer.
      • Advanced functions apply culture-invariant parameter conversions, unlike cmdlets.

      • Advanced functions, in Windows PowerShell, handle ValueFromRemainingArguments differently than cmdlets.
        • This inconsistency was resolved in PowerShell Core, but, unfortunately, in a manner that created more problems than it solved - see GitHub issues #5955 and #6451.
  • A simple function, by contrast:

    • is appropriate for script- and module-internal helper functions
    • requires less "ceremony" (simpler syntax without parameter attributes, single-script-block body)
    • can, however, still process pipeline input via automatic variable $Input or even via a process { ... } block, if desired.
    • also runs in a child scope by default; outside of modules (which simple function shouldn't be exported from anyway), the caller's variables are visible owing to PowerShell's dynamic scoping; modifying them (which should generally be avoided) requires calls to Set-Variable with -Scope 1.
    • Note that there's also a specialized, but rarely used variant of a simple function optimized for pipeline processing, defined with the Filter keyword. Its body is implicitly invoked for each pipeline input object, reflected in automatic variable $_.

While exporting functions as as part of a module - preferably via its module manifest (*.psd1) - doesn't enforce that functions be advanced ones, it is good practice to only exported advanced functions.



来源:https://stackoverflow.com/questions/51911385/what-is-the-difference-between-a-cmdlet-and-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!