I am using version 3.0 and there doesn't seem to be a way to specify a default folder where all your modules are installed. In particular, I am trying to install Posh-Git, but it insists on installing the modules in MyDocuments\WindowsPowershell. How do I change this?
By default, PowerShell looks for modules in one of two locations, both are specified in the
PSModulePath environment variable.
System modules: %windir%\System32\WindowsPowerShell\v1.0\Modules
Current user modules: %UserProfile%\Documents\WindowsPowerShell\Modules
You can add your own module directory to the path:
$env:PSModulePath+=';c:\MyModules'
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 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)
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.)
i have installed all my dependencies for Catalyst in ~/perl5/lib/perl5 using local::lib
I want to run my app under Apache2 using mod_fcgid, but the fastcgi perl script cannot find the modules in my custom path. How can I specify that (apache config?) my custom lib dir is to be included in the INC directory without explicitly hacking it into myapp_fastcgi.pl? I want to be able to move my app between servers that have the perl includes installed in different directories.
Thanks,
Rob
You can set the environment variables with DefaultInitEnv. You probably want something like this, but with your regular includes too,
DefaultInitEnv PERL5LIB /home/rob/perl5/lib/perl5
You can also do things like setting your app config like that too,
DefaultInitEnv APPNAME_CONFIG /srv/app/appname.conf
I'm an absolute beginner at Perl, and am trying to use some non-core modules on my shared Linux web host. I have no command line access, only FTP.
Host admins will consider installing modules on request, but the ones I want to use are updated frequently (DateTime::TimeZone for example), and I'd prefer to have control over exactly which version I'm using.
By experimentation, I've found some modules can be installed by copying files from the module's lib directory to a directory on the host, and using
use lib "local_path";
in my script, i.e. no compiling is required to install (DateTime and DateTime::TimeZone again).
How can I tell whether this is the case for a particular module? I realise I'll have to resolve dependencies myself.
Additionally: if I wanted to be able to install any module, including those which require compiling, what would I be looking for in terms of hosting?
I'm guessing at the moment I share a VM with several others and the minimum provision I'd need would be a dedicated VM with shell access?
See perldoc perlxs.
You can probably inspect the module's source for DynaLoader or something like this. This way you can find out if a module uses any C code.
If you use a unix-like OS, you can use a package manager to see what files/libraries a package (perl module) installs.
You can use
use lib "your_local_path" ,
In this case , you can have module in your local path.