Get-Module-ListAvailable: Почему или как модули печатаются в разделах, разделенных по каталогам?

0

Вопрос

Когда я сделаю "Get-Module-ListAvailable", powershell напечатает 169 модулей. Например:

    Directory: C:\Program Files (x86)\Microsoft SQL Server\150\Tools\PowerShell\Modules


ModuleType Version    Name                                ExportedCommands                                                               
---------- -------    ----                                ----------------                                                               
Manifest   15.0       SQLPS                               {Backup-SqlDatabase, Save-SqlMigrationReport, Invoke-PolicyEvaluation, Resto...


    Directory: C:\Users\user\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands                                                               
---------- -------    ----                                ----------------                                                               
Script     3.0.1      DotNetVersionLister                 Get-STDotNetVersion                                                            
Script     1.4.7      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}         
Script     2.2.5      PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}          
Script     2.2.16     VSSetup                             {Get-VSSetupInstance, Select-VSSetupInstance}                                  


    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands                                                               
---------- -------    ----                                ----------------                                                               
Script     1.3.1      Configuration                       {Import-Configuration, Export-Configuration, Get-StoragePath, Add-MetadataCo...

Когда я записываю это в массив: "$m = Get-Module-ListAvailable" Это похоже на простой массив, но он также печатается в этих разделах.

Как это делается?

Похоже, что в объектах PSModuleInfo даже нет свойства "Каталог".

powershell
2021-11-23 19:46:21
2

Лучший ответ

4

Powershell имеет свой собственный механизм форматирования. Всякий раз, когда вы используете этот командлет, вы выводите список System.Management.Automation.PSModuleInfo Объекты.

Перед печатью объекта "необработанный" Powershell проверяет, доступно ли для этого типа предопределенное форматирование, и если да, то примените его. То, что вы видите, является результатом этой трансформации.

До PS 5.1 это делалось с помощью файла конфигурации форматирования, определенного как файлы *.ps1xml. Начиная с PS6.0 и более новых, предопределенные форматы теперь включены непосредственно в исходный код, но вы все равно можете создавать дополнительные файлы формата по мере необходимости.

Вы можете просмотреть тип загруженного формата, используя Get-FormatData командлет.

Если вы заинтересованы в Get-Module в частности, командлет, проверьте (Get-FormatData -TypeName System.Management.Automation.PSModuleInfo).FormatViewDefinition. Вы увидите что-то вроде этого:

Name   Control
----   -------
Module System.Management.Automation.TableControl
Module System.Management.Automation.WideControl
Module System.Management.Automation.ListControl

Это означает, что у любых объектов этого типа есть специальные инструкции относительно того, как он должен выводить свой объект. В этом случае он включает группировку по пути и отображение определенных столбцов (Тип модуля, Версия, Имя, экспортируемые команды). Powershell не решил отображать эти свойства сам по себе, он получил инструкции от предопределенного типа о том, что отображать.

В случае с PSModuleInfo тип, мы видим, что для этого типа существует 3 пользовательских представления. Один для представления таблицы (который отображается по умолчанию), один для списка и широкого, которые указывают, что показывать при использовании Format-List & Format-Wide.

От MS doc

Формат отображения объектов, возвращаемых командами (командлеты, функции и сценарии), определяется с помощью файлов форматирования (файлы формата.ps1xml). Некоторые из этих файлов предоставлены PowerShell, чтобы определить формат отображения для этих объектов, возвращаемых Команды, предоставляемые PowerShell, такие как Система.Диагностика. Объект процесса, возвращаемый командлетом Get-Process. Однако вы также можете создать свои собственные файлы пользовательского форматирования, чтобы перезаписать форматы отображения по умолчанию, или вы можете написать файл пользовательского форматирования, чтобы определить отображение объектов, возвращаемых вашими собственными командами.

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

Вы можете создавать свои собственные файлы (*.ps1xml) и включать их в свои модули или загружать в свои сеансы, чтобы изменить способ отображения выходных данных.

Вы также можете добавить форматирование к выводу ваших функций, определив набор отображения по умолчанию (он же, какие свойства должны отображаться).

Например, возьмем эту простую функцию:


  Function Get-EmployeesInfos() {
    $Output = @(
        
        [PSCustomObject]@{
            FirstName            = 'RObert'
            LastName             = 'Samson'
            SocialSecurityNumber = '123 344 555'
            Age                  = '32'
            Salary               = '100000'
        },
        
        [PSCustomObject]@{
            FirstName            = 'Pablo'
            LastName             = 'Morrison'
            SocialSecurityNumber = '123 345 555'
            Age                  = '22'
            Salary               = '10000'
        }


    )
    
    # Default display set
    $defaultDisplaySet = 'FirstName', 'LastName'
    $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultDisplaySet)
    $Output | Add-Member MemberSet PSStandardMembers ([System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)) -Force
    return $Output


    return $Output
  }

Без какого-либо набора отображения по умолчанию вы получите стандартный вывод со всеми перечисленными свойствами.

enter image description here

С добавлением набора отображения по умолчанию, вот новый вывод.

enter image description here

Оба вывода действительно содержат одну и ту же информацию, но к консоли применено специальное форматирование, чтобы показывать только то, что наиболее важно, полезно и т.д...

Вы можете использовать представления форматирования для:

  • Раскрасить вывод
  • Создавайте деревья
  • Измените вывод на основе условия
  • Добавление виртуальных свойств
  • определите ширину столбца
  • определите заголовок отображаемого столбца
  • и т.д...

Список литературы:

Обзор файлов форматирования

4Sysops - Вывод объекта форматирования в Powershell с файлами формата.ps1xml

Обновление-Формат данных

2021-11-24 00:29:40
1

Причина в том, что Get-Module показывает результат в группах, потому что это формат по умолчанию для Module объекты всякий раз, когда PowerShell показывает их пользователю. Это не является специфической особенностью Get-Module командлет как таковой.

В целом это удобное средство, поскольку затем вы можете использовать такие командлеты, как Sort-Object и Where-Object для сортировки и фильтрации результатов, а затем для отображения результатов в группах.

В следующем примере результаты фильтруются, а затем отображаются в группах. Значение заключается в том, что ни Get-Module ни Where-Object осознает, что конечный результат будет отображаться в группах; они просто имеют дело с объектами.

PS> Get-Module -ListAvailable | Where-Object Name -Match Read

    Directory: C:\program files\powershell\7\Modules

ModuleType Version    PreRelease Name
---------- -------    ---------- ----
Script     2.1.0                 PSReadLine                          ...
Binary     2.0.3                 ThreadJob                           ...

    Directory: C:\Program Files\WindowsPowerShell\Modules

ModuleType Version    PreRelease Name
---------- -------    ---------- ----
Script     2.0.0      beta2      PSReadline                          ...

Вы можете увидеть, что делает PowerShell в этом конкретном случае, посмотрев код форматирования по умолчанию для модулей на GitHub. Соответствующей частью является GroupByScriptBlock вызов (с незначительным переформатированием для уменьшения длины линии):

yield return new FormatViewDefinition("Module",
    TableControl.Create()
        .GroupByScriptBlock(@"
            Split-Path -Parent $_.Path | ForEach-Object {
                if([Version]::TryParse((Split-Path $_ -Leaf), [ref]$null)) {
                    Split-Path -Parent $_
                } else {
                    $_
                }
            } | Split-Path -Parent", customControl: sharedControls[0])
        .AddHeader(Alignment.Left, width: 10)

        ...

Когда PowerShell покажет массив объектов модуля пользователю в формате по умолчанию, он запустит блок сценария в GroupByScriptBlock на каждом объекте сначала отрабатывается группировка.

2021-11-23 21:29:07

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................