为什么 Powershell 输出在 5.1 和 Core 7.1.4 之间不同

Why is Powershell output different between 5.1 and Core 7.1.4

我有一段 PowerShell 代码,运行 是一个命令,然后对其进行处理并将其写入文本文件。

$commandOutput = &"C:\Program Files (x86)\Dell EMC\Unity\Unisphere CLI\uemcli" -d $frame -noHeader /stor/config/pool/sr show
foreach ($idline in $commandOutput)
{
    if ($idline -match ' ID ')
    {
    $subline = $idline.substring(6,($idline.length - 6))
    $writeline = $subline.trim()
    #$writeline
    }
    elseif ($idline -match 'Total pool space used')
    {
    $Sleft,$Sright = $idline.Split('(',2)
    $writeline = $Sleft.trim()
    #    $writeline
    #    write-host ""
    } 
 
    else {$writeline = $idline.trim()}
    #$writeline
    Add-Content -path $outdir$frame-intrim.txt -value $writeline -Encoding UTF8
    }

当我在 PowerShell 5.1 中 运行 它时,我得到:

ID                    = res_2
Name                  = asi-vcva-fs01
Resource type         = VMware NFS
Pool                  = pool_1
Total pool space used = 18025199894528
Health state          = OK (5)

当我在 PowerShell Core 7.1.4 中 运行 它时,我得到:

1 :          I D                                         =   r e s _ 2 
             N a m e                                     =   a s i - v c v a - f s 0 1 
             R e s o u r c e   t y p e                   =   V M w a r e   N F S 
             P o o l                                     =   p o o l _ 1 
             T o t a l   p o o l   s p a c e   u s e d   =   1 8 0 2 5 2 1 3 2 7 2 0 6 4   ( 1 6 . 3 T ) 
             H e a l t h   s t a t e                     =   O K   ( 5 )

这打乱了脚本的其余部分。我尝试了 -Encoding UTF8 但没有任何改变。我如何使它能够在 5.1 和 Core 7.1 中 运行?

更多信息:

它以这种方式写入输出的原因是因为这是从输入中解析数据的方式。我如何去掉空格,特别是要使其在两个版本的代码中都可用?

我不知道为什么在这种情况下 PowerShell 版本之间的行为不同,但看起来uemcli 输出 UTF-16LE(“Unicode”)编码字符串.

为了让 PowerShell 正确识别它们[1],(暂时)设置
[Console]::OutputEncoding = [Text.Encoding]::Unicode
调用前
.


至于诊断特定外部程序使用的字符编码以及PowerShell如何对其进行解码:

  • 参见的底部部分,它提供了两个辅助函数:

    • Debug-NativeInOutput 帮助您诊断外部程序的输入和输出。

    • Invoke-WithEncoding 使具有给定编码的外部程序调用更容易;例如,在您的情况下,您会致电:

      Invoke-WithEncoding -Encoding Unicode { 
        & "C:\Program Files (x86)\Dell EMC\Unity\Unisphere CLI\uemcli" -d $frame -noHeader /stor/config/pool/sr show
      }
      
  • This answer 包含另一个辅助函数,Debug-String,它可以帮助您找到一般字符串中的非打印和非 ASCII 字符;例如,从 UTF-16LE 输出中错误解码的 ASCII 范围字符将导致该字符 加上一个 NUL (0x0) 字符 ,其中 Debug-String 会显示为 `0.

    • 默认情况下,NUL 个字符在控制台中打印 个空格,这就是您所看到的。

[1]在后续处理;请注意,direct-to-display 输出可能 print 没问题,但字符编码问题可能会在 PowerShell decodes 输出,这总是发生在变量中捕获输出或通过管道或文件发送输出的过程中。