Глава 8. Объекты: данные с другим названием

В этой главе мы намерены делать нечто слегка иное. Применение объектов в PowerShell может быть одним из самых запутанных элементов, но в то же самое время это одна из наиболее важных концепций его оболочки, влияющая на всё что вы осуществляете в данной оболочке. На протяжении многих лет мы пробовали различные объяснения и остановились паре, в которой каждое из них хорошо работает для совершенно разных аудиторий. Если у вас имеется опыт программирования и вы знакомы с понятием объектов, мы хотим чтобы вы перешли к Разделу 8.2. Если у вас нет опыта программирования и вы ранее не программировали объекты или не писали сценарии с ними, начинайте с Раздела 8.1 и прочтите всю главу.

Что такое объекты?

Потратьте секунду на запуск в PowerShell Get-Process. Вы должны обнаружить таблицу с несколькими столбцами, однако эти столбцы лишь малая часть всех доступных сведений о процессах. Каждый объект процесса также обладает названием машины, дескриптором главного окна, максимальным размером рабочего набора, кодом и временем выхода, информацию о родственности процессора и многое иное. Вы обнаружите более 60 фрагментов сведений, связанных с процессом. Почему PowerShell показывает так мало из общего числа?

Простой факт состоит в том, что большинство тех моментов, к которым PowerShell способен выполнять доступ предоставляют больше сведений, чем их может уместиться на вашем экране. Когда вы исполняете любую команду, такую как Get-Process, Get-AzVm или Get-AzStorageBlob, PowerShell строит - целиком в оперативной памяти - некую таблицу, которая содержит все необходимые сведения об этих элементах. Для Get-Process такая таблица состоит из чего- то порядка 67 столбцов, причём по одной строке для каждого процесса, которые запущены в вашем компьютере. Каждый столбец содержит единицу информации, такую как виртуальная память, загруженность ЦПУ, название процесса, идентификатор процесса и тому подобное. Затем PowerShell просматривает определили ли вы те столбцы, которые вы желаете просматривать. Если нет, ваша оболочка просматривает предоставляемый Microsoft файл конфигурации и отображает лишь те столбцы таблицы, которые Microsoft подразумевает для просмотра вами.

Один из вариантов просматривать все имеющиеся столбцы состоит в применении ConvertTo-Html:


Get-Process | ConvertTo-Html | Out-File processes.html
		

Этот командлет не заботится о фильтрации имеющихся столбцов. Вместо этого он производит некий файл HTML, который содержит их все. Это один из вариантов просмотреть их все.

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

Всякий раз когда вы запускаете команду, которая производит вывод, такой вывод получает форму таблицы в памяти. Когда вы переправляете вывод из одной команды в другую, например,


Get-Process | ConvertTo-Html
		

вся такая таблица передаётся через такой конвейер. Эта таблица не фильтруется до меньшего числа столбцов пока исполняется каждая из команд.

Теперь относительно некоторых изменений в терминологии. PowerShell не называет такую таблицу в оперативной памяти таблицей. Вместо этого он использует такие термины:

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

  • Свойство - это то, что мы называли столбцом таблицы. Оно представляет один фрагмент сведений относительно объекта, например, название процесса, идентификатор процесса, либо состояние исполняемой ВМ.

  • Метод - это то, на что мы ссылаемся как на некое действие. Метод относится к отдельному объекту и делает нечто с данным объектом - к примеру, уничтожает процесс, или запускает ВМ.

  • Коллекция - Это набор объектов целиком или то, что мы именовали таблицей.

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

 

Рисунок 8-1


Отображение того, что соответствующий объект (файл) обладает множеством свойств, например, Author и FileType.

Разбираемся зачем PowerShell пользуется объектами

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

Самая первая причина состоит в истории PowerShell, который ранее был только в Windows. Windows сама по себе выступает объектно- ориентированной операционной системой или, по крайней мере, бо́льшая часть работающего в Windows программного обеспечения является объектно- ориентированным. Выбрать структуру данных в виде набора объектов несложно, потому как основная часть самой операционной системы подходит для таких структур. Как оказалось, мы можем применять такой объектно- ориентированный подход к прочим операционным системам и даже к иным системам понятий, таким как облачные решения и DevOps.

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


PS /Users/travis> Get-Process
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     39       5     1876       4340    52    11.33   1920 Code
     31       4      792       2260    22     0.00   2460 Code
     29       4      828       2284    41     0.25   3192 Code
    574      12     1864       3896    43     1.30    316 pwsh
    181      13     5892       6348    59     9.14    356 ShipIt
    306      29    13936      18312   139     4.36   1300 storeaccountd
    125      15     2528       6048    37     0.17   1756 WifiAgent
   5159    7329    85052      86436   118     1.80   1356 WifiProxy
		

Что делать, если вы желаете сделать с этими сведениями что- то ещё? Возможно вы желаете внести изменения во все процессы, исполняющие Code. Для этого вам придётся слегка отфильтровать свой перечень. В UNIX или в Linux вы можете попытаться воспользоваться такой командой как grep (которую, между прочим, вы можете запускать в PowerShell), сообщая ей, "Просмотри для меня этот текст. Оставь лишь те строки, в которых столбцы 58- 64 содержат символы Code. Удали все прочие строки". Получаемый в результате список содержит те процессы, которые вы определили:


Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     39       5     1876       4340    52    11.33   1920 Code
     31       4      792       2260    22     0.00   2460 Code
     29       4      828       2284    41     0.25   3192 Code
 	   

Затем вы переправляете этот текст в иную команду, возможно, указывая ей выделить значение идентификатора процесса из своего списка. "Пройдись по этому и получи все символы из столбцов 52- 56, но отбрось две первые (заголовок) строки". Получаемый результат может быть таким:


1920
2460
3192
 	   

Наконец, вы переправляете этот текст в ещё иную команду, прося её уничтожать данные процессы (либо нечто ещё, что вы пытались сделать), представленные такими номерами идентификаторов.

Именно так ИТ профессионалы применяют работу bash. Они тратят уйму времени на изучение того как лучше выполнять синтаксический разбор текста; пользуются такими инструментами как grep, awk и sed; и превращаются в профессионалов использования регулярных выражений. Прохождение такого процесса обучения упрощает для них определение необходимых шаблонов текста, который они бы хотели чтобы их компьютер находил. В давние времена, когда PowerShell не был переносимым, ИТ профессионалы UNIX и Linux полагались бы на языки программирования сценариев, такие как Perl и Python, которые располагают бо́льшими возможностями для синтаксического анализа текста. Но такой текстовый подход создаёт ряд проблем:

  • Вы можете тратить больше времени на путаницу вокруг такого текста чем выполнять реальное задание.

  • Когда вывод команды изменяется - скажем, перемещая столбец ProcessName в самое начало вашей таблицы - вам приходится переписывать все свои команды, потому как все они зависят от таких моментов как позиции столбцов.

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

  • Такие языки программирования как Perl и Python это цельные языки программирования ... но также не являются оболочками.

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

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

[Совет]Не сердитесь

Между прочим, ничто из перечисленного выше не предназначено для углубления в Bash, Perl или Python. У каждого инструмента имеются свои плюсы и минусы. Python - отличный язык программирования общего назначения, который нашёл применение даже в области машинного обучения и искусственного интеллекта, но вы читаете данную книгу не для этого. Вы ищите нечто, что поможет вам превратиться в ИТ- профессионала, а PowerShell выступает для этого идеальным инструментом. {Прим. пер.: если желаете найти между ними баланс, предлагаем вам наш перевод PowerShell и Python сообща - настроены на цифровые расследования Чета Хосмера, Apress, 2019.}

Обнаружение объектов: Get-Member

Раз объекты подобны гигантской таблице в оперативной памяти, а PowerShell показывает на вашем экране лишь часть такой таблицы, как вы можете обнаружить с чем ещё вы способны поработать? Если вы полагаете, что вам следует воспользоваться командой Get-Help мы счастливы, ибо мы, вне всяких сомнений, впихивали это в вас в своих предыдущих главах. Но, к сожалению, вы ошибаетесь.

Имеющаяся система подсказок системы документирует лишь базовые понятия (в виде тем about) и синтаксис команд. Для получения дополнительных сведений об объекте вы пользуетесь другой командой: Get-Member. Вам должно быть комфортно применять данную команду - настолько, что вы начнёте искать более короткий способ её ввода. И мы предоставим вам его прямо сейчас: это псевдоним gm.

Вы можете пользоваться gm после любого командлета, который обычно производит вывод, вы уже знакомы с тем, что запуск Get-Process производит вывод на ваш экран. Вы можете переправить его в gm:


Get-Process | gm
		

всякий раз, когда некий командлет производит коллекцию объектов, как это делает Get-Process, вся эта коллекция остаётся доступной вплоть до окончания своего конвейера. Не раньше чем каждая команда выполнит это, PowerShell фильтрует получаемые столбцы отображаемых сведений и создаёт окончательный, наблюдаемый вами, текстовый вывод. Тем самым, в нашем предыдущем примере gm обладает полным доступом ко всем свойствам и методам объектов соответствующего процесса, поскольку они ещё не были отфильтрованы для отображения. gm просматривает каждый объект и создаёт перечень свойств и методов объектов. Это выглядит так:


PS C:\> Get-Process | gm
   TypeName: System.Diagnostics.Process
Name                       MemberType     Definition
----                       ----------     ----------
Handles                    AliasProperty  Handles = Handlecount
Name                       AliasProperty  Name = ProcessName
NPM                        AliasProperty  NPM = NonpagedSystemMemo...
PM                         AliasProperty  PM = PagedMemorySize
VM                         AliasProperty  VM = VirtualMemorySize
WS                         AliasProperty  WS = WorkingSet
Disposed                   Event          System.EventHandler Disp...
ErrorDataReceived          Event          System.Diagnostics.DataR...
Exited                     Event          System.EventHandler Exit...
OutputDataReceived         Event          System.Diagnostics.DataR...
BeginErrorReadLine         Method         System.Void BeginErrorRe...
BeginOutputReadLine        Method         System.Void BeginOutputR...
CancelErrorRead            Method         System.Void CancelErrorR...
CancelOutputRead           Method         System.Void CancelOutput...
		

Мы усекли свой предыдущий список по причине его длины, но, к счастью, он дал вам мысль.

[Совет]Попробуйте прямо сейчас

Не принимайте на веру наши слова. Сейчас самое время последовать им и запустить те же самые команды, которые исполняли мы, чтобы обнаружить их полный вывод.

Кстати, вам может быть интересно узнать, что все свойства, методы и прочие моменты, прикрепляемые к некому объекту, все они в совокупности носят название участников (членов, members), как если бы сам объект представлял собой загородный клуб, а все эти свойства и методы относились бы к этому клубу. Именно отсюда Get-Member и получил своё название - он получает перечень участников объекта. Но помните, поскольку соглашение PowerShell предусматривает применение существительного в единственном числе, название этого командлета Get-Member, а не Get-Members.

[Предостережение]Важно

На это запросто не обратить внимание, но отметьте для себя первую строку вывода Get-Member. Это TypeName, уникальное название, присвоенное данному конкретному типу объекта. Сейчас это может показаться не важным - в конце концов, какая разница какое название он носит? Но в следующей главе это станет критически важным.

Применение атрибутов объектов, или свойств

Когда вы изучаете вывод gm, вы заметите некоторые виды свойств:

  • ScriptProperty

  • Property

  • NoteProperty

  • AliasProperty

[Замечание]Дополнительно

Как правило, объекты в .NET - именно отсюда поступают все объекты PowerShell - обладают лишь свойствами. PowerShell динамически добавляет прочее наполнение: ScriptProperty, NoteProperty, AliasProperty и так далее. Когда вам придётся искать тип объекта в документации Microsoft (вы можете указать TypeName объекта в своей любимой поисковой системе чтобы найти необходимую страницу docs.microsoft.com), вы не обнаружите этих дополнительный свойств.

PowerShell обладает Расширяемой системой типов (ETS, extensible type system), которая отвечает за добавление таких свойств последней минуты. Почему так происходит? В некоторых случаях это делается для того, чтобы превратить объекты в более согласованные, например, добавить свойство Name к объектам, которые изначально обладают только чем- то вроде ProcessName (именно для этого предназначено свойство AliasProperty). Порой это делается для того, чтобы выставлять сведения, глубоко сокрытые в самом объекте (у объектов процесса имеется несколько свойств ScriptProperties, которые осуществляют это).

Когда вы в PowerShell, все эти свойства ведут себя одинаково. Но не удивляйтесь если они не появятся на странице официальной документации: часто для облегчения вашей жизни сама оболочка добавляет эти дополнительные сведения.

Для ваших целей эти свойства одинаковы. Единственное отличие состоит в том как изначально были созданы сами свойства, но это не то о чём стоит беспокоиться. Для вас всё это свойства, и вы будете пользоваться ими одинаково.

Свойство всегда содержит некое значение. Например, значением свойства ID объекта может быть 1234, а значение свойства Name может обладать значением Code. Свойства описывают нечто в объекте: его состояние, его идентификатор и тому подобное. В PowerShell свойства часто доступны только на чтение, что означает что вы не можете изменять значение названия службы присваивая новое значение его свойству Name. Однако вы можете выполнять выборку значения названия службы считывая его свойство Name. По нашим оценкам 90% того что вы будете делать в PowerShell будет связано со свойствами.

Применение действий объектов, или методов

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

Например, когда вам требуется прервать процесс, у вас имеются три способа выполнения этого. Один способ состоит в выборке необходимого объекта и затем каким- то образом выполнить его метод Kill. Другой способ состоит в применении пары командлетов:


Get-Process -Name Code | Stop-Process
		

Вы можете совершить это при помощи единственного командлета:


Stop-Process -Name Code
		

В данной книге мы целиком сосредоточимся на применении команд PowerShell для выполнения задач. Они обеспечивают самый простой, наиболее ориентированный на ИТ профессионалов в большинстве сосредоточенном на задачи способ осуществления вещей. Применение методов восходит к программированию .NET, которое может быть более сложным и требовать намного большего числа исходных сведений. По этой причине вы изредка - если вообще когда бы то ни было - столкнётесь в данной книге с тем как мы выполняем метод объекта. Наша общая философия на данный момент такова: "Если вы можете выполнить это при помощи командлета, отступите и воспользуйтесь графическим интерфейсом". Мы обещаем вам, что вы не будете ощущать себя так на протяжении всей своей карьеры, но на данный момент это достойный способ сосредоточиться на "пути PowerShell".

[Замечание]Дополнительно

Вам нет нужды знать обо всём этом на данном этапе вашего обучения PowerShell, однако дополнительно к свойствам и методам, объекты также могут обладать событиями. Некое событие (event) это тот способ, которым объекты уведомляют что для него что- то произошло. Объект процесса, например, может переключать своё событие Exited по завершению данного процесса. Вы можете подключать свои собственные команды к таким событиям с тем, например, чтобы отправлялось некое электронное письмо при выходе процесса. Работа с событиями таким образом это некая продвинутая тема, которая выходит за рамки данной книги.

Сортировка объектов

Большинство командлетов PowerShell производят неким предопределённым образом, что означает, что они обладают тенденцией производить объекты в том же самом порядке при каждом запуске соответствующей команды. И ВМ и процессы Azure, скажем, перечисляются в алфавитном порядке названий. Что если мы изменим это?

Допустим, вы хотите отобразить список процессов с наибольшей загруженностью ЦПУ в самом верху этого списка и с наименьшими потреблениями в нижней части. Нам потребуется неким образом изменить порядок этого списка на основе значения свойства CPU. PowerShell предоставляет простой командлет, Sort-Object, который осуществляет именно это:


Get-Process | Sort-Object -Property CPU
		
[Совет]Попробуйте прямо сейчас

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

Данная команда не совсем то чего бы мы хотели. Она и в самом деле сортирует по ЦПУ, однако выполняет это в нисходящем порядке, когда наибольшие значения располагаются внизу. Прочитав подсказку для Sort-Object, мы видим, что она обладает параметром -Descending, который должен изменять порядок сортировки. Мы также замечаем, что наш параметр -Property позиционный, а потому нам не требуется набирать название этого параметра.

Мы сокращаем -Descending до -desc и мы получаем тот результат, который желали. Наш параметр -Property получает несколько значений (мы уверены что вы обратили внимание на это в соответствующем файле подсказки, если вы заглядывали в него).

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


Get-Process | Sort-Object CPU,ID -desc
		

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

Выбор нужных свойств

Другим полезным командлетом является Select-Object. Она принимает из своего конвейера объекты и вы можете определять те свойства, которые вы желаете отображать. Это делает возможным выполнять доступ к свойствам, которые обычно фильтруются правилами конфигурации PowerShell, либо обрезать этот список до нескольких интересующих вас свойств. Это может быть полезным при передаче объектов в ConvertTo-HTML, поскольку данный командлет обычно строит таблицу, содержащую все свойства. Сравним получаемые в следующих двух командах результаты:


Get-Process | ConvertTo-HTML | Out-File test1.html
Get-Process | Select-Object -Property Name,ID,CPU,PM | ConvertTo-Html | 
➥ Out-File test2.html
		
[Совет]Попробуйте прямо сейчас

Проследуйте далее и запустите каждую из этих команд по- отдельности, а затем изучите получаемые в результате файлы HTML в веб браузере чтобы увидеть отличия.

Взгляните на подсказку для Select-Object (либо можете воспользоваться её псевдонимом, Select). Наш параметр -Property позиционный, что означает, что мы имеем возможность сократить свою последнюю команду:


Get-Process | Select Name,ID,CPU,PM | ConvertTo-HTML | Out-File test3.html
		

Потратьте какое- то время на эксперименты с Select-Object. Испробуйте варианты следующей команды, которая позволяет появляться выводу на вашем экране:


Get-Process | Select Name,ID,CPU,PM
		

Попробуйте добавлять и удалять различные свойства объекта процесса из данного списка и повторно просматривайте получаемые результаты. Сколько свойств вы можете определять и всё ещё получать в виде вывода таблицу?

[Замечание]Дополнительно

Select-Object также обладает параметрами -First и -Last, которые позволяют вам оставлять в соответствующем конвейере некое подмножество получаемых объектов. Например, Get-Process | Select -First 10 оставляет самые первые 10 объектов. Нет никаких критериев, таких как сохранение определённых процессов; это просто захват первых (или последних) 10.

[Предостережение]Предостережение

Люди часто путают две команды PowerShell: Select-Object и Where-Object, которую вы пока не видели. Select-Object используется для выбора свойств (или столбцов), которые вы хотите наблюдать, а также способна выбирать произвольное подмножество выходных строк (при помощи -First и -Last). Where-Object удаляет или фильтрует объекты из своего конвейера на основании указываемых вами критериев.

Объекты до самого конца

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

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


Get-Process |
Sort-Object CPU -Descending |
Out-File c:\procs.txt
		

В этом примере мы начинаем с запуска Get-Process, которая помещает объекты процессов в общий конвейер. Нашей следующей командой выступает Sort-Object. Она не изменяет чего бы то ни было в своём конвейере; она изменяет лишь установленный порядок его объектов, а потому по окончанию Sort-Object, на конвейер всё ещё содержит процессы. Самой последней командой является Out-File. Здесь PowerShell должен производить вывод, а потому он берёт то что имеется в её конвейере - процессы - и форматирует их в соответствии с её настройками внутренних правил. Получаемые результаты поступают в предписанный файл. Далее идёт более сложный пример:


Get-Process |
Sort-Object CPU -Descending |
Select-Object Name,ID,CPU
		

Он стартует аналогично. Get-Process помещает объекты процессов в свой конвейер. Они следуют в Sort-Object, которая сортирует их и помещает те же самые объекты процессов в свой конвейер. Однако Select-Object работает слегка иначе. Объект процесса всегда обладает теми же самыми участниками. Для усечения имеющегося списка свойств Select-Object не способен удалять те свойства которые вам не нужны, поскольку получаемый результат вовсе не был бы объектом процесса. Вместо этого Select-Object создаёт некий новый вид пользовательского объекта с названием PSObject. Он копирует те свойства, которые вам нужны от данного процесса, в результате приводя к тому, что в наш конвейер помещается некий индивидуальный объект.

[Совет]Попробуйте прямо сейчас

Попробуйте выполнить командную строку с тремя командлетами, имея в виду что вы вам следует набирать ею целиком в одной строке. Обратили внимание на то, что получаемый вывод отличается от обычного вывода Get-Process?

Когда PowerShell обнаруживает, что он достиг конца своей командной строки, ему приходится решить как располагать свой текстовый вывод. Поскольку в нашем конвейере больше нет никаких объектов процессов, PowerShell не будет применять установленные по умолчанию правила и конфигурации, которые применяются к объектам процессов. Вместо этого он ищет правила и конфигурации для PSObject, который и содержит в данный момент его конвейер. Microsoft не предоставляет никаких правил для PSObjects, поскольку подразумевается их применение для индивидуального вывода. Вместо этого PowerShell делает всё возможное и создаёт таблицу, исходя из той теории, что эти три фрагмента сведений, скорее всего, по- прежнему поместятся в таблице. Однако получаемая таблица выглядит не столь хорошо, как обычный вывод Get-Process, потому как в оболочке отсутствуют дополнительные сведения о необходимой для создания более привлекательной таблицы конфигурации.

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


Get-Process | Sort-Object CPU -Descending | gm
Get-Process | Sort-Object CPU -Descending | Select Name,ID,CPU | gm
		
[Совет]Попробуйте прямо сейчас

Попробуйте выполнить эти две командные строки по отдельности и обратите внимание на получаемое отличие в их выводах.

Заметьте, что как часть вывода gm, PowerShell отображает вам значение названия типа для того объекта, который он наблюдает в своём конвейере. В нашем первом случае это System.Diagnostics.Process, однако во второй ситуации наш конвейер содержит различные виды объектов. Эти новые отобранные объекты содержат только три заданных свойства - Name, ID и CPU - плюс пару созданных системой участников.

Даже gm производит объекты и помещает их в свой конвейер. После исполнения gm имеющийся конвейер более не содержит никаких процессов или отобранных объектов; он содержит значение типа производимых gm объектов: Microsoft.PowerShell.Commands.MemberDefinition. Вы можете убедиться в этом передавая получаемый в gm вывод в саму gm:


Get-Process | gm | gm
		
[Совет]Попробуйте прямо сейчас

Вы несомненно пожелаете испробовать это и хорошо продумайте чтобы быть уверенным что это имеет смысл для вас. Вы начинаете с Get-Process, который помещает объекты процессов в конвейер. Они следуют в gm, который анализирует их и создаёт свои собственные объекты MemberDefinition. Далее они передаются в gm, который анализирует их и выдаёт выходные данные со списком участников каждого объекта MemberDefinition.

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

Общие моменты путаницы

Новички, как правило, совершают несколько распространённых ошибок, когда приступают к работе с PowerShell. Большинство из них проходит при некотором опыте, но мы обращаем на них внимание при помощи следующего списка, чтобы дать вам возможность ловить себя, если вы начинаете идти по неверному пути.

  • Помните что файлы подсказок PowerShell не содержат сведений по свойствам объектов. Для просмотра списка свойств вам придётся передавать эти объекты в gm (Get-Member).

  • Помните, что вы можете добавлять gm в самый конец любого конвейера, который обычно производит результаты. Такая командная строка как Get-Process -Name Code | Stop-Process обычно не производят результатов, поэтому помещение | gm в её конец не произведёт ничего.

  • Уделяйте внимание аккуратному набору. Помещайте пробел с каждой из сторон символа конвейера, поскольку ваша командная строка должна читаться как Get-Process | gm, а не Get-Process|gm. По какой- то причине эта клавиша пробелом чрезвычайно велика - пользуйтесь ею.

  • Помните что ваш конвейер может содержать различные типы объектов на каждом из этапов. Думайте о том какой тип объекта пребывает в вашем конвейере и сосредотачивайтесь на том, что именно будет делать ваша следующая команда с этим типом объекта.

Лабораторные занятия

[Замечание]Замечание

Для данного лабораторного занятия вам требуется компьютер с исполняемым PowerShell v7 или последующим.

Данная глава, вероятно охватила больше, причём более сложных, новых понятий, нежели любая иная глава до сих пор. Мы надеемся, что вы смогли во всём этом и что данные упражнения помогут вам закрепить полученные знания. Лабораторная работа может быть более сложной чем предыдущие, но мы бы хотели чтобы вы привыкли выяснять какие именно команды применять и полагаться на get-command и help, а не на нас, для нахождения верной команды. В конце концом, именно этим вы и будете заниматься, как только приступите к работе с PowerShell над своими заданиями и столкнётесь со всевозможными ситуациями, которые мы не рассматривали в этой книге. Некоторые из таких задач основаны на навыках ,которые вы освоили в предыдущих главах чтобы освежить вашу память и удерживать вас в тонусе:

  1. Укажите командлет, который производит случайные числа.

  2. Укажите командлет, который отображает текущую дату и время.

  3. Какой тип объекта производит командлет из задачи 2? (Какой TypeName того объекта, который производит этот командлет?)

  4. Применяя командлет из задачи 2 и Select-Object отобразите только текущий день недели в таблице, подобной приводимой ниже (предостережение: получаемый вывод выравнивается справа, поэтому убедитесь что ваше окно PowerShell не обладает полосой горизонтальной прокрутки):

    
    DayOfWeek
    ---------
       Monday
     	   
  5. Укажите командлет, который отобразит вам все значения времён в неком каталоге.

  6. Применяя командлет из задачи 5, отобразите все значения времён в своём каталоге по выбору. Затем расширьте это выражение до сортировки получаемого списка по их времени тех элементов, которые были созданы и отобразите только их название файла (файлов) и значение даты создания. Помните, что значения заголовков столбцов, показываемые в установленном по умолчанию выводе командные обязательно значения реальных названий свойств - чтобы быть уверенным, вам придётся отыскать значения действительных названий свойств.

  7. Повторите задачу 6, но на этот раз отсортируйте получаемые элементы по времени последней записи; затем отобразите его название файла, время создания и значение времени последней записи. Сохраните это в файле CSV и в файле HTML.

Ответы лабораторных занятий

  1. Get-Random

  2. Get-Date

  3. System.DateTime

  4. Get-Date | select DayofWeek

  5. Get-ChildItem

  6. Get-ChildItem | Sort-Object CreationTime | Select-Object

    ➥ Name,CreationTime

  7. Get-ChildItem | Sort-Object LastWritetime | Select-Object

    ➥ Name,LastWritetime,CreationTime | Export-CSV files.csv

    Get-ChildItem | Sort-Object LastWritetime | Select-Object

    ➥ Name,LastWritetime,CreationTime | Out-file files.html