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

Calling Register-PSRepository or Set-PSRepository triggers the error Unknown Option: -V in Powershell Core running on Ubuntu Linux #661

Open
5 tasks done
tristanbarcelon opened this issue Sep 7, 2021 · 7 comments

Comments

@tristanbarcelon
Copy link

Prerequisites

Steps to reproduce

  1. Create an Azure Devops YAML pipeline with following definition. To protect my private Nuget v2 feed, I've replaced the actual feed url with myorg and myfeed
trigger: none

pool:
   vmImage: 'ubuntu-latest'

variables:
- name: PowershellRepositoryName
  value: 'PrivatePSGallery'
- name: PowershellRepositorySourceLocation
  value: 'https://pkgs.dev.azure.com/**myorg**/_packaging/**myfeed**/nuget/v2'

- task: PowerShell@2
  displayName: 'Set or register PrivatePSGallery'
  inputs:
    targetType: 'filePath'
    filePath: '$(Build.SourcesDirectory)/src/setprivatepsgallery.ps1'
    arguments: '-RepositoryName $(PowershellRepositoryName) -RepositorySourceLocation $(PowershellRepositorySourceLocation)'
    failOnStderr: true
    showWarnings: true
    pwsh: true
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  1. define setprivatepsgallery.ps1 as follows and store in src folder:
[CmdletBinding()]
param(
    [Parameter(Mandatory = $true, HelpMessage = 'Powershell repository name to set or register')]
    [string] $RepositoryName,
    [Parameter(Mandatory = $true, HelpMessage = 'Azure Devops feed URL to use as repository source')]
    [string] $RepositorySourceLocation
)
begin {}
process {
    try
    {
        [string] $BuildDefinition = $ENV:BUILD_DEFINITIONNAME

        if ([string]::IsNullOrEmpty($ENV:SYSTEM_ACCESSTOKEN))
        {
            Write-Error "Build pipeline: $BuildDefinition needs to have access to SYSTEM_ACCESSTOKEN environment variable"
        }
        else
        {
            $AZDOCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @('buildagent', (ConvertTo-SecureString -String $ENV:SYSTEM_ACCESSTOKEN -AsPlainText -Force))
        }

        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13

        Write-Host "Searching for repository: $($RepositoryName)"
        $PrivateRepository = Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue

        if ($null -eq $PrivateRepository)
        {
            $PrivateRepository = Get-PSRepository | Where-Object { ($_.SourceLocation -ieq $RepositorySourceLocation) -and ($_.Name -ine $RepositoryName) }
            if ($null -ne $PrivateRepository)
            {
                Write-Host "Unregistering repository $($RepositoryName)"
                Unregister-PSRepository -Name $RepositoryName
            }
            Write-Host "Registering repository $($RepositoryName) name with SourceLocation to $($RepositorySourceLocation)"
            Register-PSRepository -Name $RepositoryName -SourceLocation $RepositorySourceLocation -InstallationPolicy Trusted -Credential $AZDOCredential
        }
        else
        {
            if (($PrivateRepository.SourceLocation -ine $RepositorySourceLocation) -or ($PrivateRepository.InstallationPolicy -ine 'Trusted'))
            {
                Write-Host "Updating repository $($RepositoryName) because its InstallationPolicy and SourceLocation do not match expected values"
                Set-PSRepository -Name $RepositoryName -InstallationPolicy Trusted -SourceLocation $RepositorySourceLocation -Credential $AZDOCredential
            }
            else
            {
                Write-Host "Found repository: $($RepositoryName) and no updates are needed"
            }
        }
    }
    catch {
        throw $_
    }
    finally {
        Get-Variable -Scope local -ErrorAction SilentlyContinue | Remove-Variable -ErrorAction SilentlyContinue
    }
}
end {}
  1. Define a build pipeline using the yaml definition and execute it.

Somebody also mentioned in a PowershellGetV2 issue that they also see the "Unknown option: -V" error.

Azure Devops team is also able to repro the error on hosted agents and I'm able to repro it on my private Azure devops agents. I filed an Azure Devops issue initially, thinking this was a problem with the PowershellV2 task. I have also confirmed that pwsh is not installed as a dotnet global tool. pwsh was installed on private Azure Devops agents via apt package manager

For a mininum repro, reduce the script down to just this and execute in Ubuntu 18.04.5 or 20.04.*, just as long as myorg and myfeed are replaced with a valid Azure Devops nuget v2 feed and a valid Azure Devops personal access token with scope to read the nuget feed.

[string] $RepositoryName = 'PrivatePSGallery'
[string] $RepositorySourceLocation = 'https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v2'
$AZDOCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @('vstsagent', (ConvertTo-SecureString -String <replace this with your azure devops personal access token> -AsPlainText -Force))

Register-PSRepository -Name $RepositoryName -SourceLocation $RepositorySourceLocation -InstallationPolicy Trusted -Credential $AZDOCredential

Expected behavior

I expect it to create or update a repository named PrivatePSGallery on Ubuntu machines 18.04.* or 20.04.* using Powershell Core 7.1.x, 7.0.x releases.

Actual behavior

Searching for repository: PrivatePSGallery
Registering repository PrivatePSGallery name with SourceLocation to https://pkgs.dev.azure.com/**myorg**/_packaging/**myfeed**/nuget/v2
Unknown option: -V
.NET SDK (5.0.400)
Usage: dotnet [runtime-options] [path-to-application] [arguments]

Error details

I get an error like this:


Searching for repository: PrivatePSGallery
Registering repository PrivatePSGallery name with SourceLocation to https://pkgs.dev.azure.com/**myorg**/_packaging/**myfeed**/nuget/v2
Unknown option: -V
.NET SDK (5.0.400)
Usage: dotnet [runtime-options] [path-to-application] [arguments]

Execute a .NET Core application.

runtime-options:
  --additionalprobingpath <path>   Path containing probing policy and assemblies to probe for.
  --additional-deps <path>         Path to additional deps.json file.
  --fx-version <version>           Version of the installed Shared Framework to use to run the application.
  --roll-forward <setting>         Roll forward to framework version  (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable).

path-to-application:
  The path to an application .dll file to execute.

Usage: dotnet [sdk-options] [command] [command-options] [arguments]

Execute a .NET Core SDK command.

sdk-options:
  -d|--diagnostics  Enable diagnostic output.
  -h|--help         Show command line help.
  --info            Display .NET Core information.
  --list-runtimes   Display the installed runtimes.
  --list-sdks       Display the installed SDKs.
  --version         Display .NET Core SDK version in use.

SDK commands:
  add               Add a package or reference to a .NET project.
  build             Build a .NET project.
  build-server      Interact with servers started by a build.
  clean             Clean build outputs of a .NET project.
  help              Show command line help.
  list              List project references of a .NET project.
  msbuild           Run Microsoft Build Engine (MSBuild) commands.
  new               Create a new .NET project or file.
  nuget             Provides additional NuGet commands.
  pack              Create a NuGet package.
  publish           Publish a .NET project for deployment.
  remove            Remove a package or reference from a .NET project.
  restore           Restore dependencies specified in a .NET project.
  run               Build and run a .NET project output.
  sln               Modify Visual Studio solution files.
  store             Store the specified assemblies in the runtime package store.
  test              Run unit tests using the test runner specified in a .NET project.
  tool              Install or manage tools that extend the .NET experience.
  vstest            Run Microsoft Test Engine (VSTest) commands.

Additional commands from bundled tools:
  dev-certs         Create and manage development certificates.
  fsi               Start F# Interactive / execute F# scripts.
  sql-cache         SQL Server cache command-line tools.
  user-secrets      Manage development user secrets.
  watch             Start a file watcher that runs a command when files change.

Run 'dotnet [command] --help' for more information on a command.

Environment data

Name                           Value
----                           -----
PSVersion                      7.1.4
PSEdition                      Core
GitCommitId                    7.1.4
OS                             Linux 4.15.0-154-generic PowerShell/PowerShell#161-Ubuntu SMP Fri Jul 30 13:04:17 UTC 2021
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

@SteveL-MSFT
Copy link
Member

Did you try the workaround mentioned in #619 (comment)?

@SteveL-MSFT SteveL-MSFT transferred this issue from PowerShell/PowerShell Sep 15, 2021
@tristanbarcelon
Copy link
Author

tristanbarcelon commented Sep 16, 2021

Hi @SteveL-MSFT , Are you referring to the workaround which used -SkipValidate? I did not try that because that was referring to Register-PackageSource and not Register-PSRepository. In my particular situation, I only needed to ensure that the Azure Devops backed private feed was was present to ensure subsequent steps are able to install/update specific powershell modules from that feed. Is Register-PSRepository invoking dotnet behind the scenes? I'm also not using nuget or dotnet to push or install any nuget package. Do I need to install the nuget credential provider (via https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh or https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1) and set the VSS_NUGET_EXTERNAL_FEED_ENDPOINTS env variable for Register-PSRepository or Set-PSRepository to work in addition to providing the Credential parameter?

@StevenBucher98
Copy link
Collaborator

Thanks @tristanbarcelon! From what we understand you are trying to use the credential provider and the credential provider for PowerShellGetv2 is a bit finicky and we have not been maintaining it. In PowerShellGetv3 we intent to add persistent credential (WIP PR) support soon so it might be better to wait for that and move to v3.

In the meantime, if you want to connect to a private feed, you can do so with the -Credential parameter on Find-Module, Install-Module and other such cmdlets. You will have to use it each time but will be the cleanest work around.

@tristanbarcelon
Copy link
Author

tristanbarcelon commented Sep 16, 2021

Hi @StevenBucher98, we're actually setting the -Credential parameter when calling Register-PSRepository or Set-PSRepository cmdlets in the setprivatepsgallery.ps1 above. I'm just not sure why I get the error below when setting -Verbose parameter to $false within the script and this only happens in pscore and ubuntu 18.04 and 20.04.

Unknown option: -V
.NET SDK (5.0.400)
Usage: dotnet [runtime-options] [path-to-application] [arguments]

I want to explicitly set -Verbose to $false for all built-in PSCore cmdlets we reference in our scripts and utilize Write-Verbose instead of Write-Host in the script/functions we write to minimize the amount of log data to sift through in our pipelines. For example, if we invoke our custom script setprivatepsgallery.ps1 with -Verbose set to $true, we would like to avoid these kinds of messages from Get-PSRepository.

image

Main motivating reason for setprivatepsgallery.ps1 was to decouple our pipeline from psgallery outages. Since Azure Devops nuget feeds does not support upstreaming of powershellgallery.com, we've written a script we run on a schedule that looks at a hashtable of psmodules we utilize and mirrors specific versions in the nuget feed. Version range syntax is similar to that of a nuget package reference.

[HashTable] $ModulesToSync = @{
        'AzurePipelinesPS' = '(3.0.13,4.0.7]'
        'Carbon' = '(2.9.2,2.10.2]'
        'dbatools' = '(1.0.101,1.2)'
        'MSI' = '3.3.4'
        'NameIT' = '(2.1.1,2.3.2]'
        'powershell-yaml' = '(0.4.1,0.4.2]'
        'PSOneTools' = '[1.0,2.4]'
        'RabbitMQTools' = '[1.0,1.5]'
        'SqlServer' = '[21.0.17099,21.1.18256]'
        'VcRedist' = '(2.0.181,3.0.273]'
        'VenafiTppPS' = '(1.2.3,2.2.7]'
        'ImportExcel' = '[6.5,7.3]'
        'VSSetup' = '[1.0,2.2]'
        'PSRabbitMQ' = '[0.3.1,0.3.5]'
        'VSTeam' = '(6.4.6,7.5)'
        'Az.Accounts' = '2.5.1'
        'Az.KeyVault' = '3.4.5'
        'Az.ApplicationInsights' = '1.2.0'
        'Az.Resources' = '4.2.0'
        'AWS.Tools.Common' = '4.1.14'
        'AWS.Tools.EC2' = '4.1.14'
        'AWS.Tools.ECR' = '4.1.14'
        'AWS.Tools.EKS' = '4.1.14'
        'AWS.Tools.Route53' = '4.1.14'
        'AWS.Tools.S3' = '4.1.14'
        'AWS.Tools.Elasticache' = '4.1.14'
        'Join-Object' = '2.0.2'
        'MicrosoftTeams' = '[2.0.0,2.6.0]'
        'NtObjectManager' = '[1.0,1.2.0)'
        'Bicep' = '[1.0.0,2.0.0]'
        'VenafiPS' = '[3.0,3.1]'
        'MarkdownToHtml' = '1.0'
        'ComputerManagementDsc' = '[8.0,8.5]'
        'ServiceNow' = '[1.8,3.0]'
    }

@alerickson
Copy link
Member

After taking a closer look at this issue, I think this is a bug originating from here:

Start-Process $filename -ArgumentList "$arguments -V minimal" `

For now I'd suggest not using the -Credential parameter when using Register-PSRepository or Set-PSRepository.
Whenever you access a repository you can simply pass in the credential object, eg:
Install-Resource <pkg-to-install> -Credental $AZDOCredential

Again, we're working on improving this scenario in PowerShellGet v3 so that it's smoother and more streamlined. Please follow us there for our upcoming releases so you can grab the credential persistence changes when they get pushed there. Also let us know if you're running into any other issues with this particular scenario.

@tristanbarcelon
Copy link
Author

tristanbarcelon commented Sep 17, 2021

Hi @alerickson, I have pscore 7.1.4 on Windows and Ubuntu and could not find Install-Resource cmdlet/function. Which module contains Install-Resource?

Update: @alerickson After a little bit more digging, I found this stackoverflow article. Did you want me to use Get-PackageSource, Register-PackageSource, Unregister-PackageSource, Install-Package cmdlets from PackageManagement in lieu of Get-PSRepository, Register-PSRepository, Unregister-PSRepository, Install-Module functions from PowershellGet and that would fix the Unknown option: -V error?

After using Register-PackageSource to add the azure devops feed, I can't seem to remove it anymore in Windows using Unregister-PackageSource. Is this information being stored in a file or registry key for me to remove manually? It also seems to me that using Register-PSRepository creates/updates a $ENV:APPData\Nuget\nuget.config file similar to what nuget.exe and dotnet nuget would have done. Furthermore, Register-PSRepository/Unregister-PSRepository also adds/removes an entry to the same store used by PackageManagement except that it has a ProviderName of PowershellGet.

@StevenBucher98
Copy link
Collaborator

Hi @tristanbarcelon,
We (@alerickson) were chatting and realized we meant to say
Install-Module <pkg-to-install> -Credental $AZDOCredential

Please give this a try and let us know if that resolves your issue.

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

No branches or pull requests

4 participants