Фильтрация свойств объектов в PowerShell
Оглавление
1. Для чего нужен командлет 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, подробности смотрите по ссылкам:
- Как в PowerShell менять набор выводимых по умолчанию данных
- Тонкая настройка вывода с Format-Table
- В PowerShell таблица не помещается на экран — как исправить (РЕШЕНО)
У обоих командлетов, 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.
Связанные статьи:
- Как в PowerShell менять набор выводимых по умолчанию данных (100%)
- В PowerShell таблица не помещается на экран — как исправить (РЕШЕНО) (77.1%)
- Тонкая настройка вывода с Format-Table (77.1%)
- Как поменять заголовок столбца в выводе PowerShell. Как поменять ширину и выравнивание в таблицах (77.1%)
- Как выводить данные без таблицы в PowerShell (67.2%)
- Аналоги cat, tail, head и wc в PowerShell (RANDOM - 50%)