Фильтрация свойств объектов в PowerShell


Оглавление

1. Для чего нужен командлет Select-Object

2. Опции Select-Object

3. Примеры использования Select-Object

4. Что выбрать для использования Select-Object или Format-Table


В данной заметке будет рассмотрена, как показать определённый свойства одного или нескольких объектов. Для этого используется командлет Select-Object. Для того чтобы отобрать только те объекты, одно или несколько свойств которого соответствуют заданным условиям, используется командлет Where-Object, он будет рассмотрен в другой статье. Также командлет Select-Object имеет много общего с Format-Table — мы рассмотрим, что у них общего, какие различия и какой из них нужно выбрать в той или иной ситуации.

Для чего нужен командлет Select-Object

Командлет Select-Object выбирает указанные свойства объекта или набора объектов. Он также может выбирать уникальные объекты, указанное количество объектов или объекты в указанной позиции в массиве.

Чтобы выбрать объекты из коллекции, используйте параметры -First, -Last, -Unique, -Skip и -Index. Чтобы выбрать свойства объекта, используйте параметр -Property. При выборе свойств командлет Select-Object возвращает новые объекты, имеющие только указанные свойства.

Начиная с Windows PowerShell 3.0 командлет Select-Object включает функцию оптимизации, которая не позволяет командам создавать и обрабатывать объекты, которые не используются. Когда вы включаете команду Select-Object с параметрами -First или -Index в конвейер команд, PowerShell останавливает команду, которая создаёт объекты, как только создаётся выбранное количество объектов, даже если команда, которая создаёт объекты, появляется перед командой Select-Object в конвейере. Чтобы отключить это поведение оптимизации, используйте параметр -Wait.

Опции Select-Object

-ExcludeProperty

Указывает свойства, которые этот командлет исключает из операции. Подстановочные знаки разрешены.

Начиная с PowerShell 6, для работы -ExcludeProperty больше не требуется включать параметр -Property.


-ExpandProperty

Если указанное свойство является массивом, каждое значение массива включается в выходные данные.

Если указанное свойство является объектом, свойства объектов раскрываются для каждого объекта InputObject.

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

Если указан параметр -Property, командлет Select-Object пытается добавить каждое выбранное свойство в качестве NoteProperty к каждому выводимому объекту.

Предупреждение: Если вы получаете сообщение об ошибке, что свойство не может быть обработано, так как свойство с таким именем уже существует, рассмотрите следующее. Обратите внимание, что при использовании -ExpandProperty командлет Select-Object не может заменить существующее свойство. Это означает:

  • Если развёрнутый объект имеет свойство с таким же именем, команда возвращает ошибку.
  • Если выбранный объект имеет свойство с тем же именем, что и свойство развёрнутого объекта, команда возвращает ошибку.

-First

Указывает количество объектов, которые необходимо выбрать в начале массива входных объектов.

-Index

Выбирает объекты из массива на основе значений их индексов. Введите индексы в список через запятую. Индексы в массиве начинаются с 0, где 0 представляет первое значение, а (n-1) представляет последнее значение.

-InputObject

Указывает объекты для отправки командлету через конвейер. Этот параметр позволяет направлять объекты в Select-Object.

Когда вы передаёте объекты параметру -InputObject, вместо использования конвейера командлет Select-Object обрабатывает -InputObject как отдельный объект, даже если значение является коллекцией. Рекомендуется использовать конвейер при передаче коллекций в Select-Object.

-Last

Указывает количество объектов, которые нужно выбрать из конца массива входных объектов.

-Property

Задаёт свойства для выбора. Эти свойства добавляются как члены NoteProperty к выходным объектам. Подстановочные знаки разрешены.

Значение параметра -Property может быть новым вычисляемым свойством. Чтобы создать вычисляемое свойство, используйте хеш-таблицу.

Действительные ключи:

  • Name (или Label) - <строка>
  • Expression - <строка> или <блок скрипта>

-Skip

Пропускает (не выбирает) указанное количество элементов. По умолчанию параметр -Skip ведёт отсчёт с начала массива или списка объектов, но если в команде используется параметр -Last, он отсчитывается с конца списка или массива.

В отличие от параметра -Index, который начинает отсчёт с 0, параметр -Skip начинается с 1.

-SkipLast

Пропускает (не выбирает) указанное количество элементов с конца списка или массива. Работает так же, как использование -Skip вместе с параметром -Last.

В отличие от параметра -Index, который начинает отсчёт с 0, параметр -SkipLast начинается с 1.

-Unique

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

-Unique выбирает значения после применения других параметров фильтрации.

Этот параметр чувствителен к регистру. В результате строки, отличающиеся только регистром символов, считаются уникальными (то есть разными).

-Wait

Указывает, что командлет отключает оптимизацию. PowerShell запускает команды в том порядке, в котором они появляются в конвейере команд, и позволяет им создавать все объекты. По умолчанию, если вы включаете команду Select-Object с параметрами -First или -Index в конвейер команд, PowerShell останавливает команду, которая создаёт объекты, как только создаётся выбранное количество объектов.

Этот параметр появился в Windows PowerShell 3.0.

Примеры использования Select-Object

Пример 1: Выбор объектов по свойству

В этом примере создаются объекты, обладающие свойствами Name, ID и рабочего набора (WS) объектов процесса.

Get-Process | Select-Object -Property ProcessName, Id, WS


Пример 2. Выбор объектов по свойству и форматирование результатов

Этот пример получает информацию о модулях, используемых процессами на компьютере. Он использует командлет Get-Process для получения процесса на компьютере.

Он использует командлет Select-Object для вывода массива экземпляров [System.Diagnostics.ProcessModule], содержащихся в свойстве Modules каждого экземпляра System.Diagnostics.Process, выводимого командлетом Get-Process.

Параметр -Property командлета Select-Object выбирает имена процессов. Это добавляет ProcessName NoteProperty к каждому экземпляру [System.Diagnostics.ProcessModule] и заполняет его значением свойства ProcessName текущего процесса.

Наконец, командлет Format-List используется для отображения имени и модулей каждого процесса в списке.

Get-Process Explorer | Select-Object -Property ProcessName -ExpandProperty Modules | Format-List

Пример вывода:

ProcessName       : explorer
ModuleName        : Explorer.EXE
FileName          : C:\Windows\Explorer.EXE
BaseAddress       : 140701319757824
ModuleMemorySize  : 5054464
EntryPointAddress : 140701320022512
FileVersionInfo   : File:             C:\Windows\Explorer.EXE
                    InternalName:     explorer
                    OriginalFilename: EXPLORER.EXE.MUI
                    FileVersion:      10.0.22000.1090 (WinBuild.160101.0800)
                    FileDescription:  Проводник
                    Product:          Операционная система Microsoft® Windows®
                    ProductVersion:   10.0.22000.1090
                    Debug:            False
                    Patched:          False
                    PreRelease:       False
                    PrivateBuild:     False
                    SpecialBuild:     False
                    Language:         Русский (Россия)
...

Пример 3: Выбор процессов, использующие больше всего памяти

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

Параметр -Wait не требуется в командах, включающих командлет Sort-Object, поскольку Sort-Object обрабатывает все объекты, а затем возвращает коллекцию. Оптимизация Select-Object доступна только для команд, которые возвращают объекты по отдельности по мере их обработки.

Get-Process | Sort-Object -Property WS | Select-Object -Last 5

Пример вывода:

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     88    66,09     138,66       2,86    9036   1 PhoneExperienceHost
     98   205,89     153,88       0,00    3968   0 MsMpEng
     89    91,84     159,91       2,00    7336   1 SearchHost
     87    47,27     162,64      20,84    6660   1 explorer
    308   570,88     193,71       0,00    3920   0 mysqld

Пример 4: Выбор уникальных символов из массива

В этом примере параметр -Unique командлета Select-Object используется для получения уникальных символов из массива символов.

"a","b","c","a","a","a" | Select-Object -Unique
a
b
c

Пример 5: Использование «-Unique» с другими параметрами

Параметр -Unique фильтрует значения после применения других параметров Select-Object. Например, если вы используете параметр -First для выбора первого числа элементов в массиве, Уникальность применяется только к выбранным значениям, а не ко всему массиву.

"a","a","b","c" | Select-Object -First 2 -Unique
a

В этом примере «-First 2» выбирает «a», «a» в качестве первых двух элементов массива. -Unique применяется к "a", "a" и возвращает a как уникальное значение.

Пример 6: Выббор самых новых и самых старых событий в журнале событий

Этот пример получает первое (самое новое) и последнее (самое старое) событие в журнале событий Windows PowerShell.

Командлет Get-EventLog получает все события из журнала Windows PowerShell и сохраняет их в переменной $a. Затем $a передаётся командлету Select-Object. Команда Select-Object использует параметр -Index для выбора событий из массива событий в переменной $a. Индекс первого события равен 0. Индекс последнего события равен количеству элементов в $a минус 1.

$a = Get-EventLog -LogName "Windows PowerShell"
$a | Select-Object -Index 0, ($A.count - 1)

Пример 7: Как выбрать все объекты, кроме первого

В этом примере создаётся новый сеанс PSSession на каждом из компьютеров, перечисленных в файле Servers.txt, кроме первого.



Select-Object выбирает все компьютеры, кроме первого, в списке имён компьютеров. Результирующий список компьютеров задаётся как значение параметра -ComputerName командлета New-PSSession.

New-PSSession -ComputerName (Get-Content Servers.txt | Select-Object -Skip 1)

Пример 8. Переименование файлов с атрибутом «только для просмотра» и показ нескольких результатов

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

Командлет Get-ChildItem использует динамический параметр ReadOnly для получения файлов, доступных только для чтения. Полученные файлы передаются командлету Rename-Item, который переименовывает файл. Он использует параметр -PassThru команды Rename-Item для отправки переименованных файлов командлету Select-Object, который выбирает для отображения первые 5 файлов.

Параметр -Wait команды Select-Object не позволяет PowerShell остановить командлет Get-ChildItem после того, как он получит первые пять текстовых файлов, доступных только для чтения. Без этого параметра будут переименованы только первые пять файлов только для чтения.

Get-ChildItem *.txt -ReadOnly | Rename-Item -NewName {$_.BaseName + "-ro.txt"} -PassThru | Select-Object -First 5 -Wait

Пример 9: Показать тонкости параметра -ExpandProperty

В этом примере показаны тонкости параметра -ExpandProperty.

Обратите внимание, что сгенерированный вывод представлял собой массив экземпляров [System.Int32]. Экземпляры соответствуют стандартным правилам форматирования выходного представления. Это справедливо для любых расширенных свойств. Если выходные объекты имеют определённый стандартный формат, расширенное свойство может быть невидимым.

# Создаём пользовательский объект для использования в примере Select-Object.
$object = [pscustomobject]@{Name="CustomObject";Expand=@(1,2,3,4,5)}
# Используем параметр -ExpandProperty, чтобы развернуть свойство.
$object | Select-Object -ExpandProperty Expand -Property Name

Вывод:

1
2
3
4
5

Далее:

# Вывод не содержал свойства Name, но оно было успешно добавлено.
# Используем Get-Member, чтобы подтвердить, что свойство Name было добавлено и заполнено.
$object | Select-Object -ExpandProperty Expand -Property Name | Get-Member

Вывод:

TypeName: System.Int32

Name        MemberType   Definition
----        ----------   ----------
CompareTo   Method       int CompareTo(System.Object value), int CompareTo(int value), ...
Equals      Method       bool Equals(System.Object obj), bool Equals(int obj), bool IEq...
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
GetTypeCode Method       System.TypeCode GetTypeCode(), System.TypeCode IConvertible.Ge...
ToBoolean   Method       bool IConvertible.ToBoolean(System.IFormatProvider provider)
ToByte      Method       byte IConvertible.ToByte(System.IFormatProvider provider)
ToChar      Method       char IConvertible.ToChar(System.IFormatProvider provider)
ToDateTime  Method       datetime IConvertible.ToDateTime(System.IFormatProvider provider)
ToDecimal   Method       decimal IConvertible.ToDecimal(System.IFormatProvider provider)
ToDouble    Method       double IConvertible.ToDouble(System.IFormatProvider provider)
ToInt16     Method       int16 IConvertible.ToInt16(System.IFormatProvider provider)
ToInt32     Method       int IConvertible.ToInt32(System.IFormatProvider provider)
ToInt64     Method       long IConvertible.ToInt64(System.IFormatProvider provider)
ToSByte     Method       sbyte IConvertible.ToSByte(System.IFormatProvider provider)
ToSingle    Method       float IConvertible.ToSingle(System.IFormatProvider provider)
ToString    Method       string ToString(), string ToString(string format), string ToS...
ToType      Method       System.Object IConvertible.ToType(type conversionType, System...
ToUInt16    Method       uint16 IConvertible.ToUInt16(System.IFormatProvider provider)
ToUInt32    Method       uint32 IConvertible.ToUInt32(System.IFormatProvider provider)
ToUInt64    Method       uint64 IConvertible.ToUInt64(System.IFormatProvider provider)
Name        NoteProperty string Name=CustomObject

Пример 10. Создание настраиваемых свойств объектов

В следующем примере показано использование Select-Object для добавления настраиваемого свойства к любому объекту. Когда вы указываете несуществующее имя свойства, Select-Object создаёт это свойство как NoteProperty для каждого переданного объекта.

$customObject = 1 | Select-Object -Property MyCustomProperty
$customObject.MyCustomProperty = "New Custom Property"
$customObject

Вывод:

MyCustomProperty
----------------
New Custom Property

Пример 11: Создание вычисляемых свойств для каждого InputObject

В этом примере показано использование командлета Select-Object для добавления вычисляемых свойств к входным данным. Передача ScriptBlock в параметр -Property приводит к тому, что командлет Select-Object оценивает выражение для каждого переданного объекта и добавляет результаты к выходным данным. Внутри ScriptBlock вы можете использовать переменную $_ для ссылки на текущий объект в конвейере.

По умолчанию командлет Select-Object использует строку ScriptBlock в качестве имени свойства. Используя Hashtable, вы можете пометить вывод вашего ScriptBlock как пользовательское свойство, добавляемое к каждому объекту. Вы можете добавить несколько вычисляемых свойств к каждому объекту, переданному командлету Select-Object.

# Создайте вычисляемое свойство с именем $_.StartTime.DayOfWeek.
Get-Process | Select-Object -Property ProcessName,{$_.StartTime.DayOfWeek}

ProcessName  $_.StartTime.DayOfWeek
----         ----------------------
alg                       Wednesday
ati2evxx                  Wednesday
ati2evxx                   Thursday
...

# Добавляем пользовательское свойство для расчета размера в килобайтах каждого передаваемого объекта FileInfo. Используйте переменную конвейера, чтобы разделить длину каждого файла на 1 килобайт.
$size = @{label="Size(KB)";expression={$_.length/1KB}}
# Создаём дополнительное вычисляемое свойство с количеством дней с момента последнего обращения к файлу. Вы также можете сократить имя ключа до «l» и «e» или использовать «Name» вместо «Label».
$days = @{l="Days";e={((Get-Date) - $_.LastAccessTime).Days}}
# Вы также можете сократить имя ключа метки до «l», а ключ выражения до «e».
Get-ChildItem $PSHOME -File | Select-Object Name, $size, $days

Name                        Size(KB)        Days
----                        --------        ----
Certificate.format.ps1xml   12.5244140625   223
Diagnostics.Format.ps1xml   4.955078125     223
DotNetTypes.format.ps1xml   134.9833984375  223

Пример 12. Выбор ключей хеш-таблицы без использования вычисляемых свойств

Начиная с PowerShell 6 командлет Select-Object поддерживает выбор ключей ввода хеш-таблицы в качестве свойств. В следующем примере выбираются ключи weight и name во входной хеш-таблице и отображаются выходные данные.

@{ name = 'a' ; weight = 7 } | Select-Object -Property name, weight

name weight
---- ------
a         7

Пример 13. Как в PowerShell узнать, какие программы прослушивают открытые TCP порты

В этом примере будет получено имя процесса, связанного с каждым открытым портом TCP:

Get-NetTcpConnection -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}} | Sort-Object -Property LocalPort | Format-Table

Пример 14. Как в PowerShell узнать, какие программы прослушивают открытые UDP порты

Эта команда покажет открытые на всех сетевых интерфейсах UDP порты, а также отобразит имя процесса, открывшего UDP порт:

Get-NetUDPEndpoint | Select-Object LocalAddress,LocalPort,OwningProcess,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}} | Sort-Object -Property LocalPort | Format-Table

Что выбрать для использования Select-Object или Format-Table

В предыдущих статьях рассмотрены опции, примеры и тонкости работы с Format-Table, подробности смотрите по ссылкам:

У обоих командлетов, Select-Object или Format-Table, имеется опция -Property, которую можно пропускать. Опция имеет общие для обоих командлетов параметры:

  • Name (или Label) = `<строка>`
  • Expression = `<строка>` или `<скриптовый блок>`

Благодаря этому следующие команды дают идентичный результат:

Get-PSDrive C | Format-Table @{Expression={$_.Free/1GB}}
Get-PSDrive C | Select-Object @{Expression={$_.Free/1GB}}

И эти две команды выведут в точности одинаковые данные о количестве свободного и занятого дискового пространства:

Get-PSDrive C | Format-Table @{Expression={$_.Free/1GB}},@{Expression={$_.Used/1GB}}
Get-PSDrive C | Select-Object @{Expression={$_.Free/1GB}},@{Expression={$_.Used/1GB}}

Следующая команда взята из статьи «Как поменять заголовок столбца в выводе PowerShell. Как поменять ширину и выравнивание в таблицах»:

Get-ChildItem | Format-Table @{Label="Режим"; Expression={$_.Mode}}, @{Label="Последняя запись в"; Expression={$_.LastWriteTime}}, @{Label="Размер"; Expression={$_.Length}}, @{Label="Имя"; Expression={$_.Name}}

В предыдущей команде заголовки всех столбцов переведены на русский.

Если Format-Table заменить на Select-Object, то команда вновь сработает:

Get-ChildItem | Select-Object @{Label="Режим"; Expression={$_.Mode}}, @{Label="Последняя запись в"; Expression={$_.LastWriteTime}}, @{Label="Размер"; Expression={$_.Length}}, @{Label="Имя"; Expression={$_.Name}}

Ещё одна команда из статьи, ссылка на которую дана выше:

Get-ChildItem | Format-Table @{Label="Режим"; Expression={$_.Mode}; Width=8}, @{Label="Последняя запись в"; Expression={$_.LastWriteTime}; Width=20}, @{Label="Размер"; Expression={$_.Length}; Width=7; Alignment="Left"}, @{Label="Имя"; Expression={$_.Name}}

Но аналогичная команда с Select-Object:

Get-ChildItem | Select-Object @{Label="Режим"; Expression={$_.Mode}; Width=8}, @{Label="Последняя запись в"; Expression={$_.LastWriteTime}; Width=20}, @{Label="Размер"; Expression={$_.Length}; Width=7; Alignment="Left"}, @{Label="Имя"; Expression={$_.Name}}

завершилась ошибкой:

Select-Object: The Width key is not valid.

Причина ошибки в том, что для параметра -Property командлета Format-Table предусмотрены также следующие ключи, в дополнении к двум уже рассмотренным выше:

  • FormatString = `<строка>`
  • Width = `<int32>`
  • Alignment = значением может быть Left, Center или Right

А для параметра -Property командлета Select-Object данные ключи отсутствуют. Таким образом, если вам нужно указать ширину столбцов и выравнивание в них, то используйте Format-Table вместо Select-Object.

Если вам нужно создать новое свойство объекта, также используйте Select-Object.


Рекомендуется Вам:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *