Closed katriendg closed 6 months ago
@jiasli for awareness
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
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.
Inside az.ps1
we have changed $args
to @args
which seems a simple fix.
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 :-)
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.
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.
Thank you for your feedback. This has been routed to the support team for assistance.
The next version will revert that change and will be shipped on 10.12
@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
If 2.39 works, 2.41 works.
The next version will revert that change and will be shipped on 10.12
Thank you for taking this up and informing us.
Duplicate of https://github.com/Azure/azure-cli/issues/23797
@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
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.
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.