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

AZ CLI 2.40 on Windows Powershell fails to run '&' invocation operator with parameters #23890

Closed
katriendg opened this issue Sep 14, 2022 · 13 comments
Assignees
Labels
Account az login/account Auto-Assign Auto assign by bot Azure CLI Team The command of the issue is owned by Azure CLI team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Shell - PowerShell
Milestone

Comments

@katriendg
Copy link

az feedback auto-generates most of the information requested below, as of CLI version 2.0.62

Related command

Any AZ command with arguments using an invocation operator.

Describe the bug
In PowerShell on Windows, with CLI 2.40, using PS 5.2, 7.2.6 or 7.3.preview7, all versions fail to run script blocks with the invocation (call) operator '&' and passing an arguments array. It looks like parsing is not done correctly and could be linked to this article https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md

To Reproduce
Try out a block like this in your PowerShell terminal, the result is Azure CLI returning an error that the 'account show' is misspelled or cmdlet not found.

$arglist = @("account", "show")
& "az" $arglist

Expected behavior
The expected behavior is that 'az account show' should be executed and the result of the JSON shown on screen.

Environment summary
OS: Windows 11 insider build
PowerShell 7.2.6
AZ CLI: 2.40

I also tested this on PowerShell in CloudShell and there it runs as expected. Als on PowerShell on Linux WSL2 it works fine, both using Azure CLI 2.40. It seems the issue is only arising on Windows.

@ghost ghost added Auto-Assign Auto assign by bot Account az login/account labels Sep 14, 2022
@ghost ghost assigned jiasli Sep 14, 2022
@ghost ghost added this to the Backlog milestone Sep 14, 2022
@yonzhan yonzhan added Azure CLI Team The command of the issue is owned by Azure CLI team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Sep 14, 2022
@yonzhan
Copy link
Collaborator

yonzhan commented Sep 14, 2022

@jiasli for awareness

@tj-spyro
Copy link

I think I have the same issue and it is affecting our ability to use the call operator and mock az using pester for testing, for example:

Describe "mocking az" {
  It "mock az" {
    function GetAzVersion {
      & az version
    }
    Mock az { Write-Warning "$args"; Write-Output "az successfully mocked" }
    GetAzVersion | Should -Be "az successfully mocked"
    Should -Invoke az -Exactly -Times 1 -ParameterFilter { $args[0] -eq 'version' }
  }
}

The expected behaviour is for the tests to pass as the az command was not invoked but the mock was.
The actual behaviour is that the az command is invoked with the following output:

Starting discovery in 1 files.
Discovery found 1 tests in 74ms.
Running tests.
[-] mocking az.mock az 1.9s (1.87s|25ms)
 Expected 'az successfully mocked', but got @('{', '  "azure-cli": "2.40.0",', '  "azure-cli-core": "2.40.0",', '  "azure-cli-telemetry": "1.0.8",', '  "extensions": {', '    "azure-devops": "0.25.0",', '    "desktopvirtualization": "0.2.0",', '    "interactive": "0.4.5",', '    "sentinel": "0.1.1"', '  }', ...1 more).
 at GetAzVersion | Should -Be "az successfully mocked", C:\Temp\azpester\mocking-az.tests.ps1:9
 at <ScriptBlock>, C:\Temp\azpester\mocking-az.tests.ps1:9
Tests completed in 2.18s
Tests Passed: 0, Failed: 1, Skipped: 0 NotRun: 0

@cveld
Copy link

cveld commented Sep 15, 2022

In my own wording:

In az 2.39 the following was still possible:

az @("extension", "list")

In az 2.40 this breaks:
'extension list' is misspelled or not recognized by the system.

With Az cli 2.39 Get-Command az returns the following:

CommandType: Application
Name: az.cmd                                               
Version: 0.0.0.0
Source: C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.cmd

With Az cli 2.40 Get-Command az returns the following:

CommandType: ExternalScript  
Name: az.ps1                                                                                      
Version: <blank>
Source: C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.ps1

Workaround found, with az 2.40:

pwsh -command az @("extension", "list")

works.

Permanent solution

Inside az.ps1 we have changed $args to @args which seems a simple fix.

@Jawz84
Copy link

Jawz84 commented Sep 15, 2022

This can be solved by adapting the build_scripts/windows/scripts/az.ps1 script:

$env:AZ_INSTALLER="MSI"
& "$PSScriptRoot\..\python.exe" -IBm azure.cli $args

# SIG # Begin signature block
# <generated signature omitted>

should become

$env:AZ_INSTALLER="MSI"
& "$PSScriptRoot\..\python.exe" -IBm azure.cli @args  # notice the @ instead of the $ here with @args

# SIG # Begin signature block
# <generated signature omitted>

Maintainers should re-generate the signature block ofcourse. So I won't be offering a pull request at this time.

This can be used as a local work-around too. Just change $args to @args in your az.ps1. (Find where it lives by using get-command az)

Thanks @cveld for drawing my attention to this issue :-)

@mjhilton
Copy link

We are encountering the same/very similar issue in a script that is bundled with our project, and customers are now unable to login if using 2.40 on Windows. A simplified version of our login script looks like this:

$loginArgs = @();
$loginArgs += @("--username=""exampleusername""");
$loginArgs += @("--password=""examplepassword""");
$loginArgs += @("--tenant=""exampletenant""");

az login --service-principal $loginArgs

This runs in a non-interactive PowerShell session, and so just appears to hang indefinitely for the user. When run in an interactive session, you get the Password: prompt as if no password were provided, because the args aren't parsed/passed properly.

@EmilDamsbo
Copy link

EmilDamsbo commented Oct 4, 2022

This has had me fixing infrastructure code on so many release branches in different repositories. Please, for the love of all that is good. Fix this issue with 2.41 so I don't have to go and fix even more stuff when it inevitably breaks on an older branch of mine which needs hotfixing.

@yonzhan yonzhan added the CXP Attention This issue is handled by CXP team. label Oct 4, 2022
@ghost
Copy link

ghost commented Oct 4, 2022

Thank you for your feedback. This has been routed to the support team for assistance.

@yonzhan
Copy link
Collaborator

yonzhan commented Oct 4, 2022

The next version will revert that change and will be shipped on 10.12

@EmilDamsbo
Copy link

@yonzhan will this be done in such a way that the workaround mentioned in this thread will still work? So both these snippets would perform the same:

$env:AZ_INSTALLER="MSI"
& "$PSScriptRoot\..\python.exe" -IBm azure.cli $args

and

$env:AZ_INSTALLER="MSI"
& "$PSScriptRoot\..\python.exe" -IBm azure.cli @args  # notice the @ instead of the $ here with @args

Example courtesy of @Jawz84

@yonzhan
Copy link
Collaborator

yonzhan commented Oct 4, 2022

If 2.39 works, 2.41 works.

@Jawz84
Copy link

Jawz84 commented Oct 4, 2022

The next version will revert that change and will be shipped on 10.12

Thank you for taking this up and informing us.

@PramodValavala-MSFT PramodValavala-MSFT removed the CXP Attention This issue is handled by CXP team. label Oct 13, 2022
@jiasli
Copy link
Member

jiasli commented Mar 1, 2024

Duplicate of #23797

@jiasli jiasli marked this as a duplicate of #23797 Mar 1, 2024
@jiasli jiasli closed this as completed Mar 1, 2024
@jiasli
Copy link
Member

jiasli commented Mar 1, 2024

@cveld, az @("extension", "list") is actually passing an array @("extension", "list") to az.ps1 as $arg[0]. This is not what az.ps1 is designed to take.

This can be verified with:

test.ps1:

$args.GetType()
$args[0].GetType()
$args[0][0].GetType()
> ./test.ps1 @("extension", "list")

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
True     True     Object[]                                 System.Array
True     True     String                                   System.Object

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Account az login/account Auto-Assign Auto assign by bot Azure CLI Team The command of the issue is owned by Azure CLI team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Shell - PowerShell
Projects
None yet
Development

No branches or pull requests

9 participants