Installing PowerShell module persistently for all users - powershell

I'm installing a PowerShell module via Octopus Deploy onto a number of different servers. For testing purposes, I went with the guidance of Microsoft's documentation for installing PowerShell Modules.
This worked fine, but as the documentation stated, my changes would be visible only for the current session. That is, if I were to do the following:
$modulePath = [Environment]::GetEnvironmentVariable("PSModulePath", [EnvironmentVariableTarget]::Machine)
# More practically, this would be some logic to install only if not present
$modulePath += ";C:\CustomModules"
[Environment]::SetEnvironmentVariable("PSModulePath", $modulePath, [EnvironmentVariableTarget]::Machine)
When running this installer automatically on tentacle servers, future PowerShell sessions do not appear to see the newly installed modules.
How can I install a PowerShell module in a profile agnostic way so that every PowerShell session started can see it?

PowerShell can only "see" modules installed in one of the directories listed in $env:PSModulePath. Otherwise you'll have to import the module with its full path.
To make a new module visible to all users you basically have two options:
Install the module to the default system-wide module directory (C:\Windows\system32\WindowsPowerShell\v1.0\Modules).
Modify the system environment so that PSModulePath variable already contains your custom module directory (e.g. via a group policy preference).
The latter will only become effective for PowerShell sessions started after the modification was made, though.

This profile applies to all users and all shells.
%windir%\system32\WindowsPowerShell\v1.0\profile.ps1

After taking the steps you spelled out in your question (which I think is the general way to go), I found two ways to get the new module source recognized by Powershell:
Restart the machine. (Works every time.)
Reset the PSModulePath in each open session.
$env:PSModulePath=[Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
I found this was necessary to run in both normal and elevated prompts to get this to work without restarting in each type of prompt. (See also the conversation # Topic: PSModulePath.)

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.

How can you run a config script when installing a perl module?

I've been searching for a couple of hours and I'm coming up empty trying to find a solution. I'm using Dist::Zilla. I have a module that uses a simple config file in .ini format located in the module's share/ directory. When my module is installed, I'd like the install script to prompt the user for configuration options and save the user's options in the config file. Then, using File::UserConfig, it will copy the file over to the user's configuration directory where it can be loaded by the module when it runs.
Someone had suggested the Dist::Zilla::Plugin::MakeMaker::Custom module but I know next to nothing about MakeMaker and how I might write a custom one to kick off the configuration script.
I'm surprised I can't find anything that makes this easy to do. Perhaps I'm searching on the wrong keywords?
You had discussed this in IRC, and the gist is:
You cannot rely on the installation process allowing any interaction, as a large amount of installations are via cpanm which is non-interactive and hides output from Makefile.PL by default. This is because users don't like having to configure things, and as an example, a Carton deployment is frequently non-interactive by its nature. You can allow configuration via environment variables recognized by your Makefile.PL to get around this.
You can document to install using the --interactive option for cpanm in order to respond to prompts in your Makefile.PL, injected into the generated file using the [MakeMaker::Awesome] plugin.
You can include a script with the distribution that will set up the configuration so the user can do it themselves separate from the installation.

Powershell : Executing custom function on remote servers

i have custom functions list, and another config file that is going to be used by the functions, my goal is to run those functions on remote servers, considering that some functions call other function from within them that's why i can't use the method below to call functions that are loaded in the local session.
invoke-command -scriptblock ${function:foo}
is it possible to make a module out of it and then make that module get imported automatically on system boot rather than user logon.
any suggestions on how to accomplish the main goal ?
Well, if you want to install Powershell Module on the system just copy it to appropriate directory.
Installing Modules for all Users in Program Files
If you want a module to be available to all user accounts on the computer, install the module in the Program Files location.
$EnvProgramFiles\WindowsPowerShell\Modules\<Module Folder>\<Module Files>
Reference: https://msdn.microsoft.com/en-us/library/dd878350(v=vs.85).aspx
Install Modules in PSModulePath whenever possible, install all modules in a path that is listed in the PSModulePath environment variable or add the module path to the PSModulePath environment variable value.
The PSModulePath environment variable ($Env:PSModulePath) contains the locations of Windows PowerShell modules. Cmdlets rely on the value of this environment variable to find modules.
By default, the PSModulePath environment variable value contains the following system and user module directories, but you can add to and edit the value.
$PSHome\Modules (%Windir%\System32\WindowsPowerShell\v1.0\Modules)
# This location is reserved for modules that ship with Windows. Do not install modules to this location.
$Home\Documents\WindowsPowerShell\Modules (%UserProfile%\Documents\WindowsPowerShell\Modules)
$Env:ProgramFiles\WindowsPowerShell\Modules (%ProgramFiles%\WindowsPowerShell\Modules)

How to use Powershell DSC for application installation?

Currently we are having application which will be in DVD. there will be setup.exe and user will click on that and fill the inputs it asks for . Inputs such as path where the application to be installed, SQL server instance where db will be created and port numbers which required to be bind.
I am hearing that Powershell DSC can be used for application deployment. But it is not like running some setup.exe and get some inputs for installation.
Whether Powershell DSC can really be used for application deployment? or is it only for environment preparation?
If it is being used for application deployment , how it is being achieved? Whether the end user told to fill the data in some configurationdata psd1 file manually and then run the script?
You can use the built-in Package resource. However you may want to explore looking at cChoco instead as Chocolatey is much more geared towards software management (application deployment) with handling installs, upgrades and uninstallation.
https://github.com/PowerShellOrg/cChoco
Powershell DSC its for Application Deployment, but... you can use it as an exe, what you can do is create a simple console or windows forms EXE program that embeds the script as a resource and the EXE, upon loading retrieves the script and throws it at a PowerShell runspace to execute.
This is a link about it Make PSexe

Creating application installers with PowerShell

Hi I'm wondering if it's possible to create application installers for MSI's. What I want it to do is when I run an MSI I want to be able to run it in it's own process so I can reference it via it's process ID so I can send various keys to it so it installs the way I want it too.
I can code in both C and Java but for the Sys Admins would be good if I could code it in Powershell for them. Also I've seen other installers that can detect when the next instance of the install screen appears so it immediately send the new command keys, well appears that way.
Any advice is welcomed.
MSI's traditionally allow for admins to provide an answer file or arguments using msiexec.
See this q/a on SuperUser or this SO Q/A for more info.
You can then use PowerShell to call the exe's by using the 3rd party Windows Installer PowerShell Module
.
[The Windows Installer PowerShell Module] Exposes Windows Installer functionality to PowerShell, providing means to query installed product and patch information and to query views on packages.
for example:
install-msiproduct .\example.msi -destination (join-path $env:ProgramFiles Example)
See this page for additional examples.
If you need to send keystrokes to the msi gui; you could look in to the Windows Automation Snapin for PowerShell. I have never used this personally.