How can I create executable package for OneGet Install-Package? - powershell

I understand how to create a package for NuGet. There's also nothing especially hard with creating a NuGet package or PowerShell package.
I'm aware it may be impossible to create PowerShell package with binary cmdlet in .NET Core, so wondering if it's possible to create a package with lifecycle hooks.
Say, in npm, you can define scripts in package.json to declare pre/post install/publish dependencies.
So, the question is:
How can I perform custom script after having my package added to the system via Install-Package?
For example, I want to add executable to PATH (likely to be pretty common task)

Likely, this one will work:
project.json#scripts
Note, that valid values are allowed platform executables, so, as I got that, PowerShell is not allowed by default.
Quick workaround, as far as arguments are available:
runner.cmd:
#powershell -File %1
and in project.json:
"scripts": {
"postrestore": "%project:Directory%/scripts/runner.cmd %project:Directory%/scripts/install.ps1"
}

Related

Call a chocolatey package in powershell based on its package name

I recently set up a new machine and installed/enabled chocolatey. As far as I can remember I was able to call a package via powershell based on the package name. For instance, if I wanted to install mongodb, I used to type choco install mongodb - and was able to call the mongo client by simply typing mongo in the powershell console. Is there a way to see if something is bound to a specific shim ? or is there an option to enable it?
I don't think there is a way to match packages with shims, but you can check the executable a shim points to, along with general information about it and what would happen if you run the shim:
shimname.exe --shimgen-noop
I tried crafting a command to check all the shims in the $env:ChocolateyInstall\bin directory, but there's no guarantee that executables there are going to be a shim. I tried filtering out the known Chocolatey executables as well, but some packages (like putty) drop their real executables right in the bin folder, and won't respond to the shim parameters like you'd expect.
Looking at the Install-BinFile cmdlet, it doesn't look like Chocolatey provides a way to track shims at all as it doesn't even do this itself. I think it uses the same logic to track automatically generated shims at package uninstall time, but any shims explicitly created with Install-BinFile also need to have Uninstall-BinFile called in the associated chocolateyUninstall.ps1 script or the shim won't be removed at package uninstall time.
Short of crawling the $env:ChocolateyInstall\lib\packageName directory for potential automatic shim names, or the chocolateyInstall.ps1/chocolateyUninstall.ps1 scripts for explicit shims, you're not going to be able to match a shim to a package.

PowerShell Gallery vs NuGet Gallery vs MSI vs Snap-Ins

I'm quite confused at the differences here and would appreciate some clarification.
What I think is that in PowerShell 1.0, there were Modules (commands written in PowerShell) and Snap-Ins (a dynamic link library that implements cmdlets and providers). However, the lines became blurred as Modules can contain DLLs that the Cmdlets and Functions in the module can call, so eventually Snap-Ins are now effectively redundant.
Then came NuGet packages, which seems to be some kind of package deployment system (build by Microsoft??). This is not PowerShell specific in the way that the PowerShell Gallery is, and NuGet packages can deploy any kind of functionality to a Windows system. Is it correct to think of NuGet as the successor of MSI as a package deployment method?
So, we have PowerShell Gallery (only for PowerShell modules) and NuGet (for anything, but also contains PowerShell packages). What is a Package and how is it defined differently from a Module in the context of PowerShell?
Then, I notice that PowerShell have *-Package and *-Module Cmdlets, so you can run:
find-module *7zip*
find-package *7zip*
The same four items are returned here, but where are these Cmdlets pointing? If you run install-module is the Module installed from the PowerShell Gallery, and if you run install-package is an equivalent package (that is not a Module, but a package, whatever that is!) installed from NuGet?
Any clarification on the above would be greatly appreciated as I'm finding it hard to find clear definitions of what all of these things are and how they interact with each other (and indeed, what is the best way for me to approach installing them and upkeep)?

Can the Powershell "using" statement with dynamic module paths?

I have some powershell modules which contain classes I need to instantiate from various powershell scripts. To access the classes from the powershell scripts I am have statements like:
using module "..\..\Library\Mymodule.psm1"
But I dont know ahead of time where in the folder hierarchy my library will be relative to the script.
We dont want to use the standard powershell modules folders because these classes are under source control and deploying to user's folders would be nightmarish.
This is an extremely hard topic to google because, well "using" is used everywhere!
Tried provide multiple possible locations for the same file but of course we get an error for the alternate locations that do not exist:
The specified module 'C:...Mymodule.psm1' was not loaded because no valid module file was found in any module directory.
At line:0 char:0
using module "..\..\Library\Mymodule.psm1"
using module "..\Library\Mymodule.psm1"
using module ".\Library\Mymodule.psm1"
But I'd rather run a function to first determine the correct module path, and then use something like this
using module "$foundModulePath"
Is there any way to dynamically set the path of a module and then "using" it?
I would version my modules in a separate repository and write a function the clones that repository inside the workspace at runtime.
Using tags in that repo - would allow me to control the version of the modules I am loading for each script.
This will make the development of the modules possible, even when a script still has to use the old versions and I don't want to "invest" time in re-writing it , just because I've changed a dependency.
idea no 2.
Gradle is very good in handling messy dependencies lists in big projects.
You can build a gradle script that prepares the workspace and then, from inside of it, execute your powershell script.
See Link here

How do you install Swift package binaries after building them?

After building a package how do you install it on the system?
For example, I'm trying to install Swift language server but I have no idea what to do after swift build. Do I have to copy executables and libraries manually?
In CMake/make world there is always a make install step. Is there anything similar in Swift package manager? There doesn't seem to be an install command or something similar. Am I missing something?
Swift Package Manager produces plain executables, in .build/debug or .build/release directory. You can see the last line in its output Linking .build/debug/<the name of the main module in the Package>.
If not specified otherwise, you can just run the result executable, as any other executable, by typing its path in the command line and providing parameters as needed.
Swift Package Manager does not support custom scripts or targets, like install, deploy etc. If there is a need for installation/deployment automation, it should be done by additional scripts or tools, like Makefile.

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.