You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Install-PSResource installs Script module to lowercase directory #1446
Install a PSM1/PSD1 module with a mixed-case name (e.g., MyModule) using Install-PSResource.
Expected behavior
The module should install to C:\...\Modules\MyModule\ and be find-able as a PowerShell module.
Actual behavior
When I install a module with a mixed-case name (e.g., MyModule) using Install-Module, it installs perfectly. When I use Install-PSResource, it installs successfully, but installs it in C:\...\Modules\mymodule\ (i.e. lowercase) instead of C:\...\Modules\MyModule\. This doesn't cause any problem for PS under Windows, but on case-sensitive *nix platforms, the module can't be found and, therefore, can't be loaded (without manually renaming the install directory).
Error details
No response
Environment data
Name : Microsoft.PowerShell.PSResourceGet
Path : C:\Users\rick\Documents\PowerShell\Modules\Microsoft.PowerShell.PSResourceGet\1.0.0\Microsoft.PowerShell.PSResourceGet.dll
Description : PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, Scripts, and DSC Resources.
ModuleType : Binary
Version : 1.0.0
PreRelease :
NestedModules : {Microsoft.PowerShell.PSResourceGet}
ExportedFunctions : Import-PSGetRepository
ExportedCmdlets : {Find-PSResource,Get-InstalledPSResource,Get-PSResourceRepository,Get-PSScriptFileInfo…}
ExportedVariables :
ExportedAliases : {fdres,Get-PSResource, isres, pbres…}
Name Value
---------
PSVersion 7.3.8
PSEdition Core
GitCommitId 7.3.8
OS Microsoft Windows 10.0.22621
Platform Win32NT
PSCompatibleVersions {1.0,2.0,3.0,4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
This is an issue referenced, but not documented as a known issue. Everyone discovers it.
There is an implicit rule which is not controlled and remains the responsibility of the user. Just like the file names specified in a module manifest.
The case of the package name can influence the installation, see the platyPS module for example.
Thanks, Laurent Dardenne (@LaurentDardenne), although I'm not sure this is part of that overall issue; I'm not convinced it's that straightforward. When I install my module to PSGallery, with the mixed-case names, everything works fine. The module is installed into a mixed-case directory and all is well. But when I publish to the GitHub Packages, which (apparently) requires that I use the newly-released PowerShellGet v3 (PSResourceGet), it installs into a lowercase directory and the problem arises. PSResourceGet (more specifically, Install-PSResource) also works on PSGallery, so I'm starting to suspect the problem is with GitHub's environment.
I've been assuming GitHub is using standard hosting software, but I don't know if that's the case. Maybe I need to flag this as a bug for GitHub? Any ideas?
But when I publish to the GitHub Packages, which (apparently) requires that I use the newly-released PowerShellGet v3
(PSResourceGet), it installs into a lowercase directory and the problem arises.
In my case, the module and package have the same name (i.e., "MyModule"), but the module is installed in the lowercase directory ("mymodule") when installed from GitHub Packages. If the directory and PSD1 file were named differently, I'd understand the issue, but they are the same.
I wish I could have you install it to see if you see the same behavior and/or see if I made a mistake, but I'm not allowed to expose it yet. I am trying to find a way to download the nupkg file directly so I can see if it was generated correctly by Publish-PSResource (via the following command).
Thanks for opening this issue Rick Andersen (@rickandersen-forte) PowerShell is, by default, case-insensitive even on non-Windows platform, to confirm are you running into an issue with your use case because of this or are you worried that you might in the future?
Thanks, Sydney Smith (@SydneyhSmith). I am already running into this case, but it's not a significant issue (yet?) because we are in development and I don't think it's being used by anyone in an affected environment (e.g., Debian or Ubuntu). I'm hoping to get it fixed before it does, but since this is an internal tool, worst case scenario is that I tell users to either rename the directory or create a properly named symbolic link to the lowercase-named directory.
In case it helps (e.g., I hope I'm doing something wrong in publication), below is the GitHub Action that I use to publish. Notice that the Publish using nuget.exe section at the end is disabled; that was a test to see if using nuget worked better, but it had the same problem.
Also relevant, the module directory and PSD1 file are both named AnyChain.
# This is a basic workflow to help you get started with Actions
name: Publish AnyChain PowerShell module
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
#push:
# branches: [ "main" ]
#pull_request:
# branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow packages and publishes the AnyChain module to the GitHub package repository
publish-anychain-package:
# The type of runner that the job will run on
runs-on: windows-latest
# Enable required repo permissions for this workflow
permissions:
contents: read
packages: write
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out this repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
- uses: nuget/setup-nuget@v1
with:
nuget-version: 'latest'
nuget-api-key: ${{ github.token }}
# Import new PSResourceGet v3
- name: Import new PSResourceGet modules
if: ${{ true }}
run: |
# Mark PSGallery as trusted to allow subsequent installations w/o prompts
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -Verbose
# Install secret management modules
Install-Module Microsoft.PowerShell.SecretManagement,Microsoft.PowerShell.SecretStore
# Install PowerShellGet 3.0 (Microsoft.PowerShell.PSResourceGet)
Install-Module -Name Microsoft.PowerShell.PSResourceGet -AllowClobber -Force
# OPTIONAL?: Install PowerShellGet 3.x module (provides backward compatibility for PowerShellGet 2.0 functionality)
Install-Module -Name PowerShellGet -AllowPrerelease -Force
# OPTIONAL?: Register PowerShellGet (v2) repos in the PSResourceGet (v3) resources repos
Import-PSGetRepository
# Runs a set of commands using the runners shell
- name: Publish the PowerShell module to GitHub package repository
if: ${{ true }}
run: |
# Temporary repo name
$repoName = "MyPackages"
# Construct a PSCredential from the GitHub token
$pass = '${{ github.token }}' | ConvertTo-SecureString -AsPlainText -Force
$cred = [PSCredential]::new( '${{ github.actor }}', $pass )
# Register the NuGet repository to which the module will be published
Register-PSResourceRepository -Name $repoName -Priority 10 -Trusted -Uri 'https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json' -CredentialInfo $credInfo -Verbose
# Publish the AnyChain module to the NuGet repository
# We're having a problem in which the nupkg file is lowercase, which causes problems on case-sensitive Unix platforms.
Publish-PSResource -Path "${{ github.workspace }}\AnyChain\AnyChain.psd1" -Repository $repoName -ApiKey ${{ github.token }} -DestinationPath "${{ github.workspace }}" -Verbose
# Publish using nuget.exe
- name: Publish module using nuget.exe
if: ${{ false }}
run: |
$ver = (Import-PowerShellDataFile -Path "${{ github.workspace }}\AnyChain\AnyChain.psd1").ModuleVersion
nuget pack "${{ github.workspace }}\AnyChain.nuspec" -BasePath "${{ github.workspace }}\AnyChain\" -Version $ver
nuget sources add -Name "GitHubRepo" -Source 'https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json' -username "rickandersen-forte" -password "${{ github.token }}"
nuget push "${{ github.workspace }}\AnyChain.$ver.nupkg" -Source GitHubRepo
I was able to download the raw nupkg file from the GitHub Packages and it appears to be virtually identical to that from PSGallery (e.g., different Id and psmdcp Target file in .rels, "NuGet" vs "NuGet.Packaging" in .psmdcp files). Both also specify the nupkg name as lowercase ("anychain.2.5.8.4.nupkg") and mixed-case within the encapsulated files (e.g., AnyChain.nuspec's element).
Yet, when I install from PSGallery using Install-PSResource, it installs to ".../Modules/AnyChain", and when I install from GitHub using Install-PSResource, it installs to ".../Modules/anychain". GitHub uses ApiVersion v3 while PSGallery uses v2. I can't but suspect the problem is in the v3 repository "provider".
By chance, is there a v3 interface to the PSGallery yet that I can test against?
I just noticed that Find-PSResource also returns a lowercase name for the GitHub Packages repo, but a mixed-case for the PSGallery repo. It seems like that might be relevant.
Through experiments, it appears that the case of the nupkg filename and the name of the enclosed nuspec file (though not the <id> within the nuspec file) must match exactly for the resource to be available via Find-PSResource or for Install-PSResource to work correctly.
When installed from the GitHub repo, each part of the URL is converted to lowercase, as per the standard (https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource). This results in the downloaded nupkg filename and local directory name being lowercase, which is then moved into the final destination (keeping the same lowercase name), even though the package itself uses mixed case.
Since the URL must use lowercase (e.g., https://nuget.pkg.github.com/<organization>/anychain/2.5.8.4/anychain.2.5.8.4.nupkg), but the package itself may be mixed-case, as specified in the nuspec file (e.g., <id>AnyChain</id>), it seems that two things must change in the PSResourceGet implementation to allow a workable installation under case-sensitive file systems:
Publish-PSResource must generate a lowercase nuspec filename (e.g., anychain.nuspec) that contains a mixed-case id tag (e.g., <id>AnyChain</id>). Since this file is embedded in the nupkg file, the server can't be expected to convert it to lowercase for us. Right now, the file is created with the same case as the internal package name, which only works if the package name is always lowercase (a very bad restriction).
Install-PSResource must download the package to a directory whose name matches the mixed-case id tag from the <id> tag within the nupkg file, not the lowercase package name; or at least convert it to that name before the installation completes. This allows the installed directory to match the case of the actual module so PowerShell can find the module in a mixed-case-sensitive environment.
Or, I'm completely lost and don't know what I'm talking about. Definitely possible. If so, please let me know.
Reacted by Jakub Tomkiewicz and Victor Andres Morales
I don't think so, it's consistent with the behavior we see.
Since this file is embedded in the nupkg file, the server can't be expected to convert it to lowercase for us.
I don't know if it's related to this problem, but when downloading from the Cloudsmith site the file name 'anychain.2.5.8.4.nupkg' is renamed to 'AnyChain.2.5.8.4.nupkg' ( id=AnyChain ) :
Which is not the case for the package I mentioned previously:
The difference is I created the .nuspec file and the package manually.
For this package the directory name is in lower case:
If my understanding is correct, the behavior you're seeing makes sense. I believe the name of the downloaded nupkg file should be the same as the <id> from the nuspec file, not the value as specified in the URL. I'm not sure if that's necessary, but it is if the client-side installer uses the file name instead of the <id> value for the target directory. I suspect the safest would be to do both in case there are clients that don't follow that rule. (Q: Is Install-PSResource the only relevant client in this context?)
Sydney Smith (@SydneyhSmith): Any thoughts or suggestions? I'm not asking for a commitment, but just wondering if this sounds like we're on the right track? And thinking maybe I should rename my modules to be all lowercase if it looks like this fix (or any fix) isn't possible in the foreseeable future.
Is there any update on when we should expect this issue to be addressed? We got bit by this too. Also - there is another open issue which I believe is the same and perhaps should be merged. Thanks!
I can reproduce this with NuGet GitHub Packages repo package NuGet.Internal.GithubIssueTagger.
https://nuget.pkg.github.com/NuGet/index.json
Debug output
PS >Install-PSResource-Repository 'gh-nuget'-TrustRepository -Scope 'CurrentUser'`-Name 'NuGet.Internal.GithubIssueTagger'-Debug -Verbose
VERBOSE: All paths to search: 'C:\Users\<redacted>\Documents\PowerShell\Modules'
VERBOSE: All paths to search: 'C:\Users\<redacted>\Documents\PowerShell\Scripts'
VERBOSE: Retrieving directories in the path 'C:\Users\<redacted>\Documents\PowerShell\Modules'
VERBOSE: Retrieving directories in the path 'C:\Users\<redacted>\Documents\PowerShell\Scripts'
VERBOSE: All paths to search: 'C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure'
DEBUG: In GetHelper::GetPackagesFromPath()
DEBUG: In GetHelper::FilterPkgPathsByName()
DEBUG: In GetHelper::FilterPkgPathsByVersion()
DEBUG: Searching through package path: 'C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure'
DEBUG: Searching through package path: 'C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure'
DEBUG: Searching through package version path: 'C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure\0.92.1.0'
VERBOSE: The PSGetModuleInfo.xml file found at location: C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure\0.92.1.0\PSGetModuleInfo.xml cannot be parsed due to TryReadPSGetInfo: Cannot read the PSResourceGet information file with error: Could not find file 'C:\Users\<redacted>\Documents\PowerShell\Modules\Microsoft.PowerToys.Configure\0.92.1.0\PSGetModuleInfo.xml'.
DEBUG: In InstallPSResource::ProcessInstallHelper()
DEBUG: In InstallHelper::BeginInstallPackages()
DEBUG: Parameters passed in>>> Name: 'NuGet.Internal.GithubIssueTagger'; VersionRange: ''; NuGetVersion: ''; VersionType: 'NoVersion'; Version: ''; Prerelease: 'False'; Repository: 'gh-nuget'; AcceptLicense: 'False'; Quiet: 'False'; Reinstall: 'False'; TrustRepository: 'True'; NoClobber: 'False'; AsNupkg: 'False'; IncludeXml 'True'; SavePackage 'False'; TemporaryPath ''; SkipDependencyCheck: 'False'; AuthenticodeCheck: 'False'; PathsToInstallPkg: 'C:\Users\<redacted>\Documents\PowerShell\Modules,C:\Users\<redacted>\Documents\PowerShell\Scripts'; Scope 'CurrentUser'
DEBUG: In InstallHelper::ProcessRepositories()
VERBOSE: credential successfully read from vault and set for repository: gh-nuget
VERBOSE: Attempting to search for packages in'gh-nuget'
WARNING: Installing dependencies is not currently supported for V3 server protocol repositories. The package will be installed without installing dependencies.
Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): a
DEBUG: In InstallHelper::InstallPackages()
DEBUG: In InstallHelper::InstallPackage()
DEBUG: In V3ServerAPICalls::FindName()
DEBUG: In V3ServerAPICalls::FindNameHelper()
DEBUG: In V3ServerAPICalls::GetVersionedPackageEntriesFromRegistrationsResource()
DEBUG: In V3ServerAPICalls::GetResourcesFromServiceIndex()
DEBUG: In V3ServerAPICalls::HttpRequestCall()
DEBUG: Request url is 'https://nuget.pkg.github.com/NuGet/index.json'
DEBUG: In V3ServerAPICalls::FindRegistrationsBaseUrl()
DEBUG: In V3ServerAPICalls::GetVersionedResponsesFromRegistrationsResource()
DEBUG: In V3ServerAPICalls::HttpRequestCall()
DEBUG: Request url is 'https://nuget.pkg.github.com/NuGet/nuget.internal.githubissuetagger/index.json'
DEBUG: In V3ServerAPICalls::GetMetadataElementsFromResponse()
DEBUG: In V3ServerAPICalls::GetMetadataElementFromItemsElement()
DEBUG: In V3ServerAPICalls::IsLatestVersionFirstForSearch()
DEBUG: 'NuGet.Internal.GithubIssueTagger' version parsed as '2025.4.30'
Confirm
Are you sure you want to perform this action?
Performing the operation "Install-PSResource" on target "Package to install: 'nuget.internal.githubissuetagger', version: '2025.4.30'".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): a
DEBUG: In V3ServerAPICalls::InstallPackage()
DEBUG: In V3ServerAPICalls::InstallVersion()
DEBUG: In V3ServerAPICalls::InstallHelper()
DEBUG: In V3ServerAPICalls::GetVersionedPackageEntriesFromRegistrationsResource()
DEBUG: In V3ServerAPICalls::GetResourcesFromServiceIndex()
DEBUG: In V3ServerAPICalls::HttpRequestCall()
DEBUG: Request url is 'https://nuget.pkg.github.com/NuGet/index.json'
DEBUG: In V3ServerAPICalls::FindRegistrationsBaseUrl()
DEBUG: In V3ServerAPICalls::GetVersionedResponsesFromRegistrationsResource()
DEBUG: In V3ServerAPICalls::HttpRequestCall()
DEBUG: Request url is 'https://nuget.pkg.github.com/NuGet/nuget.internal.githubissuetagger/index.json'
DEBUG: In V3ServerAPICalls::GetMetadataElementsFromResponse()
DEBUG: In V3ServerAPICalls::GetMetadataElementFromItemsElement()
DEBUG: In V3ServerAPICalls::IsLatestVersionFirstForInstall()
DEBUG: In V3ServerAPICalls::HttpRequestCallForContent()
DEBUG: Request url is 'https://nuget.pkg.github.com/NuGet/download/nuget.internal.githubissuetagger/2025.4.30/nuget.internal.githubissuetagger.2025.4.30.nupkg'
DEBUG: In InstallHelper::TryInstallToTempPath()
VERBOSE: This resource is not a PowerShell package and will be installed to the modules path: C:\Users\<redacted>\Documents\PowerShell\Modules.
DEBUG: In InstallHelper::DeleteExtraneousFiles()
DEBUG: Deleting 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30\nuget.internal.githubissuetagger.nuspec'
DEBUG: Deleting 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30\[Content_Types].xml'
DEBUG: Deleting 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30\_rels'
DEBUG: Deleting 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30\package'
DEBUG: In InstallHelper::CreateMetadataXMLFile()
WARNING: Installing dependencies is not currently supported for V3 server protocol repositories. The package will be installed without installing dependencies.
DEBUG: In InstallHelper::TryMoveInstallContent()
DEBUG: In InstallHelper::MoveFilesIntoInstallPath()
VERBOSE: Installation source path is: 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30'
VERBOSE: Installation destination path is: 'C:\Users\<redacted>\Documents\PowerShell\Modules\nuget.internal.githubissuetagger\2025.4.30'
VERBOSE: Attempting to move 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc\nuget.internal.githubissuetagger\2025.4.30' to 'C:\Users\<redacted>\Documents\PowerShell\Modules\nuget.internal.githubissuetagger\2025.4.30'
VERBOSE: Successfully installed package 'nuget.internal.githubissuetagger' to location 'C:\Users\<redacted>\Documents\PowerShell\Modules'
VERBOSE: Attempting to delete 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc'
VERBOSE: Successfully deleted 'C:\Users\<redacted>\AppData\Local\Temp\300c9c54-bb71-4f9b-b166-854c718b2bdc'
PS >
PS >Find-PSResource-Repository 'gh-pwsh'-Name 'test*'
Name Version Prerelease Repository Description
------------------------------------------
test_local_mod 1.0.0 gh-pwsh None
test_module 5.0.0 gh-pwsh This is a test module,for PSGallery team internal testing. Do not take a dependency on this package. This version co…
test_module2 5.0.0 gh-pwsh This is a test module,for PSGallery team internal testing. Do not take a dependency on this package. This version co…
test_script 3.5.0 gh-pwsh Description for the Required-Script1 script
test_local_mod 1.0.0 gh-pwsh None
test_module 5.0.0 gh-pwsh This is a test module,for PSGallery team internal testing. Do not take a dependency on this package. This version co…
test_module2 5.0.0 gh-pwsh This is a test module,for PSGallery team internal testing. Do not take a dependency on this package. This version co…
test_script 3.5.0 gh-pwsh Description for the Required-Script1 script
PS >
Please add a test module with some upper case. Then we can write a test, and fix this.
Pseudo code idea for fix:
Do test install of .nugetpkgs to temp path.
If GitHub NuGet v3 API.
String case sensitive compare ID from API with:
Module: Use file name of module manifest <modulename>.psd1.
Script: Use file name of <scriptname>.ps1.
Fallback: Use file name of <packagename>.nuspec.
If case sensitive compare finds a difference: Use name from above.
Running into this exact issue with a Github NuGet feed, same repro steps as described above with PSResourceGet 1.2.0.
Though I didn't see any updates to the above, I also tried Microsoft.PowerShell.PSResourceGet 1.3.0-preview1 just in case but still observe the issue.
This does break module discoverability and implicit module importing/auto loading on Linux unless the folder is renamed to the correcting casing which is an extra step.
My thinking based on what Olav Rønnestad Birkeland (@o-l-a-v) wrote up, is that even if this was solely a GH issue is there something defensive that can be added to PSResourceGet? A mechanism to ensure that regardless of Nuget feed, that the installed module folder names always match what's in the manifest?
Edit: Almost missed it but see that Olav has a draft PR (#1855) open that starts to work on a fix. If that's working, I am all for getting that merged into the 1.3.0 previews if possible😊
Activity
LaurentDardenne commentedon Oct 15, 2023
This is an issue referenced, but not documented as a known issue. Everyone discovers it.
There is an implicit rule which is not controlled and remains the responsibility of the user. Just like the file names specified in a module manifest.
The case of the package name can influence the installation, see the platyPS module for example.
See too : PowerShell/PowerShellGetv2#472 (comment)
rickandersen-forte commentedon Oct 16, 2023
Thanks, Laurent Dardenne (@LaurentDardenne), although I'm not sure this is part of that overall issue; I'm not convinced it's that straightforward. When I install my module to PSGallery, with the mixed-case names, everything works fine. The module is installed into a mixed-case directory and all is well. But when I publish to the GitHub Packages, which (apparently) requires that I use the newly-released PowerShellGet v3 (PSResourceGet), it installs into a lowercase directory and the problem arises. PSResourceGet (more specifically, Install-PSResource) also works on PSGallery, so I'm starting to suspect the problem is with GitHub's environment.
I've been assuming GitHub is using standard hosting software, but I don't know if that's the case. Maybe I need to flag this as a bug for GitHub? Any ideas?
LaurentDardenne commentedon Oct 16, 2023
This may be another problem...
Here is a case where this occurs :
https://cloudsmith.io/~psmodulecache/repos/test/packages/detail/nuget/wrongnamingrule/1.0.0/#files
rickandersen-forte commentedon Oct 16, 2023
In my case, the module and package have the same name (i.e., "MyModule"), but the module is installed in the lowercase directory ("mymodule") when installed from GitHub Packages. If the directory and PSD1 file were named differently, I'd understand the issue, but they are the same.
I wish I could have you install it to see if you see the same behavior and/or see if I made a mistake, but I'm not allowed to expose it yet. I am trying to find a way to download the nupkg file directly so I can see if it was generated correctly by Publish-PSResource (via the following command).
SydneyhSmith commentedon Oct 16, 2023
Thanks for opening this issue Rick Andersen (@rickandersen-forte) PowerShell is, by default, case-insensitive even on non-Windows platform, to confirm are you running into an issue with your use case because of this or are you worried that you might in the future?
LaurentDardenne commentedon Oct 16, 2023
May be a problem similar to this
rickandersen-forte commentedon Oct 16, 2023
Thanks, Sydney Smith (@SydneyhSmith). I am already running into this case, but it's not a significant issue (yet?) because we are in development and I don't think it's being used by anyone in an affected environment (e.g., Debian or Ubuntu). I'm hoping to get it fixed before it does, but since this is an internal tool, worst case scenario is that I tell users to either rename the directory or create a properly named symbolic link to the lowercase-named directory.
As Laurent Dardenne (@LaurentDardenne) pointed out, it appears to be the same as issue 1402 (so far as I can tell).
rickandersen-forte commentedon Oct 16, 2023
In case it helps (e.g., I hope I'm doing something wrong in publication), below is the GitHub Action that I use to publish. Notice that the
Publish using nuget.exesection at the end is disabled; that was a test to see if using nuget worked better, but it had the same problem.Also relevant, the module directory and PSD1 file are both named
AnyChain.rickandersen-forte commentedon Oct 16, 2023
I was able to download the raw nupkg file from the GitHub Packages and it appears to be virtually identical to that from PSGallery (e.g., different Id and psmdcp Target file in .rels, "NuGet" vs "NuGet.Packaging" in .psmdcp files). Both also specify the nupkg name as lowercase ("anychain.2.5.8.4.nupkg") and mixed-case within the encapsulated files (e.g., AnyChain.nuspec's element).
Yet, when I install from PSGallery using Install-PSResource, it installs to ".../Modules/AnyChain", and when I install from GitHub using Install-PSResource, it installs to ".../Modules/anychain". GitHub uses ApiVersion v3 while PSGallery uses v2. I can't but suspect the problem is in the v3 repository "provider".
By chance, is there a v3 interface to the PSGallery yet that I can test against?
rickandersen-forte commentedon Oct 16, 2023
I just noticed that Find-PSResource also returns a lowercase name for the GitHub Packages repo, but a mixed-case for the PSGallery repo. It seems like that might be relevant.
rickandersen-forte commentedon Oct 17, 2023
Through experiments, it appears that the case of the nupkg filename and the name of the enclosed nuspec file (though not the
<id>within the nuspec file) must match exactly for the resource to be available via Find-PSResource or for Install-PSResource to work correctly.When installed from the GitHub repo, each part of the URL is converted to lowercase, as per the standard (https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource). This results in the downloaded nupkg filename and local directory name being lowercase, which is then moved into the final destination (keeping the same lowercase name), even though the package itself uses mixed case.
Since the URL must use lowercase (e.g.,
https://nuget.pkg.github.com/<organization>/anychain/2.5.8.4/anychain.2.5.8.4.nupkg), but the package itself may be mixed-case, as specified in the nuspec file (e.g.,<id>AnyChain</id>), it seems that two things must change in the PSResourceGet implementation to allow a workable installation under case-sensitive file systems:Publish-PSResourcemust generate a lowercase nuspec filename (e.g.,anychain.nuspec) that contains a mixed-case id tag (e.g.,<id>AnyChain</id>). Since this file is embedded in the nupkg file, the server can't be expected to convert it to lowercase for us. Right now, the file is created with the same case as the internal package name, which only works if the package name is always lowercase (a very bad restriction).Install-PSResourcemust download the package to a directory whose name matches the mixed-case id tag from the<id>tag within the nupkg file, not the lowercase package name; or at least convert it to that name before the installation completes. This allows the installed directory to match the case of the actual module so PowerShell can find the module in a mixed-case-sensitive environment.Or, I'm completely lost and don't know what I'm talking about. Definitely possible. If so, please let me know.
LaurentDardenne commentedon Oct 17, 2023
I don't think so, it's consistent with the behavior we see.
I don't know if it's related to this problem, but when downloading from the Cloudsmith site the file name 'anychain.2.5.8.4.nupkg' is renamed to 'AnyChain.2.5.8.4.nupkg' ( id=AnyChain ) :
Which is not the case for the package I mentioned previously:
The difference is I created the .nuspec file and the package manually.
For this package the directory name is in lower case:

Which is not the case for your package.
rickandersen-forte commentedon Oct 17, 2023
If my understanding is correct, the behavior you're seeing makes sense. I believe the name of the downloaded nupkg file should be the same as the
<id>from the nuspec file, not the value as specified in the URL. I'm not sure if that's necessary, but it is if the client-side installer uses the file name instead of the<id>value for the target directory. I suspect the safest would be to do both in case there are clients that don't follow that rule. (Q: IsInstall-PSResourcethe only relevant client in this context?)Sydney Smith (@SydneyhSmith): Any thoughts or suggestions? I'm not asking for a commitment, but just wondering if this sounds like we're on the right track? And thinking maybe I should rename my modules to be all lowercase if it looks like this fix (or any fix) isn't possible in the foreseeable future.
corkupine commentedon Jun 20, 2024
Is there any update on when we should expect this issue to be addressed? We got bit by this too. Also - there is another open issue which I believe is the same and perhaps should be merged. Thanks!
o-l-a-v commentedon Aug 11, 2025
Anam Navied (@anamnavi) and/or alerickson
I can reproduce this with NuGet GitHub Packages repo package
NuGet.Internal.GithubIssueTagger.https://nuget.pkg.github.com/NuGet/index.jsonDebug output
Various NuGet v3 APIs compared:
read:packages): https://nuget.pkg.github.com/NuGet/nuget.internal.githubissuetagger/index.jsonSo, can not reproduce with other NuGet v3 sources, like pwsh.gallery by Justin Grote, or NuGet Gallery.
The PowerShell GitHub Packages repo only contains lower case modules?
https://nuget.pkg.github.com/PowerShell/index.jsonPlease add a test module with some upper case. Then we can write a test, and fix this.
Pseudo code idea for fix:
.nugetpkgsto temp path.<modulename>.psd1.<scriptname>.ps1.<packagename>.nuspec.ephos commentedon Jun 4, 2026
Running into this exact issue with a Github NuGet feed, same repro steps as described above with PSResourceGet 1.2.0.
Though I didn't see any updates to the above, I also tried Microsoft.PowerShell.PSResourceGet 1.3.0-preview1 just in case but still observe the issue.
This does break module discoverability and implicit module importing/auto loading on Linux unless the folder is renamed to the correcting casing which is an extra step.
My thinking based on what Olav Rønnestad Birkeland (@o-l-a-v) wrote up, is that even if this was solely a GH issue is there something defensive that can be added to PSResourceGet? A mechanism to ensure that regardless of Nuget feed, that the installed module folder names always match what's in the manifest?
Edit: Almost missed it but see that Olav has a draft PR (#1855) open that starts to work on a fix. If that's working, I am all for getting that merged into the 1.3.0 previews if possible😊