I have a simple PowerShell module contained in a .psm1 file. Is it possible to assign a version number to the module without creating a manifest?
Thanks
Short answer - "no"
Longer answer - the version for a Powershell module is determined by the module manifest. You can create this by running the New-ModuleManifest cmdlet, or by manually creating the manifest file and putting it in a fresh "psd1" file with the same name as your module.
Related
I am using Azure DevOps to deploy PowerShell modules to a server. This release task deploys the modules to the directory C:\Windows\System32\WindowsPowerShell\v1.0\Modules\. I am able to use the modules once they are deployed to this folder successfully.
If I modify one of the modules and re-release it the file in C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ gets updated, however the old version of the module is still used when running from a batch file using pwsh.
I discovered that the module file also exists in the following paths:
C:\Program Files\PowerShell\Modules\
C:\Program Files\PowerShell\6\Modules\
When deploying the new version using Azure DevOps the old version in the above two directories are not updated. Manually updating the module in those locations fixes the problem.
Why is the module file being copied into those two additional paths?
Should those copies be overwritten when a new version of the module is deployed?
What is the correct way of deploying a module in this scenario?
Powershell uses different paths to load modules. Use $env:PSModulePath -split ";" to know which are the paths being used.
The difference between each path is user scope and usage scope (e.g. made for custom modules or windows official modules).
Now, by default, PS looks for the latest version of each module across all the paths. So maybe the old version is being run because at the time you re-deploy. You are not updating the module version in the Module Manifest, so if PS see they are the "same" version it gets the last one loaded on the PSModulePath.
Take a look at this awesome post for more details: Everything you wanted to know about PowerShell's Module Path
Now to your questions.
Why is the module file being copied into those two additional paths?
This could be a server configuration or the script that you are using to deploy.
Should those copies be overwritten when a new version of the module is deployed?
Not necessarily, if the versions are maintained correctly. On the post shared says how to check the versions of each module.
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.
I'm currently learning about PowerShell modules. If you're using a .psd1 manifest file, you have the option to use .ps1 script files as well as .psm1 manfiest files. Why do you need both?
I created a module with both, with the .psm1 set as RootModule and the .ps1 set in ScriptsToProcess and I've noted some differences, but I'm not sure what they add up to.
If I add Write-Output statements to both, on import the output is displayed for .ps1, but suppressed for the .psm1. Write-Warnings are displayed for .psm1.
If I run the Get-Command prefix for the module prefix, functions from the .psm1 are listed with the module name whereas functions from the .ps1 file are listed with a blank module name.
The section of your manifest in which you place the references to the Ps1 files determines how they are executed.
In your case:
The ScriptsToProcess will execute the listed PowerShell scripts in the caller's environment prior to importing the module. This makes me think of them as prep scripts.
This is because files listed here are not meant to contain functions; it's meant to be a script. If you want additional functions accessible by your module you have a few options:
List them in NestedModules
Include them in your module
Try listing them in the functions to the export section of the manifest. (I have not tried this method, but it's my understanding that it will work the way you want no matter where the function is located.)
I have written all my powershell functions in a ps1 file.
In another ps1 file ,it is being dot sourced and function are being called.
When i look for better methods i came to know that putting all the functions as modules (.psm1) is better option.
But for .ps1 file i can simply it in a folder and ship it.
With .psm1 file ,it says i have to add it to particular location so that it can be imported.
how to provide .psm1 file to customer then ? should we instruct them to copy to the mentioned location before using it ? (if we don't ship via msi)
Technically you can import psm1 files via path but that isn't the best user experience. If you put the file in a folder under either $home\documents\WindowsPowerShell\Modules or $pshome\Modules then the user can import based on just the name of the psm1 file. Finally, you can put the psm1 file in any location you want and if you modify the PSModulePath environment variable to include that directory, PowerShell will search for modules in that dir.
I want to organize functions into multiple .psm1 files and have them loaded by a single Module Manifest file (.psd1) -- such that Only the .psd1 file would need to have the same name as the module.
I think it should be possible. Can anyone help me out please ?
Launch the Powershell ISE
Use the New-ModuleManifest command
Follow the instructions here - How to Write a Module Manifest. When asked for nested modules, key in the module as Modulepath\Modulename.psm1
Finally, once the .psd1 file is created, load / import it using Import-Module <<module-name>>
You can load them manually in your main module psm1 file using Import-Module calls or by specifying them in the NestedModules key in the manifest file (psd1)