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

PowerShell in Depth

Глава 21.1 Техника номер 1. Использование хеш таблиц для создания кастомных объектов.

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

# Собираем какието данные, в последующем нам нужно это скомпоновать и вывести
$os = Get-WmiObject –Class Win32_OperatingSystem –comp localhost
$cs = Get-WmiObject –Class Win32_ComputerSystem –comp localhost
$bios = Get-WmiObject –Class Win32_BIOS –comp localhost
$proc = Get-WmiObject –Class Win32_Processor –comp localhost |
Select –First 1

# Хэш таблица. Описывает свойства будущего объекта
$props = @{OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}

# Создаем объект из хэш таблицы и выводим
$obj = New-Object –TypeName PSObject –Property $props
Write-Output $obj


выполнив этот код вы получите результат подобный этому:

Manufacturer : Microsoft Corporation
OSVersion : 6.3.9600
OSArchitecture : 64-bit
BIOSSerial : 036685734653
ComputerName : RSSURFACEPRO2
Model : Surface Pro 2
ProcArchitecture : 64


Т.к. на выходе у вас объект имеющий более четырех свойств PowerShell сделал вывод на экран в виде списка. Вы могли бы выполнить

Write-Output $obj | ft


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

Manufacturer=$cs.manufacturer


Если поместить записи хэш-таблицы на одной строке, вам нужно будет отделить каждое свойство точкой с запятой. Если поместить каждое свойство на отдельной строке, вам не нужна точка с запятой, вам намного легче читать и править код.
Скобки с прешедствующим им знаком @ говорят что далее начинается хэш-таблица. Т.к. таблица находится в переменной $props ее легко передать в параметрах -property нового объекта. Объект PSObject специально предусмотрен для этих целей.

Преимущество этого подхода в том что легко построить хэш таблицу на лету и создать из нее много пользовательских объектов. Вы можете заметить что в выходном объекте свойства имеют не тот же самый порядок как они были определены в таблице. Одно из возможных решений — создать форматирование для кастомного объекта (специальный XML файл описывающий как выводить на экран, в каком порядке и т.п.) или, если вы используете powershell 3 и выше, то можно использовать свойство ordered

$props = [ordered]@{ OSVersion=$os.version
Model=$cs.model
Manufacturer=$cs.manufacturer
BIOSSerial=$bios.serialnumber
ComputerName=$os.CSName
OSArchitecture=$os.osarchitecture
ProcArchitecture=$proc.addresswidth}


Все остальное тоже самое. Теперь свойства объекта будут отображаться в том порядке как они были записаны. Если вы передадите $obj на Get-Member, вы увидете что это PS-CustomObject.

Примечание PowerShell по умолчанию не отслеживает порядок элементов в хэш таблице. Вот почему когда вы видете окончательный вывод его свойства идут не в том порядке в каком вы их создавали. Начиная с PowerShell 3 вы можете исправить это использовав атрибут [ordered]. Это создает упорядоченный словарь (другое название хэш таблиц) и поддерживает порядок элементов в ней.

Добавлю от себя.
Действительно этот способ очень удобен: легко читаем, легко править. Этот способ широко используется в PowerShell — от создания параметров для отправки письма по SMTP, для объединения в один объект информации для вывода из функции или скрипта.

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



  1. gotch
    02.03.2016 16:43

    Будем брать на вооружение


    1. pak-nikolai
      02.03.2016 19:01
      +1

      это кусок 20 главы, по идее надо все перевести. Материал полу теоретический, как собрать в один объект вывод, почему надо выводить объектами и как. Если интересно могу сделать. Хотя бы часть как правильно делать вывод из функции. Искал материал потому что в рунете больше половины устаревшей информации с первых двух версий пошика. Очень неудобно и не объясняется как надо и почему.


      1. padla2k
        02.03.2016 20:34

        Если интересно могу сделать.

        Интересно. Сделайте, пожалуйста.


  1. rbobot
    02.03.2016 19:19

    Глянь мой последний пост ;-)


  1. kuda78
    03.03.2016 08:40

    Если уж создавать объекты, то и методы надо добавлять:

    function ServicesDbUtils($connectionString)
    {
        $result = New-Object -Typename PSObject -Property `
        @{
            ConnectionString = $connectionString
        }
    
        Add-Member -InputObject $result -MemberType ScriptMethod -Name ConnectionOpen -Value `
        {
            $conn = New-Object System.Data.SqlClient.SQLConnection
            #....
            return $conn
        }
    
        Add-Member -InputObject $result -MemberType ScriptMethod -Name UpdateFormatParamSet -Value `
        {
            Param($name, $title, ...)
            $conn = $this.ConnectionOpen()
            #....
        }
    
        return $result
    }
    
    $ServiceDbUtils = ServicesDbUtils -connectionString "Server=PORT-EXT-DB02;Database=EecService;Integrated Security=True"
    $ServiceDbUtils.UpdateFormatParamSet('...', '...', ...)


    1. pak-nikolai
      03.03.2016 09:40

      Суть статьи в том как правильно сделать в PoSh объект для передачи дальше по конвееру, на большее она и не претендует. Я думаю для создания "тяжелых" объектов, сложной автоматизации существуют другие языки и способы. В повершелле даже конструкции типа for не рекомендуются не говоря о классах. Если нужно чтото сложнее лучше взять C# и потом приделать к нему обертку в виде повершелла. Хотя в 5й версии классы и прикрутили, посмотрим что получится.

      Я рассматриваю пошик в качестве языка для админов.
      Он должен:
      А) быть максимально понятным и коротким,
      Б) обеспечивать унификацию и возможность передачи от сервера к серверу через сеть. (методы при передаче кстати обрежутся)
      Отсюда и несколько необычный стиль PowerShell, отсюда и требование собирать все вывод в один кастомный объект для передачи дальше по конвееру, отсюда и рекомендация не использовать return.

      Я так смотрю, потому что так его использую. В русле пути Дон Джонса и Сиддэвэя. Если мне нужны объекты я обычно использую не скриптовый язык. Зато в качестве ежедневных админских задач повершелл очень хорош!

      З.Ы. также перевод делался из за того что в ру зоне нужно больше материала, в том числе и теоритического.


      1. padla2k
        04.03.2016 13:39

        По вашей наводке скачал эту книгу… буду знакомиться.


        1. pak-nikolai
          04.03.2016 14:18

          по мере чтения книги Вам будет что то нравится, напишите какие главы и куски, может переведу и выложу в общий доступ. Вы увидите еще что то, чего не вижу я


          1. padla2k
            04.03.2016 14:30

            Постараюсь.