Powershell Unload Module... completely

Solution 1:

There is a workaround. Open up another instance of PowerShell:

PS > powershell
PS > [load DLL]
PS > [do work]
PS > exit

After the exit, you'll be brought back to the instance of PowerShell from which you made this call (assuming you made the powershell call inside and instance of PowerShell). You can pass in any of the normal arguments to powershell, so you can use -Command or -File. E.g.,

PS > powershell -Command '[load DLL]; [do work]' # Executes a command and exits
PS > powershell -Command '.\myscript.ps1 param1 param2' # Executes the script and exits
PS > powershell -File .\myscript.ps1 param1 param2 # Executes a script and exits.

When PowerShell exits, it will release the lock on the DLL, allowing you to continue working.

All of this was done from the PowerShell command line interface. I haven't tested what happens if you throw powershell in the middle of a script or if this works within ISE. (I suspect it works within ISE.) Even if if doesn't work inside a script, this is still useful during development.

Edit:

Did some checking. So this seems to work fine from within scripts and in ISE, but there's a caveat within ISE. From ISE, you can't read any input from the user while you're inside the separate PowerShell process. If you try, the script or commands stop to wait, but no input box is shown like normal, and of course, you can't type directly into the output window in ISE. So if you need to prompt for input in the middle of [do work], prompt before firing up a new instance of PowerShell, and pass it into the work as a parameter. These aren't problems at all if you're using the regular PowerShell command line.

Solution 2:

No. As PowerShell uses .NET underneath it has the same requirements. You cannot unload a dll from a .NET AppDomain without unloading the AppDomain itself. As the PowerShell UI lives in the same AppDomain this is not possible.