Question

I have a large set of functions defined in a PowerShell script module. I want to use Export-ModuleMember -Function *, but I want to exclude just one function. It'll be easier for me to exclude this one function than to list all the included functions. Is there anyway to achieve this?

Was it helpful?

Solution

So I know this is way late to the party, but the simple solution is to place all functions you do not want exported AFTER the Export-ModuleMember cmdlet. Any Functions defined AFTER that statement will not be exported and WILL be available to your module (aka private functions).

Perhaps the more elegant method is to include a Module Definition file, and simply not include that function on the list of functions to include.

The idea of writing code inside the module to not include functions in the module seems overly complicated, this is not a new feature, I've been placing functions after Export since the very early days of PowerShell.

OTHER TIPS

My stock answer about excluding functions is to use verb-noun naming for functions I want to export, and use initial caps for everything else.

Then, Export-ModuleMember -function *-* takes care of it.

Find all functions in a script and then filter based on what you want to exclude (assuming PowerShell v2):

$errors = $null 
$functions = [system.management.automation.psparser]::Tokenize($psISE.CurrentFile.Editor.Text, [ref]$errors) `
    | ?{(($_.Content -Eq "Function") -or ($_.Content -eq "Filter")) -and $_.Type -eq "Keyword" } `
    | Select-Object @{"Name"="FunctionName"; "Expression"={
        $psISE.CurrentFile.Editor.Select($_.StartLine,$_.EndColumn+1,$_.StartLine,$psISE.CurrentFile.Editor.GetLineLength($_.StartLine))
        $psISE.CurrentFile.Editor.SelectedText
    }
}

This is the technique I used for v2 to create a ISE Function Explorer. However, I don't see a reason why this won't work with plain text outside ISE. You need to workaround the caret line details though. This is just an example on how to achieve what you want.

Now, filter what is not required and pipe this to Export-ModuleMember!

$functions | ?{ $_.FunctionName -ne "your-excluded-function" }

If you are using PowerShell v3, the parser makes it a lot easier.

My solution, using PowerShell V3, as hinted by ravikanth (who was using V2 in his solution), is to define a PSParser module:

Add-Type -Path "${env:ProgramFiles(x86)}\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll"

Function Get-PSFunctionNames([string]$Path) {
    $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$null, [ref]$null)
    $functionDefAsts = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)
    $functionDefAsts | ForEach-Object { $_.Name }
}

Export-ModuleMember -Function '*'

And in a module, if I want to exclude a given function, the last line would look like:

Export-ModuleMember -Function ( (Get-PSFunctionNames $PSCommandPath) | Where { $_ -ne 'MyPrivateFunction' } )

Note that this will only work in PowerShell V3 or later because the AST parser and $PSCommandPath were introduced in version 3.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top