Format-Table -GroupBy, отображающий свойство массива в одной строке

Я создаю пользовательский объект с двумя свойствами. Первая - это строка, в основном ключ, а вторая - это вывод функции, которая возвращает массив. Затем я передаю результаты в Format-Table и группирую по свойству string. Я хотел бы видеть каждый элемент свойства массива в отдельной строке в выводе. Вместо этого Format-Table отображает массив в одной строке.

Есть ли способ форматирования вывода, чтобы каждый элемент свойства массива отображался в отдельной строке?

Вот некоторый код, который иллюстрирует проблему:

function Get-Result([string]$lookup)
{
    if ($lookup -eq "first")
    {
        return @("one", "two")
    }
    else
    {
        return @("three")
    }
}

$a = "first", "second"

$a | 
    Select-Object @{Name="LookupValue"; Expression={$_}}, `
        @{Name="Result"; Expression={Get-Result $_}} | 
    Format-Table -GroupBy LookupValue

И вот что он выводит:

   LookupValue: first

LookupValue Result    
----------- ------    
first       {one, two}


   LookupValue: second

LookupValue Result
----------- ------
second      three 

То, что я хотел бы видеть это:

   LookupValue: first

LookupValue Result    
----------- ------    
first       one  
first       two    


   LookupValue: second

LookupValue Result
----------- ------
second      three 

2 ответа

Решение

Format-cmdlets не собираются создавать объекты, которые не существуют. В вашем примере есть значение результата, которое содержит массив. Если вы не хотите, чтобы это был массив, а вместо этого часть двух отдельных объектов, то вам нужно как-то разделить это или изменить процесс создания, чтобы сделать эти несколько / отсутствующих объектов.

Первый, добавив еще один внутренний цикл, который обрабатывает несколько "результатов"

$a | ForEach-Object{
    $element = $_
    Get-Result $element | ForEach-Object{
        $_ | Select-Object @{Name="LookupValue"; Expression={$element}},
            @{Name="Result"; Expression={$_}}
    }
} | Format-Table -GroupBy LookupValue

Так что для каждого выхода Get-Result новый объект создается с ссылкой на текущий LookupValue в трубопроводе, который представлен $element,

Это немного неуклюже, поэтому я также хочу добавить пример лестницы, где мы изменим ваш процесс создания

function Get-Result{
    param(
        [Parameter(
            ValueFromPipeline)]
        [string]$lookup
    )

    process{
        switch($lookup){
            "first"{
                [pscustomobject]@{LookupValue=$lookup;Result="one"},
                [pscustomobject]@{LookupValue=$lookup;Result="two"}
            }
            default{
                [pscustomobject]@{LookupValue=$lookup;Result="three"}
            }

        }
    }
}

$a = "first", "second"
$a | Get-Result | Format-Table -GroupBy LookupValue

Создайте функцию, которая принимает входные данные конвейера и выплевывает pscustomobjects на основе $lookup, Я использовал здесь переключатель в случае, если ваше реальное применение этого имело больше условий, чем вы показываете в своем примере.

Заметка

Для того чтобы -GroupBy Для работы набор данных должен быть отсортирован. Так что, если у вас есть проблемы с реальными данными, которые не отображаются правильно.... сначала рассортируйте их.

Один из способов получить это -

function Get-Result([string]$lookup) {
    if ($lookup -eq "first") {
        Write-Output @( 
            @{ LookupValue=$lookup; Result="one" },
            @{ LookupValue=$lookup; Result="two" }
        )
    }
    else {
        Write-Output @(
            @{ LookupValue=$lookup; Result="three" }
        )
    }
}

"first", "second" | % {  Get-Result($_) } | % { [PSCustomObject]$_ } | Format-Table LookupValue, Result -GroupBy LookupValue

Выход:

    LookupValue: first

LookupValue Result
----------- ------
first       one   
first       two   


   LookupValue: second

LookupValue Result
----------- ------
second      three 
Другие вопросы по тегам