Home > other >  Should I prefer "Export-ModuleMember" or "global:" (or something else) when writ
Should I prefer "Export-ModuleMember" or "global:" (or something else) when writ

Time:10-16

I've been writing a Cmdlet, and, to keep my interfaces clean, I've been manually exporting the functions I care about with Export-ModuleMember.

However, someone pointed out that I could also put my functions directly in the global: scope instead, without calling Export-ModuleMember.

Which one is preferable?

# Option A: Export-ModuleMember
function Do-Something {}
Export-ModuleMember -Function Do-Something

# Option B: global scope
function global:Do-AnotherThing {}

# Something else?

Thanks!


My hunch is that Export-ModuleMember is better since it lets the caller decide which scope the function ends up in (e.g. another cmdlet could import my cmdlet without exposing those exported functions globally), but I'm not sure.

CodePudding user response:

You are spot on. Improperly exporting functions circumvents generally expected behavior when installing modules.

For example, Import-Module protects against clobbering if a cmdlet stomps on a cmdlet already available to the current session, for example. Declaring a function with the global scope circumvents this, and there is rarely a time when this should be done unless the purpose of the module is to actually override something (like perhaps it sets or modifies the prompt in some way). Doing this as a matter of expectation should be crystal clear to who is installing the module via way of module documentation.

Note: Clobbering is the same basic principle of overloading or overriding members in class inheritance. Creating a new entity with the same name that may (overload) or may not (override) have a different signature.

And even though Import-Module errors on clobbering by default, Import-Module -AllowClobber is the solution if you need the cmdlet which would have clobbers the existing one, and lets the user choose whether or not to allow clobbering.


But I also don't recommend Export-ModuleMember either. Rather, you should prepare your module with a manifest (ModuleName.psd1) instead, and specify the exported functions and cmdlets there. There are also many other things you can set in the manifest as well.

It has the benefit of making the module definition easier to understand operationally. And now you don't have to litter your code with a bunch of Export-ModuleMember commands.

Note: If you don't specify the functions or cmdlets to export in your module manifest, or don't have one and do not make use of Export-ModuleMember, all functions and cmdlets will be exported. This may be desirable or it may not be for a given module, but it's important to understand.


Additional Info on Writing Modules

As requested in the comments, here are some additional links around designing and writing PowerShell modules:

  • Related