Scroll Top
Evotec Services sp. z o.o., ul. Drozdów 6, Mikołów, 43-190, Poland

Executing hidden or private functions from PowerShell Modules

img_5d2b4ff64affd

When you write PowerShell modules, there's a high chance you will have conflicts with either existing system commands (you should avoid that) or with someone else's modules. There are also times when someone wants to use a private function from a module that only exports essential functions. Here's a couple of ways how to deal with those scenarios.

Discovering hidden PowerShell commands

For this article, I'll use something you should never, or very rarely do. I will create a small function called Get-Date and therefore overwrite PowerShell one.

function Get-Date {
    param(
        [string] $Something
    )
    Write-Host "This function does something $Something"
}

Get-Date -Something 'Else'

Now for the remaining of the PowerShell session whenever you will try to use Get-Date for something, it will be my function that shows up rather than the built-in one. This may be less than great. How can you deal with a scenario where you have two or more commands from different modules having the same name?

Get-Command Get-Date -All | Format-Table -Property CommandType, Name, ModuleName -AutoSize

The command above allows you to find out all modules that have precisely the same function as you want to execute. It shows that right now Get-Date can be found without any module (which is correct because I've copy/pasted that function into PS Session) and there's a built-in cmdlet Get-Date from Microsoft.PowerShell.Utility. So how can we get it to work without renaming our function or someone else's function in a module you just downloaded? Well, there are two ways to do it.

Import-Module Microsoft.PowerShell.Utility -Prefix 'Test' 
Get-TestDate

Use Prefix in Import-Module command to define your prefix. This gives you the ability to set something useful for you without going to the developer of some module and complaining that his function conflicts with your function or someone else's function. For example, in Dashimo, I have a function called Table. The same function name is in PScribo module. All you have to do to fix this clash of functions is to use Import-Module PScribo -Prefix PScribo to be able to use both modules even at the same time.

Import-Module Dashimo
Import-Module PScribo -Prefix PScribo

# Dashimo
Dashboard {
     Table -
}

# PScribo
Document {
      PScriboTable
}

So that's one way, and it's pretty straightforward. The second way is actually to call a command by its module name.

Microsoft.PowerShell.Utility\Get-Date 

Calling private functions from PowerShell modules

Sometimes developer of PowerShell module creates a function that he then uses that function across his module but hides it, so it's not accessible when someone installs and imports it. I have created several PowerShell modules that have Public one or two commands and then Private, non-accessible functions that I didn't want to expose. But what if you wanted to use some of those functions? What if the function was so good that you wanted to use it in your code without “extracting” that function from someone else's code (which may or may not be as simple as copy/paste). Fortunately, there is a way to do it:

Get-Command -Module PSWinDocumentation.AD 

As you can see my PSWinDocumentation.AD PowerShell module has only two exported functions. That was intentional and something I've done on purpose. However, that module has about 100 small, internal, private functions that I use to deliver results. If for some reason you would like to use any of those functions in your code you can either copy/paste it from my GitHub repository into your own and use the function to suit your needs or call it like that.

$Features = Import-Module -Name 'PSWinDocumentation.AD' -PassThru
& $Features { Get-WinADDomain | Format-Table -AutoSize }

Notice that again I'm using Import-Module, but the magic here is about PassThru switch. You can utilize any of the private functions that way. In my case, I'm calling Get-WinADDomain. Notice that I'm using & (ampersand)& is the call operator which allows you to execute a command, a script, or a function.

So instead of copying some functions from other modules, you can use that instead.

Related Posts