Powershell 5 与 7 的不同输出

问题

我遇到一个奇怪的情况,在 Powershell 7 中运行某些东西会返回预期的结果,但在 Powershell 5 中则不会,除非你在多个赋值中打破行。

$wrong = az role assignment list --all --query "[? contains(scope,'/subscriptions/')]" | ConvertFrom-JSON | Select-Object *, @{
    
    n='Key';e={
    
    $_.scope+"|"+$_.roleDefinitionName+"|"+$_.principalName}}  | Select -expand Key
Write-Host Wrong
$wrong[0]

$right = az role assignment list --all --query "[? contains(scope,'/subscriptions/')]" | ConvertFrom-JSON 
$right = $right | Select-Object *, @{
    
    n='Key';e={
    
    $_.scope+"|"+$_.roleDefinitionName+"|"+$_.principalName}}  
$right = $right | Select -expand Key
Write-Host Right
$right[0]

$wrong 和 $right 在 PowerShell 7(Azure Portal Cloud Shell)中都是正确的,但 $wrong 在 PowerShell 5(来自 DevOps 管道)中给出了错误的结果…

Wrong
/subscriptions/***/resourceGroups/***/providers/Microsoft.ApiManagement/service/***
Right
/subscriptions/***/resourceGroups/***/providers/Microsoft.ApiManagement/service/***|Owner|

仅当将命令拆分为多行时,在 Select-Object 命令中为新属性 Key 完成的整个字符串连接才有效。

解决方案

ConvertFrom-Json在 PowerShell 5(以及 iirc 的早期版本 7.x)中,默认请求管道处理器不枚举数组输出- 这意味着如果您将以列表/数组作为根对象的 JSON 文档传递给ConvertFrom-JSON,它会将整个数组对象输出为一个东西:

PS ~> '[1,2,3,4,5]' |ConvertFrom-JSON |ForEach-Object {
    
    "We received 1 item: '$_'"}
We received 1 item: '1 2 3 4 5'

您可以通过将管道立即分解为两个下游管道ConvertFrom-JSON(正如您所发现的那样)来应对这种行为,或者您可以将输出通过管道传输到枚举数组的命令(此处使用Write-Output):

PS ~> '[1,2,3,4,5]' |ConvertFrom-JSON |Write-Output |ForEach-Object {
    
    "We received 1 item: '$_'"}
We received 1 item: '1'
We received 1 item: '2'
We received 1 item: '3'
We received 1 item: '4'
We received 1 item: '5'

我应该注意到 7.4 版本ConvertFrom-JSON还可以通过-NoEnumerateswitch 参数覆盖此行为,以便您获得与 5 中相同的行为:

PS ~> '[1,2,3,4,5]' |ConvertFrom-JSON -NoEnumerate |ForEach-Object {
    
     "We received 1 item: '$_'"}
We received 1 item: '1 2 3 4 5'

猜你喜欢

转载自blog.csdn.net/zhengzhaoyang122/article/details/143135473