How do I import a new PowerShell cmdlet? - powershell

I've written a PowerShell cmdlet in C#.
Where do I copy the library at this point?
And how do I import it into PowerShell so that I can use it?

There are two ways to load your new cmdlet.
Import Cmdlets Using Modules. Here you either put your cmdlet DLL into a system-recognized path that will allow you to load a module with a simple name (e.g. Import-Module MyModule), or you can put it in an arbitrary directory for which you need to specify a complete path (e.g. Import-Module C:\code\MyModule.dll). If you have only a single DLL and no dependencies, you can actually give the DLL as shown. Typically, though, you will also want to create a manifest using New-ModuleManifest (creating, e.g., a MyModule.psd1 file) then pass that psd1 file rather than the dll to Import-Module.
Create a Windows PowerShell Snap-in. This requires writing one additional C# class, quite small, that provides the glue necessary to treat your cmdlet as a snap-in. Then you have to register the snap-in with the installutil program and finally load the snapin with Add-SnapIn. (See also How to Register Snap-ins...)
Curiously, almost all articles that talk about writing cmdlets suggest the snap-in approach, but this is simply because that technique has been available since PowerShell version 1, while modules did not come along until version 2. Everything I have read, though, suggests essentially that the snap-in approach is deprecated to the simpler--and more flexible--module approach.

Related

How does Powershell Auto-Load Modules?

We learn that Powershell introduced Module Auto-Loading in 3.0 :
... PowerShell imports modules automatically the first time that you
run any command in an installed module. You can now use the
commands in a module without any set-up or profile configuration, ...
And this is done via PSModulePath.
What the docs fail to explain is how Powershell can detect which commands are in a module without first loading the module.
That is, when I use Import-Module, I "know" that Powershell will execute (??!) the powershell code in my .psm1 file, exporting all functions, ... or whatever I spec with Export-Modulemember.
However, the Auto-Load feature has to know before hand that a certain command is available via a certain module without actually loading the module.
Since we had some misbehaving third party modules in PsModulePath and since we have a very few modules that we wrote ourselves that we like to anchor in PSModulePath, I would very much like to understand how the files in PSModulePath are processed.
This is a partial answer.
This is done/implemented via Get-Command and this seems to be enabled to "parse" module files without actually executing the PoSh Code there. See below.
From the powershell docs:
Implicitly Importing a Module
... works on any module in a directory that is included in the value
of the PSModulePath environment variable ...
To support automatic importing of modules, the Get-Command cmdlet
gets all cmdlets and functions in all installed modules, even if the
module is not imported into the session. ...
And then:
Get-Command
The Get-Command cmdlet gets all commands that are installed on the
computer ...
Get-Command that uses the exact name of the command, without
wildcard characters, automatically imports the module that contains
the command so that you can use the command immediately. ...
Get-Command gets its data directly from the command code, unlike
...
The docs do not explain how this is implemented, but one could possibly look up how it's done in the source code. (I wasn't so far able to find it, despite browsing the sources for a while.)
Incidentally I find mentioned that Powershell 3 was the first version to expose the AST, so it stands to reason that the posh code does exactly that: Parse the Scripts and inspect their AST in some way to determine if the command is provided.

PowerShell Core and AppX package management

I am using PowerShell 6.2 preview at the moment. In my script I am trying to do stuff with Windows 10 apps. To be able to use commands like Get-AppxPackage, I need to import Windows modules from previous PowerShell like so:
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Appx\Appx.psd1 -SkipEditionCheck
Import-Module C:\Windows\system32\WindowsPowerShell\v1.0\Modules\dism\dism.psd1 -SkipEditionCheck
Does PowerShell core has its own modules to work with this? I found Get-Package for example, but that does not give me anything.
Since this is one of the top search results for PowerShell Core Get-AppxPackage, I'm going to take the information from the link provided in the comments and provide an answer, with example.
As LangsGalgEnRad pointed out in the comments, it's easiest just to do this from Windows PowerShell, but ultimately that's just-shy-of-deprecated at this point, with Microsoft stating that there are to be no more fixes or changes other than critical security issues. That said, it's still (afaik) universally available in Windows installations.
But for those of us who want to follow Microsoft's advice to use PowerShell Core, LangsGalgEnRad also points out in the comments the WindowsCompatibility module from Microsoft. Reading the blog post, this seems a bit safer than importing a Windows module (e.g. AppX) from PowerShell Core, since among other things ...
WindowsCompatibility is very careful to not overwrite native PowerShell core commands.
To install from PowerShell Gallery:
Install-Module WindowsCompatibility
Example usage for AppX:
Import-Module WindowsCompatibility
Import-WinModule AppX
Get-AppxPackage

How to share a Powershell psm1 across Azure Functions

You can create a modules folder and place a psm1 file there for auto loading. Is there a way to share that psm1 across functions in the same App Service?
Yes, you may move your modules folder up the directory tree and place it under wwwroot, e.g. D:\home\site\wwwroot\mymodules. Auto-loading will not occur in this setup, so you will need to explicitly add the Import-Module command in your PowerShell script, e.g.
Import-Module "D:\home\site\wwwroot\mymodules\MyScript.psm1";
If you suspect that MyScript.psm1 is already installed on the system and need to override it with your version, add the -Global flag as follows
Import-Module "D:\home\site\wwwroot\mymodules\MyScript.psm1" -Global;

How to add a PSCmdlet or PSSnapin to hosted Powershell runtime without installing the snapin

My scenario is as follows.
I am uploading my dll through web UI.
I am hosting a PowerShell runspace in an ASP.NET application.
I The DLL contains the PSCmdlet and would like to make use of it.
The PSCmdlet only needs to be accessible within the hosted runspace and does not need to be
used in any external scenario.
The application does not have access to the windows registry as it runs with limited privileges, so I cannot install the PsSnapin.
Is it possible for me to use the commandlet without going through the installation process?
If your use case is straightforward then it is possible. Please see these question: Hosted PowerShell cannot see Cmdlets in the same Assembly. Several answers there provide different ways, choose one that works better or you like more.
If you use PowerShell V2 you can use an unregistered snapin as a binary module.
Import-Module ‹path-to-dll›
add a -passthru to get the PSModuleInfo reference which describes the module.

How do I create powershell 2.0 modules?

I've heard powershell 2.0 CTP has modules, but I can't find much example code or instructions. I've read what little help there seems to be online...
But I just keep getting "The term 'Add-Module' is not recognized as a cmdlet..." when I try and load a module.
Any help would be gratefully received!
Edit (July 2010)
Please note this question is based on powershell 2.0 CTP and is therefore a year and half out of date! Please see Samuel Jack's answer for help with the powershell 2.0 RTM.
With the Win7 build, Add-Module is gone. The new cmdlet is Import-Module. The easiest way to create a module is rename a PS1 file to a PSM1 file. From there you can do all sorts of things including the module manifest.
I'm no Powershell expert, but here's what I just figured out using PowerShell 2.0 RTM.
Suppose you want to create a module called MyModule:
Make sure that you have created the folder %My Documents%\WindowsPowershell\Modules
Create a folder inside Modules called MyModule
Put your code in a file inside MyModule and name the file MyModule.psm1
Remember to use the Export-ModuleMember command as the last thing in your script file. Export-ModuleMember -Function * -Alias * will export all functions and aliases
In scripts where you want to use the module, use the command Import-Module MyModule
By default Powershell is configured not to run any kinds of scripts from files, so you need to alter the security settings. Set-ExecutionPolicy Unrestricted will get you going if you're not concerned about scripts needing to be signed.
Here's a little bit of information.
http://huddledmasses.org/powershell-modules/
http://blogs.msdn.com/mediaandmicrocode/archive/2008/08/10/microcode-all-about-modules-windows-powershell-ctp2.aspx
Let's hope that the upcoming CTP3 has some useful documentation about modules.
Modules will hopefully solve a few problems. Right now, we can use dot sourcing to get functions, variables, and scripts into a PowerShell session's global scope.
The problem is that this can pollute your session with all kinds of global variables and helper functions that an end user may not want/need directly.
Modules will allow you as an author to build scripts and only make certain functions/variables avaiable to the end user of the module.
They also essentially replace the concept of a PSSnapin. You can use Add-Module Some.dll to add an assembly that has cmdlets in it.
What is really cool is what is called a Module Manifest. This is a hash table that basically specifies all kinds of dependcies as well as author, name, GUID Identifier, and version number. When a user loads a module that has a module manifest, it will check all the dependencies and run any scripts the module author deems necessary.
There should be some decent documentation on these when CTP3 ships.
Hope that helps a bit.
Andy
Windows PowerShell v2.0: TFM (sapienpress.com) has information and samples in one of the chapters. It's available as an ebook which is updated as new CTPs are released. I also blogged about them on ConcentratedTech.com, and there's been discussion on them at PowerShellCommunity.org in the forums.