Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds helpers/functions/Install-PSModulePath.ps1 #327

Closed
wants to merge 1 commit into from

Conversation

ctaggart
Copy link

This fixes chocolatey-archive/chocolatey#292. I simply copied Install-ChocolateyPath.ps1 and made minimal changes. I'm using it like this from chocolateyInstall.ps1:

$tools = "$env:chocolateyPackageFolder\tools"
. "$tools\Install-PSModulePath.ps1"
Install-PSModulePath -pathToInstall $tools -pathType ([System.EnvironmentVariableTarget]::Machine)

I would think Machine would be a better default, but I left it as User. It would be great to have an Uninstall-PSModulePath.ps1 too.

@@ -0,0 +1,56 @@
# Copyright 2011 - Present RealDimensions Software, LLC & original authors/contributors from https://github.com/chocolatey/chocolatey
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be a little different since it originates here. The & original... should be removed.

@ferventcoder
Copy link
Member

On the actual commit message itself, please create an issue here in chocolatey/choco, link it back to that issue and then format your commit message according to CONTRIBUTING.md. Once you've done that please force push your branch to update the PR. Thanks!

@ferventcoder
Copy link
Member

From chocolatey-archive/chocolatey#292 (comment) :

One nuance I ran across while retrieving the PATH variable with [System]::GetEnvironmentVariable (specifying the machine scope) is that it still returned the user + machine scope, so I had to also handle if the user-scoped path was there or not. (I found this out the hard way and ended up breaking the Chocolatey prefetch in the puppet module because I did not properly remove the path from $PSModulePath).

@JimFicarra how did you end up handling the split of user from machine scope?

@JimFicarra
Copy link

Hey Rob,

Are you having this issue? I remember writing this and having the issue, but I don't remember the conditions that triggered it. I looked back at the code I wrote and I don't see me handling it other than using the Machine scope (EnvironmentVariableTarget Enumeration) so perhaps I was not using the proper parameter for targeting the machine scope at the time I wrote it.. :)

In any case, below are snippets of code I wrote back then in the ChocolateyInstall.ps1 to handle the addition of the variable to machine scope. Hope they are helpful.

$installDir = "C:\Program Files\Common Files\MyCompany\PowerShellModules"
$modPath = "C:\Program Files\Common Files\MyCompany\PowerShellModules"
$psModulePath = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")

#Add the path to the machine scoped PSModulePath environment variable only if not there
if (-not ($psModulePath -match [regex]::Escape($modPath)))
    {
        Write-Host "Adding $installDir to PSModulePath"
        Write-Debug "Adding $installDir to PSModulePath"
        $psModulePath += ";" + $installDir
        [Environment]::SetEnvironmentVariable("PSModulePath",$psModulePath, "Machine")
    }
else
    {
        Write-Host "Machine Environment Variable PSModulePath already contains $installDir.  Variable not updated"
        Write-Debug "Machine Environment Variable PSModulePath already contains $installDir.  Variable not updated"
    }

And here's a function I wrote in the chocolateyuninstall.ps1 that removes the desired path from the PSModulePath env variable. It handles the cases where the path is either at the beginning, end, or middle of the entire semicolon-delimited path string.

In my implementation, this function is called in my uninstall ONLY IF the module path I'm removing from the PSModulePath env variable doesn't contain any other modules after removing the specific modules within this uninstall. (I have other company-specific modules that I write and put in this path, hence the check before removing from the PSModulePath - I don't want to break usage for other modules I put in my common path)

#See if the installDir is empty, if so remove from PSModulePath
        if ((Get-ChildItem $installDir) -eq $NULL)
        {
            RemoveFrom-PSModulePath $installDir
        }
        else
        {
            Write-Host "$installDir is not empty - not removing path from from PSModulePath as it may break other modules installed in this path"
            Write-Debug "$installDir is not empty - not removing path from from PSModulePath as it may break other modules installed in this path"
        }

Below is the function called.

Function RemoveFrom-PSModulePath
{

Param(
    [Parameter(Mandatory=$True)]
    [string]$modPath

)
    ####################################################
    ##Remove path from System Env Variable PSModulePath#
    ####################################################

    #We remove only if the path is in the env variable AND there are no more folders in the installation directory  
    $psModulePath = [Environment]::GetEnvironmentVariable("PSModulePath", "Machine")

    #Remove the path to the machine scoped PSModulePath environment veriable only if not there
    if (($psModulePath -match [regex]::Escape($modPath)))
    {
        Write-Host "Removing $installDir from PSModulePath"
        Write-Debug "Removing $installDir from PSModulePath"
        # If it's at the end of the path we remove the preceeding ';' as well.
        if ($psModulePath.Split(';')[-1] -match [regex]::Escape($modPath))
        {
            $psModulePath = $psModulePath -replace [regex]::Escape(";$modPath"), $NULL
            [Environment]::SetEnvironmentVariable("PSModulePath",$psModulePath, "Machine")
        }
        # Else if it's at the front we remove the trailing ';'
        elseif ($psModulePath.Split(';')[0] -match [regex]::Escape($modPath))
        {
            $psModulePath = $psModulePath -replace [regex]::Escape("$modPath;"), $NULL
            [Environment]::SetEnvironmentVariable("PSModulePath",$psModulePath, "Machine")
        }
        #Else if it's in the middle we replace with a ';'
        elseif ($psModulePath.Split(';') -match [regex]::Escape($modPath))
        {
            $psModulePath = $psModulePath -replace [regex]::Escape(";$modPath;"), ";"
            [Environment]::SetEnvironmentVariable("PSModulePath",$psModulePath, "Machine")
        }       

    }
    else
    {
        Write-Host "System Environment Variable PSModulePath does not contain $installDir.  Variable not updated"
        Write-Debug "System Environment Variable PSModulePath does not contain $installDir.  Variable not updated"
    }
}

@ctaggart
Copy link
Author

@JimFicarra It looks like you've done much more work here. Would you like to replace this PR with a better one?

@JimFicarra
Copy link

@ctaggart - I'd be happy to contribute! Let me clean up the code a bit and I'll submit a PR.

@eavonius
Copy link

eavonius commented Nov 6, 2015

Any update on this? I've been trying to set PSMODULEPATH in two modules where one is dependent on the other. If they both get installed in the same choco session, the second one (dependent on the other) fails since Update-SessionEnvironment, and setting $env and [Environment]::SetEnvironmentVariable don't work across the installs. No, I can't combine the modules - on some machines users will install one, on some both.

@ferventcoder
Copy link
Member

@eavonius last I knew I believe @JimFicarra was going to fix up his code and submit a superseding PR for this feature.

@eavonius
Copy link

eavonius commented Nov 6, 2015

Thanks rob. @JimFicarra any update? That was 5 months ago ;). Hopefully this is still working code, I could sure use it! :)

@ferventcoder
Copy link
Member

Any update on this? I've been trying to set PSMODULEPATH in two modules where one is dependent on the other. If they both get installed in the same choco session, the second one (dependent on the other) fails since Update-SessionEnvironment, and setting $env and [Environment]::SetEnvironmentVariable don't work across the installs. No, I can't combine the modules - on some machines users will install one, on some both.

This has been fixed in 0.9.10.

@ferventcoder
Copy link
Member

@JimFicarra any updates on submitting those fixes?

@jberezanski
Copy link

Any update on this? I've been trying to set PSMODULEPATH in two modules where one is dependent on the other. If they both get installed in the same choco session, the second one (dependent on the other) fails since Update-SessionEnvironment, and setting $env and [Environment]::SetEnvironmentVariable don't work across the installs. No, I can't combine the modules - on some machines users will install one, on some both.

Cross-referencing chocolatey-archive/chocolatey#475.

This has been fixed in 0.9.10.

Glad to hear!

@eavonius
Copy link

eavonius commented May 30, 2016

Revisiting this - how has this been fixed in 0.9.10? I just tried on Windows 10 using 0.9.9.12 (current version) installing my two powershell modules that have chocolatey packages again. It appears that when the dependent package installs, the next package does now see the change to PSMODULEPATH which is good, however the calling process doesn't see the new modules.

Here's the chocolateyInstall from PowerDelivery3Node (PowerDelivery3 package depends on it). When I install PowerDelivery3 locally off the built nuget package, it does find the dependency to PowerDelivery3Node, installs it first, and there are no errors - but at the end of both packages being installed the current PowerShell session doesn't have the new cmdlets available.

https://github.com/eavonius/powerdelivery/blob/master/Scripts/Chocolatey/PowerDeliveryNode/ChocolateyInstall.ps1

Should I just show a message that the person has to reload their shell to use it? I'm using this as part of infrastructure automation and if I call chocolatey on a remote node to install PowerDeliveryNode, I want the calling script to be able to access its cmdlets immediately after installation.

@ferventcoder
Copy link
Member

Revisiting this - how has this been fixed in 0.9.10? I just tried on Windows 10 using 0.9.9.12 (current version) installing my two powershell modules that have chocolatey packages again. It appears that when the dependent package installs, the next package does now see the change to PSMODULEPATH which is good, however the calling process doesn't see the new modules.

0.9.10.0 versus 0.9.9.12. 0.9.10 is still in beta. I'm not sure if you made that determination or not.

@ferventcoder
Copy link
Member

ferventcoder commented May 30, 2016

@eavonius in 0.9.10 a user can refresh their shell with refreshenv, which calls Update-SessionEnvironment.

refresh env

@ferventcoder
Copy link
Member

Note a couple of really important things there - Chocolatey tells the user that they need to refresh their environment when it detects changes to the environment values.

@ferventcoder
Copy link
Member

You can call refreshenv after the installation (or use Update-SessionEnvironment) outside of Chocolatey scripts - if the installation is able to put it on the profile. I'm not completely sure how it works with SYSTEM, I'd love some testing on that if you are able to.

@ferventcoder
Copy link
Member

#295

@eavonius
Copy link

Sorry Rob I didn't notice I was reading the version wrong. Is there a way
to install this version without getting source?

I'll do some testing, really want to get these packages up there!

Thanks for your support,

Jayme

On Mon, May 30, 2016 at 11:08 AM, Rob Reynolds notifications@github.com
wrote:

#295 #295


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAWspTXQTKMzjWGu23tZcT--C0kHWv0qks5qGwt0gaJpZM4FCQ8g
.

@ferventcoder
Copy link
Member

choco upgrade chocolatey --pre

On Tuesday, May 31, 2016, Jayme Edwards notifications@github.com wrote:

Sorry Rob I didn't notice I was reading the version wrong. Is there a way
to install this version without getting source?

I'll do some testing, really want to get these packages up there!

Thanks for your support,

Jayme

On Mon, May 30, 2016 at 11:08 AM, Rob Reynolds <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:

#295 #295


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment),
or mute
the thread
<
https://github.com/notifications/unsubscribe/AAWspTXQTKMzjWGu23tZcT--C0kHWv0qks5qGwt0gaJpZM4FCQ8g

.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#327 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAD4Dss1PwGcN-aWjMfeBP4YR56m96H5ks5qHMVwgaJpZM4FCQ8g
.

Rob
"Be passionate in all you do"

http://codebetter.com/robreynolds
http://ferventcoder.com
https://twitter.com/ferventcoder

@eavonius
Copy link

eavonius commented Jun 1, 2016

Darn it. OK thanks Rob, I tried it with the pre package and the packages
install without errors (so the dependent one sees the dependency in its own
process space) but when I do a refreshenv afterwards, the updated system
environment variable for PSMODULEPATH is missing the new paths. I checked
the system environment variables dialog and they are added, but they don't
show up until I close and re-open the terminal :(

On Tue, May 31, 2016 at 7:06 PM, Rob Reynolds notifications@github.com
wrote:

choco upgrade chocolatey --pre

On Tuesday, May 31, 2016, Jayme Edwards notifications@github.com wrote:

Sorry Rob I didn't notice I was reading the version wrong. Is there a way
to install this version without getting source?

I'll do some testing, really want to get these packages up there!

Thanks for your support,

Jayme

On Mon, May 30, 2016 at 11:08 AM, Rob Reynolds <notifications@github.com
javascript:_e(%7B%7D,'cvml','notifications@github.com');>
wrote:

#295 #295


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment),
or mute
the thread
<

https://github.com/notifications/unsubscribe/AAWspTXQTKMzjWGu23tZcT--C0kHWv0qks5qGwt0gaJpZM4FCQ8g

.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#327 (comment),
or mute
the thread
<
https://github.com/notifications/unsubscribe/AAD4Dss1PwGcN-aWjMfeBP4YR56m96H5ks5qHMVwgaJpZM4FCQ8g

.

Rob
"Be passionate in all you do"

http://codebetter.com/robreynolds
http://ferventcoder.com
https://twitter.com/ferventcoder


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAWspanXEbobPkzv6AY_bGRZ9QY0_QGXks5qHM0agaJpZM4FCQ8g
.

@ferventcoder
Copy link
Member

@eavonius help me understand this a bit more - we don't actually update PSMODULEPATH at all. We hold the original variable and give it back - due to #295. Are you saying you would prefer we update it?

@eavonius
Copy link

eavonius commented Jun 1, 2016

Sorry for the lack of clarity. The chocolatey packages for my two
PowerShell modules append their chocolatey "tools" subdirectories to the
PSMODULEPATH system environment variable during chocolateyInstall.ps1. When
they are done installing, I would like a way for PSMODULEPATH to include
the new paths I've added so any further commands in a scripts that calls
chocolatey as just one part of an overall deployment process have access to
the new cmdlets.

Hopefully that helps.

On Wed, Jun 1, 2016 at 4:40 PM, Rob Reynolds notifications@github.com
wrote:

@eavonius https://github.com/eavonius help me understand this a bit
more - we don't actually update PSMODULEPATH at all. We hold the original
variable and give it back - due to #295
#295. Are you saying you
would prefer we update it?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAWspT_IS4UZnj_q1ta-IA_2Q9yU_rV_ks5qHfw7gaJpZM4FCQ8g
.

@ferventcoder
Copy link
Member

That makes sense, and conflicts with #295 as I understand it. So we will need to figure out a way to make #129 work as well. Perhaps we should continue the discussion there?

@eavonius
Copy link

eavonius commented Jun 1, 2016

That makes sense. I just gave a cursory look at #295.

On Wed, Jun 1, 2016 at 4:45 PM, Rob Reynolds notifications@github.com
wrote:

That makes sense, and conflicts with #295
#295 as I understand it. So
we will need to figure out a way to make #129
#129 work as well. Perhaps we
should continue the discussion there?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAWspWqTyZXjB5X3XsBnCdu-uFuLbFeAks5qHf1sgaJpZM4FCQ8g
.

@dragon788
Copy link
Contributor

I think with some other discussion in various places it was suggested this could really just be a specific call to Install-ChocolateyEnvironmentVariable with maybe some logic checks for existing within the environment already, or and is very similar to Install-ChocolateyPath. I'm not sure if just making it an alias or a special case inside the Install-ChocolateyEnvironmentVariable would make sense, detecting when --case-insensitive "PATH"/"PSModulePath" is the target and doing some extra checks like ensuring the ExpandSZ or whatever properties are intact.

@ferventcoder
Copy link
Member

@ctaggart reviving an old thread. I would love to get something in regarding PS ModulePath. Still interested in moving forward with this?

@ctaggart
Copy link
Author

@ferventcoder I think it is still a good idea, but I will be unable to contribute.

@glachancecmaisonneuve
Copy link

Seems like this commit was abandoned. I'm waiting for changes to this commit to go through or be abandoned before sending my own PR.

@CLAassistant
Copy link

CLAassistant commented Jun 8, 2020

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Cameron Taggart seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions bot added the Pending Closure This issue has been marked as having no response or is stale and will soon be closed. label Jun 11, 2023
@pauby pauby closed this Jun 25, 2023
@pauby pauby reopened this Jun 25, 2023
@github-actions
Copy link

Dear contributor,

As this PR seems to have been inactive for 30 days after changes / additional information
was requested, it has been automatically closed.
If you feel the changes are still valid, please re-open the PR once all changes or additional information
that was requested has been added.
Thank you for your contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0 - Waiting on User No Response / Stale Pending Closure This issue has been marked as having no response or is stale and will soon be closed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Enhancement] Install-PowershellModulePath to modify PSModulePath
9 participants