powershellazure-devopsazure-powershellazure-clipowershell-7.3

Azure CLI and PowerShell 7.3 OutputEncoding issue


There are two different commands run in my PowerShell 7.3 within Windows Terminal.

  1. Just run the az devops user show command.

    az devops user show --user $UserPrincipalName -o json
    

    enter image description here

  2. Run the same command with a $(...).

    $(az devops user show --user $UserPrincipalName -o json)
    

    enter image description here

It because my user info contains Chinese characters. The first command will be able to show correct Chinese characters. The seconds command will show garbled text on the screen.

With the same commands, if I run in my Windows PowerShell 5.1, it display the Chinese characters perfectly. Why?

What's the difference between these two commands? How to display the Chinese characters correctly on the screen when running the second command in PowerShell 7.3?

Edit

I tried to run this before run my second command. Then the output display Chinese characters correctly.

[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding('big5')

Is there any way I can force az command output using utf8 encoding?


Solution

  • tl;dr

    # Custom az CLI entry point that requests UTF-8 output and decodes it as such.
    # Based on the az.cmd batch file that comes with v2.57.0
    # (but this batch file's content rarely changes).
    function az {
    
      # Determine the full az.cmd path and derive the location of the
      # bundled Python executable.
      $azCliPath = (Get-Command -ErrorAction Ignore az.cmd).Path
      if (-not $azCliPath) { throw "'az.cmd' cannot be located via the system's path." }
      $bundledPythonExe = Convert-Path -ErrorAction Ignore -LiteralPath "$azCliPath\..\..\python.exe"
      if (-not $bundledPythonExe) { throw "Failed to load Python executable." }
    
      # Prepare the environment and temporarily instruct
      # PowerShell to decode external-program output as UTF-8.
      $prevValue = $env:AZ_INSTALLER; $env:AZ_INSTALLER = 'MSI'
      $prevEncoding = [Console]::OutputEncoding; [Console]::OutputEncoding = [Text.UTF8Encoding]::new()
    
      # Call the actual CLI via the bundled Python, requesting UTF-8 output (-X utf8),
      # and passing all arguments as well as the output through.
      & $bundledPythonExe -X utf8 -IBm azure.cli @args
    
      # Restore previous settings.
      [Console]::OutputEncoding = $prevEncoding
      $env:AZ_INSTALLER = $prevValue
    
    }
    

    Background information


    [1] As a selective exception in PowerShell 7.4+, > and >>, the redirection operators - unlike calls to cmdlets such as Set-Content and Out-File - now save the raw byte output from external programs to the target file. See this answer for background information.