Командлет Out-GridView можно использовать как универсальный диалоговый интерфейс, для этого предназначены параметры -OutputMode и -PassThru. С ними окно табличного представления (грид) отображает справа внизу дополнительные кнопки, и вы можете передать следующим командлетам выбранные строки.

Например, остановить выбранный сервис можно было бы так:

Get-Service | Where-Object CanStop | Out-GridView -Title 'Service to stop?' -OutputMode Single | Stop-Service -WhatIf 

Однако, командлет Out-GridView не даёт возможности управлять набором свойств, которые он показывает. В этом примере нам нужно видеть только название сервиса и, возможно, зависимые от него сервисы.

Да, чтобы выбрать свойства для отображения, можно воспользоваться командлетом Select-Object. Теперь грид покажет в точности запрошенные столбцы, но следующие командлеты могут сломаться, потому что вы выкинули прочие свойства и вообще поменяли тип объекта:

Get-Service | Where-Object CanStop | Select-Object -Property DisplayName, DependentServices | Out-GridView -Title 'Service to stop?' -OutputMode Single | Stop-Service -WhatIf 

Теперь грид выглядит нужным образом, но командлет Stop-Service не сможет остановить сервис потому, что командлет Select-Object изменил тип объекта, и тот перестал быть сервисом:


Stop-Service : The specified wildcard character pattern is not valid: @{DisplayName=Windows Audio Endpoint Builder; 
DependentServices=System.ServiceProcess.ServiceController[]}

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

# create object that tells PowerShell which column(s) should be visible:
# show "DisplayName", and "DependentServices"
[string[]]$visible = 'DisplayName', 'DependentServices'
$type = 'DefaultDisplayPropertySet'
[System.Management.Automation.PSMemberInfo[]]$info = 
    [System.Management.Automation.PSPropertySet]::new($type,$visible)


Get-Service | 
    Where-Object CanStop | 
    
    # add the secret object to each object that you pipe into Out-GridView:
    Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $info -PassThru |
    Out-GridView -Title 'Service to stop?' -OutputMode Single | 
    Stop-Service -WhatIf

Но и тут возможен облом c красными сообщениями об ошибках. Некоторые объекты PowerShell (например, сервисы) сами реализованы через трюк с добавлением свойства PSStandardMembers, так что мы не можем его добавить второй раз. Чтобы обойти это препятствие, просто клонируйте объекты, пропустив их через командлет Select-Object *:

# create object that tells PowerShell which column(s) should be visible:
# show "DisplayName", and "DependentServices"
[string[]]$visible = 'DisplayName', 'DependentServices'
$type = 'DefaultDisplayPropertySet'
[System.Management.Automation.PSMemberInfo[]]$info = 
    [System.Management.Automation.PSPropertySet]::new($type,$visible)


Get-Service | 
    Where-Object CanStop | 
    # clone the objects so they now belong to you:
    Select-Object -Property * |
    
    # add the secret object to each object that you pipe into Out-GridView:
    Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $info -PassThru |
    Out-GridView -Title 'Service to stop?' -OutputMode Single | 
    Stop-Service -WhatIf

Теперь всё опять работает, и Out-GridView показывает только выбранные свойства. При этом, Stop-Process по-прежнему понимает его выдачу и останавливает выбранный сервис (для этого уберите -WhatIf и убедитесь в наличии админстративных привилегий).

Хотя пропускание объектов через Select-Object изменяет их тип, большинство последующих командлетов этого не замечает, потому что прилетевшие им объекты содержат все свойства оригинала. Вот последняя иллюстрация: хотя командлет Out-GridView и показывает только выбранные свойства, объекты состоят из полного комплекта свойств:

# create object that tells PowerShell which column(s) should be visible:
# show "Name", "Description" and "MainWindowTitle"
[string[]]$visible = 'Name', 'Description', 'MainWindowTitle'
$type = 'DefaultDisplayPropertySet'
[System.Management.Automation.PSMemberInfo[]]$info =  
    [System.Management.Automation.PSPropertySet]::new($type,$visible)


Get-Process | 
    Where-Object MainWindowTitle | 
    Sort-Object -Property Name |
    # clone the objects so they now belong to you:
    Select-Object -Property * |
    
    # add the secret object to each object that you pipe into Out-GridView:
    Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $info -PassThru |
    Out-GridView -Title 'Select a process' -OutputMode Single |
    # still all properties available:
    Select-Object -Property *

Комментарии (0)