I'm working on automating an AppFabric installation using PowerShell, and I've run into a problem where the script is calling the installer, waiting for it to complete, but I am unable to import the installed modules after from the same context. i.e:
Start-Process "C:\provision\WindowsServerAppFabricSetup_x64.exe" -ArgumentList "/i /GAC" -Wait
Import-Module DistributedCacheConfiguration
# ...do configuration things...
Which errors: The specified module 'DistributedCacheConfiguration' was not loaded because no valid module file was found in any module directory.
If you close and re-open PowerShell, the script runs fine. Adding a Start-Sleep 60
between the installer and the configuration didn't help, so I tried calling it as though powershell were restarting:
C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe C:\provision\appfabric_config.ps1
The same errors were thrown. How do I get PowerShell to recognize the newly installed modules?
Installing PowerShell modules from the PowerShell Gallery is the easiest way to install modules. To install a package or module from the Gallery, we use the command: Install-Module or Install-Script cmdlet, depending on the package type.
Starting in PowerShell 3.0, installed modules are automatically imported to the session when you use any commands or providers in the module. However, you can still use the Import-Module command to import a module. You can disable automatic module importing using the $PSModuleAutoloadingPreference preference variable.
To import PowerShell modules permanently you can copy them creating a folder on C:\Windows\system32\WindowsPowerShell\v1. 0\Modules\ with the name of your script, then inside you can put all your psm1 or ps1 files.
If you want the module to be accessed only by a particular user, this must be copied into “C:\Users\THEUSERNAME\Documents\WindowsPowerShell\Modules”. Because all the necessary files are already located in the “Modules” folder, PowerShell will install it from there, not requiring an internet connection.
PowerShell looks for modules in subdirectories of the directories listed in the PSModulePath environment variable. Environment variables are read from the registry key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment when the session is initialized.
If the installer places the new module in a directory that's not already in PSModulePath and then adds that directory to the environment variable, it's modifying the environment variable in the registry, not in the current PowerShell console session's environment, so only PowerShell sessions started after the installation will have the updated PSModulePath.
You can manually update the value from the registry by adding the following line after the installation and before attempting to import the module:
$env:PSModulePath = (Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Name PSModulePath).PSModulePath
Note that although it may appear redundant, the reason you need
(Get-ItemProperty -Path [...] -Name PSModulePath).PSModulePath
rather than just
Get-ItemProperty -Path [...] -Name PSModulePath
is that Get-ItemProperty doesn't return the data of the named registry value, it returns a PSCustomObject that contains information about the registry value, and the data is in a property of that PSCustomObject that has the name of the registry value (i.e. PSModulePath in this case). If you prefer, you could also do it this way:
$env:PSModulePath = Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Name PSModulePath | select -ExpandProperty PSModulePath
(There's no practical difference, it's six or a half dozen.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With