Skip to content

[Feature Request]: Ability to configure PSRepository on a system-wide level #84

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

Open
Glober777 opened this issue Dec 26, 2017 · 30 comments
Assignees

Comments

@Glober777
Copy link

It would be great if there was a way to register a PSRepository on the system-wide level, so that if configured once, it would work for all the users on a particular system.

Expected Behavior

Register-PSRepository should have a -Scope parameter added, to control whether a particular PSRepository needs to be registered for just the current user of for the whole system (similar to the behavior of Execution Policy). It would also be great to have an extra scope option, that would register PSRepository just for the current session (like mentioned in PowerShell/PowerShellGet#65)

Apart from the Register-PSRepository, the remaining set of the *-PSRepository cmdlets should also have the -Scope parameter. Set-PSRepository and Unregister-PSRepository cmdlets should require admin privileges to work against system-wide PSRepository settings and 'Get-PSRepository' cmdlet should not require admin privileges at all.

Current Behavior

Currently Register-PSRepository only works for the user that is executing the cmdlet.

Context

Having an ability to register PSRepository on a system-wide level would allow us to pre-configure our internal Repositories in the Virtual Machine templates, thus making the provisioning process much simpler.

Additionally, that would simplify maintaining existing PSRepository configurations in a consistent fashion across all our systems.

Your Environment

PS C:\Users> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.15063.726
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.15063.726
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS C:\Users>
PS C:\Users> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     1.2        PSReadline                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PS...


PS C:\Users>
PS C:\Users> Get-Module -ListAvailable PowerShellGet,PackageManagement


    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.1.7.0    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Script     1.1.1.0    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Binary     1.0.0.1    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Script     1.6.0      PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}
Script     1.1.2.0    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}
Script     1.0.0.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}


    Directory: C:\Program Files (x86)\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     1.0.0.1    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Script     1.0.0.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}


PS C:\Users>
PS C:\Users> Get-PackageProvider

Name                     Version          DynamicOptions
----                     -------          --------------
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
NuGet                    2.8.5.210        Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag...
PowerShellGet            1.6.0.0          PackageManagementProvider, Type, Scope, AllowClobber, SkipPublisherCheck, ...
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent


PS C:\Users> Get-PackageProvider -ListAvailable

Name                     Version          DynamicOptions
----                     -------          --------------
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
nuget                    2.8.5.208
NuGet                    2.8.5.210        Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag...
NuGetProvider            2.8.5.208
PowerShellGet            1.6.0.0          PackageManagementProvider, Type, Scope, AllowClobber, SkipPublisherCheck, ...
PowerShellGet            1.1.2.0
PowerShellGet            1.0.0.1
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent
@KevinMarquette
Copy link

I also support this request.

If an admin runs Install-Module -Scope AllUsers on a system, a different admin has to first register this repository in order to call Update-Module. Every time I touch a system and want to install or update a module, I first have to check to see if the repository is registered. Even if we fully automate the onboarding of that system, I still have to register a repository by hand.

What I do now is just include the repository registration logic in any and all scripts that install modules.

@sam-bryant
Copy link

+1 for this enhancement.

@bradleywehmeier
Copy link

Windows PowerShell team, any guidance on where the "AllUsers" repositories configuration file would live?
I see 2 options:

  1. $script:ProgramFilesPSPath as this is where the AllUsers Modules are installed
  2. $script:PSGetProgramDataPath seems like the place for this configuration but might not work for "AllUsers" on Linux/OSX

@bmanikm
Copy link

bmanikm commented Jun 6, 2018

@bradleywehmeie, thanks for looking into this feature request.
Yes, $script:PSGetProgramDataPath is the right place for this configuration file.

For non-Windows platforms, please update the $script:PSGetProgramDataPath to '/usr/local/share/powershellget'.

Current:

    $script:PSGetProgramDataPath = Microsoft.PowerShell.Management\Join-Path -Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory('CONFIG')) -ChildPath 'PowerShellGet'

Expected:

    $script:PSGetProgramDataPath = '/usr/local/share/powershellget'

@bradleywehmeier
Copy link

Main Question

How do we expect Unregister-PSRepository to function when the Scope parameter is omitted? Should it be allowed to modify the AllUsers scope if the Scope is omitted OR should the Scope be required anytime the AllUsers scope is being modified?

Example:

Register-PSRepository -Name Test -Scope AllUsers ...

# Should this be allowed?
Unregister-PSRepository -Name Test

# Or should we require the Scope?
Unregister-PSRepository -Name Test -Scope AllUsers

Additional Context

With either implementation, the Set/Unregister-PSRepository cmdlets work as you would expect but I ran into a limitation with the Unregister-PackageSource cmdlet and pipelining. The value for Scope is not pipelined to the Unregister-PackageSource cmdlet so there are occasions where it will produce the incorrect result when attempting to work on the AllUsers scope.

For example:

Register-PSRepository -Name Test -Scope AllUsers ...

Get-PackageSource -Name Test -Scope AllUsers | Unregister-PackageSource

If we are strict about requiring the AllUsers to be specified, this will result in a Not Found error because no scope will end up being passed to Remove-PackageSource so it will assume "CurrentUser" scope.
If we aren't strict, then Remove-PackageSource won't assume a scope and will find the Test PackageSource and remove it.

In both implementations if the PackageSource exists in both the CurrentUser and AllUsers (a case which is possible), Get-PackageSource -Name Test -Scope AllUsers | Unregister-PackageSource will remove the wrong PackageSource. It will find Test in the CurrentUsers scope and remove it from there instead of the AllUsers scope which was pipelined. For this reason maybe this additional context is a moot point and we should simply state that using *-PackageSource for AllUsers scope is not recommended/supported.

@bmanikm
Copy link

bmanikm commented Jun 13, 2018

@bradleywehmeier
If a user is trying to unregister an AllUsers scoped repository, it is required to ensure that user has the admin privileges similar to the Uninstall and Update cmdlets.

As part of this enhancement, are you allowing the duplicate PSRepository names? I think we should allow this as the users and admin may give the same name for the psrepositories. if not, can we follow the same design as the Uninstall and Update cmdlets where -Scope parameter is not required on Unregister-PSRepository.

If we are allowing the duplicate psrepository names

  • Add Scope optional parameter on Unregister-PSRepository cmdlet
  • Admin privileges check is also required for the AllUsers scoped psrepositories
  • Scope parameter is optional for the AllUsers scoped psrepositories
  • If Scope parameter is not specified, Unregister-PSRepository cmdlet first checks if the given name is registered for the currentuser scope and unregisters it.

Above is also applicable to the Set-PSRepository cmdlet.

We need to add -Scope optional parameter in PowerShellGet provider dynamic options for the sources at
https://github.com/PowerShell/PowerShellGet/blob/development/PowerShellGet/public/providerfunctions/Get-DynamicOptions.ps1#L31 similar to https://github.com/PowerShell/PowerShellGet/blob/development/PowerShellGet/public/providerfunctions/Get-DynamicOptions.ps1#L44
For more details, please take a look at the ScriptSourceLocation dynamic option implementation in PowerShellGet provider functions.

For the pipeline operations with scope, it is required to specify -Provider PowerShellGet like below

Get-PackageSource -Name Test -Provider PowerShellGet -Scope AllUsers | Unregister-PackageSource

@bradleywehmeier
Copy link

@bmanikm
Yes admin is required for modifications to AllUsers Scope.
Dynamic Parameters have been taken care of.

Duplicate Repository names have to be supported because there is no way to avoid a situation where an admin defines an AllUsers repo that overlaps with a setting that a user has already set. In this case the user will get the instance they defined (CurrentUser scope) not the AllUsers scope.

“Scope parameter is optional for the AllUsers scoped psrepositories” answers my real question here.

With the rest having been taken care of look for a pull request in the next couple of days after I look it over one last time.

@bmanikm
Copy link

bmanikm commented Jun 14, 2018

Also please consider validating the install and update scenarios with the duplicate psrepository names as the source locations can be different.

@bradleywehmeier
Copy link

Regarding the case of duplicate PSRepository names with different source locations:

  • For Install, the repository that will be used is the CurrentUser scoped PSRepository. This is the same PSRepository that is shown in Get-PSRepository in this case so it is consistent.
  • For Update, I'm assuming the desired behavior is to use the same source location that was originally used to install. Is that assumption correct?

The name overlap does cause problems for Update. It wants to use the PSRepository source location defined in CurrentUser regardless of what source location was used for the install.

@bradleywehmeier
Copy link

The more I think about it, I'm not sure if my assumption was correct.

  • On one hand, downloading updates from the same location you downloaded makes perfect sense.
  • On the other hand, the primary mechanism that is used to reference a particular PSRepository is the Name and we allow situations where the source location is allowed to change and PowerShellGet continues to function with the new location.

When there are duplicate PSRepository names and one is chosen to be the "winner", I can also make an argument to treat that scenario in the same way we treat the PSRepository source location having been changed and using the source location from the "winner".

There are other rough edges with PowerShellGet like the current behavior of using a "CurrentUser" PSRepository to install "AllUsers" modules. If those are not causing issues, then maybe this confusion will also be negligible.

One alternative would be to Prefix the AllUsers scoped PSRepositories so that name collisions were not possible. I originally avoided that so that PackageManagement cmdlets (e.g. Register-PackageSource) and PowerShellGet cmdlets (e.g. Register-PSRepository) would have the same/similar parameters. If that's not something that matters since most people will be using the PowerShellGet cmdlets, I can spend some time implementing that approach to see if it has fewer issues.

Thanks all for your input on this. I appreciate the effort in helping me get this right.

@bmanikm
Copy link

bmanikm commented Jul 25, 2018

@bradleywehmeier thanks for looking into this feature!

Some thoughts

  • By default, Get-PSRepository cmdlet should list all the registered repositories in both scopes (CurrentUser and AllUsers). We need to add the Scope property/column in the Get-PSRepository output format.
  • Duplicate repository names should not be allowed in a single scope.
  • In case of duplicate repository names, CurrentUser scope gets precedence over AllUsers scope.
  • During the Install operation, we also need to add a property called RepositoryScope in the PSRepositoryItemInfo in PSGetModuleInfo.xml/[ScriptName]_InstalledScriptInfo.xml file so that update operation picks the correct repository name and scope. This follows the current update functionality.

@maxwell-clarke-intranel
Copy link

maxwell-clarke-intranel commented Sep 14, 2018

I also support this. I had a very confusing few hours the other day, trying to configure a proxy PowerShellGet package source through DSC. Since DSC runs as the system user, I couldn't see the repositories it was registering. I am now trying to figure out how to configure the proxy repository for all users. (Does anyone have any good solutions to that?)

@tmmruk
Copy link

tmmruk commented Oct 21, 2018

Agreed this is much needed feature. I'm trying to use the PackageManagement DSC resource to configure our internal/proxy nexus repository as part of an OS deployment but is only applied under the NT Autority\System account. The modules install fine from the internal repo as part of the DSC config, however normal users still see the default PSGallery repo meaning they cannot pull approved and custom internal modules when required.

@hematic
Copy link

hematic commented Nov 21, 2018

I just want to chime in that this causes problems using Jenkins automation as well. Jenkins agents sometimes run under system or certain service account logins and i have no good way to configure the psrepository for them.

@mrhockeymonkey
Copy link

+1 for this feature. We've want to move to using PowerShellGet exclusively for module distribution but we get constant requests for assistance with setting up the right repos which is slowing down adoption. This feature would solve that.

@jzabroski
Copy link

@SteveL-MSFT As a quick observation, this is actually a OneGet issue and not a PowerShellGet issue.

I created the following issue in OneGet to ALIGN the two projects. OneGet/oneget#468

As Program Manager for PowerShell Core, you can facilitate, advocate for, and resource a solution to this problem!

@VerdonTrigance
Copy link

I can not use Register-PackageSource (or psrepository) by my service build account that has no local logon permissions. So how do I need to use all this package management mess? Should I use another solutions?

@alerickson alerickson transferred this issue from PowerShell/PowerShellGetv2 Mar 30, 2020
@ThomasNieto
Copy link
Contributor

ThomasNieto commented Aug 20, 2020

@SydneyhSmith any chance this can be added to 3.0? This is a huge missing feature in a multi-user environment.

@SteveL-MSFT SteveL-MSFT added this to the vNext milestone Sep 4, 2020
@SteveL-MSFT SteveL-MSFT removed the vNext label Sep 4, 2020
@sam-bryant
Copy link

Any updates on this? Our job scheduling tools uses temporary user profiles so full automation of things that utilize that tool is not possible unless I use @KevinMarquette's solution, which I'd like to avoid.

@jpatigny
Copy link

jpatigny commented Apr 29, 2021

Hello,

Is there any update on this topic ? This is a a much needed feature for me as my configuration manager runs as system, I cannot register PSRepositories / install modules

@awickham10
Copy link

Also plus 1. Definitely needed for enterprises trying to run private repositories.

@alerickson
Copy link
Member

Thanks all! We'll definitely prioritize this scenario since it's been a popular request

@CasperStekelenburg
Copy link

+1 for this feature!

@Leenton
Copy link

Leenton commented Mar 26, 2022

+1 for this feature!

Make that + 2!

@SydneyhSmith
Copy link
Collaborator

Tracking this feature work in https://github.com/PowerShell/PowerShellGet/issues/616

@SydneyhSmith SydneyhSmith removed this from the 3.0-Resolved milestone May 3, 2022
@rvigliotti-sf
Copy link

+1!

@robinmalik
Copy link

robinmalik commented Dec 9, 2022

+1, looking forward to being able to set this and remove a fair bit of workaround code :)

@XtratusCloud
Copy link

+1

@jakauppila
Copy link

Would love to see this in an upcoming release as we would like to push out a default configuration to all of our workstations/servers to point at our PowerShell repositories in Artifactory. I see it was included in 3.0 then pulled out?

@TobiasSonndag
Copy link

Faced this issue today as well, so seems still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests