2013-10-27 4 views
2

Как я могу изменить порядок столбцов на выходе мой код производит:Изменение порядка столбцов в объекте

$apps = Import-CSV apps.csv 
$computers = Import-CSV compobj.csv 
foreach ($computer in $computers) {  
    $computerLob = $computer.lob 
    $lobApps = $apps | ? {$_.lob -eq $computerLob } 
    foreach ($app in $lobApps) { 
     $computerHostname = $computer.hostname 
     $appLocation = $app.location 
     $installed=Test-Path "\\$computerHostname\$appLocation"  
     New-Object PSObject -Property @{ 
      Computer=$computer.hostname 
      App=$app.appname 
      Installed=$installed 
     } 
    } 

В настоящее время он продюсирует столбцы в следующем порядке: Installed,App,Computer.

Я хотел бы иметь его в следующем порядке: Computer,App,Installed.

+0

Кстати, у вас отсутствует закрывающая скобка. Я предполагаю, что вы намереваетесь иметь вложенные ** foreach ** циклы, а пропавшая скобка заканчивается? –

+0

См. [Мой ответ] (http://stackoverflow.com/a/19625295/897326) в [ваш другой вопрос] (http://stackoverflow.com/questions/19624304/powershell-change-format-of-output) , Ответы, представленные здесь, являются хорошими - это еще один способ сделать это. – Neolisk

ответ

7

Если вы хотите, чтобы обеспечить выход объекта происходит в определенном порядке, т.е. отформатированный определенным образом, то использовать форматирование PowerShell в команды.

$obj = [pscustomobject]@{Computer=$computer.hostname;App=$app.appname;Installed=$installed} 
$obj | Format-Table Computer,App,Installed 

Более того, вы сможете лучше контролировать выход, например:

$obj | Format-Table Computer,App,Installed -AutoSize 
ширина

Или поле управления & выравнивания:

$obj | Format-Table @{label='Computer';expression={$_.Computer};width=20;alignment='right'},App,Installed 

Честно говоря, я считаю, что это лучшая практика, чтобы использовать форматирование чтобы получить требуемый порядок вывода, а не полагаться на порядок, в котором создаются свойства.

+0

Использование Format-Table довольно многословно, и на самом деле это необязательно в PowerShell 3 и выше для объектов, которые вы создаете и отображаете сами, и при написании модулей было бы хорошей практикой знать об этом и настраивать порядок по умолчанию, который удобен для людей, читающих вашу продукцию снова и снова. – Eric

+0

Это нормально для вывода на хост, но не будет работать для экспорта в файл, поскольку он искажает объект в конвейере. См. Ответ от @Emiliano Poggi. – Chiramisu

4

Проблема в том, что вы добавляете свойства с помощью хеш-таблицы, а hashtables не сохраняют порядок. Вы можете сделать одну из двух вещей:

1. Добавить свойства в порядке, который будет установлен порядок (последняя строка для вывода объекта к трубопроводу):

$obj = New-Object PSObject 
$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $computer.hostname 
$obj | Add-Member -MemberType NoteProperty -Name App -Value $app.appname 
$obj | Add-Member -MemberType NoteProperty -Name Installed -Value $installed 
$obj 

2 . Определить порядок во время вывода объект к трубопроводу с помощью Select-Object:

New-Object PSObject -Property @{ 
    Computer=$computer.hostname 
    App=$app.appname 
    Installed=$installed 
} | select Computer,App,Installed 

Какого предпочтительнее зависит на сколько вы будете работать с объектом. Если, как следует из вашего вопроса, вы используете PSObject для отображения информации в табличном формате, второй способ выполняется быстрее. Если вы собираетесь вывести объект несколько раз в разные части скрипта, первый метод позволяет просто выводить его как $obj, а не для того, чтобы нажимать на каждый раз выбирать.

Отметим также, что второй метод можно разделить, как это, если вы не хотите, чтобы вывести объект сразу после заполнения его:

$obj = New-Object PSObject -Property @{ 
    Computer=$computer.hostname 
    App=$app.appname 
    Installed=$installed 
} 

[...do other stuff...] 

$obj | select Computer,App,Installed 
+0

Использование 'Select-Object' является излишним для форматирования вывода. Для этого лучше всего использовать «команды форматирования», то есть формат-таблицу в этом случае. В этом случае Select-Object создает совершенно новый 'pscustomobject', который не нужен, если целью является просто форматирование вывода. –

+1

@KeithHill Это на самом деле сама причина, по которой я использовал ** Select-Object ** вместо ** Format-Table ** - потому что я не хотел предполагать, что желание заказать столбцы подразумевает, что единственное использование функции чтобы отобразить данные, и на выходе никогда не нужно было бы переводить на что угодно. Я считаю, что лучше использовать функции, которые извлекают один набор данных для вывода объектов в конвейер, делая их более гибкими и перепрофилируемыми, и используйте ** ft **, только если вам нужны его дополнительные функции форматирования или если вы уверены код будет использоваться только для отображения конечного результата. –

9

Powershell V3 добавлен тип ускорителя для [PSCustomObject], что создает объектов с помощью упорядоченного хэш-таблицы, поэтому свойства остаются в порядке, они объявлены:

[PSCustomObject] @{ 
    Computer=$computer.hostname 
    App=$app.appname 
    Installed=$installed 
} 
+0

+1. Это интересно. Любые ссылки на документацию? – Neolisk

+0

Я не могу вспомнить, где я читал об этом. Это не было очевидно в документах MS, выпущенных с V3. Они также добавили ускоритель типа [упорядоченный] для создания упорядоченных хеш-таблиц, но вам не нужно использовать его с [PSCustomObject], он делает это автоматически. – mjolinor

+0

Полезно знать - я довольно новичок в V3. Спасибо, что ответили. – Neolisk

1

Format-Table это хорошее решение, когда вам нужно , чтобы отобразить ваших поля объекта в определенном порядке, но это изменит obect и вы не сможете трубы вашего объекта, например, при экспорте в CSV-файл (Export-Csv).

В случае, когда вы просто хотите изменить «порядок полей в объекте», используйте Select-Object.Это сохранит тип объекта и поля, и вы все равно сможете передать объект другим командлетам.

+1

Правильно! Ура! :) – Chiramisu

Смежные вопросы