Saturday, September 20, 2014

Import-Module to Load Custom DLL

Recently a question was raised on how to find and load a custom DLL on any system.  I noted that it can be easily done using Import-Module if we place the DLL in  folder in any of the profile modules folders.

Each installation of PowerShell has a local global "Modules" folder.  To find you local modules folder, if it has been created, do the following:

Split-Path $profile

This will display the default location for the local user profile.  Now we can list the folders to see if the "Modules" folder has been created.

image

We also have a number of other profiles that we can discover like this:

image

When we use Get-Module <module name> PowerShell searches automatically through all of these folders for a Modules folder and looks in each folder for a sub-folder with a matching name.  We can place a module in any of these profile's module's folders and it will be found.

To get the path to any modules folder just split the profile path as above and add +'\Modules' to the string.

Example:

$modulepath=(Split-Path $profile.AllUsersAllHosts)+'\Modules'
dir $modulepath

image

AllUserAllHosts is a merged view of all module paths.

Now we can build and store our DLLs and script modules in any one of these paths and it can be loaded by name alone using Import-Module.

Here is the code from the Example here: Example1 or just type HELP Add-Type –online and go down to example 1.

$source=@'
public class BasicTest{

public static int Add(int a, int b){
return (a + b);
}

public int Multiply(int a, int b){
return (a * b);
}
}
'
@

Add-Type -TypeDefinition $source
[BasicTest]::Add(4, 3)
$basicTestObject = New-Object BasicTest
$basicTestObject.Multiply(5, 2)


Copy and paste this into a PowerShell prompt to see that it works as in the online example.

Now we will create a simple DLL with this code.  First we need to  open a new PowerShell CLI prompt because we have already created that type and we cannot unload it in PowerShell 4 and earlier. To unload a module we must restart PowerShell.  Now paste the following into the new PowerShell console.

$source=@'
public class BasicTest{

public static int Add(int a, int b){
return (a + b);
}

public int Multiply(int a, int b){
return (a * b);
}
}
'
@


Same source but now we are going to use it to build a DLL on disk in out Modules folder.

Start by creating the module folder.

$modules=Split-Path $profile
$BasicTest=$modules+'\BasicTest'
New-Item –Path $BasicTest –Name BasicTest –ItemType Directory

This is what you will see:

image

Now we have just one more step to create out DLL.

Add-Type -TypeDefinition $source -OutputType Library -OutputAssembly "$output\BasicTest.dll"

Now lets see what we have.

Is there a module already loaded with that name?

Get-Module BasicTest

No. Nothing is returned.  Can we find the module by name?

Get-Module –List BasicTest

image


So let's import it and test it again.

image

And that is how to both create and load your custom DLL.  In a domain environment we can distribute extensions by just saving them in the global modules folder.

Monday, September 15, 2014