Сводим результаты PowerShell к самому необходимому

В предыдущих статьях рубрики я рассказывал о том, как с помощью конвейера (|), объединяющего несколько команд PowerShell в цепочку, можно создавать простые отчеты, например:
get - aduser - I - pr lastlogondate I select samaccountname, lastlogondate I sort lastlogondate. Эта комбинация команд позволяет вывести список имен пользователей, выбрать только имена и даты последней регистрации и отсортировать результаты по дате последней регистрации. Результат выполнения такого запроса может содержать много ненужной информации. Предположим, нам требуется вывести имена и даты последней регистрации не всех пользователей, а только тех, кто не заходил в систему в течение определенного времени.
Эту задачу позволяет решить команда where-object, которую практически никогда не вызывают по полному имени. В большинстве случаев для ее вызова используется where или знак вопроса (?). В предыдущих публикациях речь шла о дуэтах команд PowerShell, состоящих из команды-фильтра (вывод учетных записей, соответствующих определенному критерию) и команды-действия (применение определенного действия к извлеченному подмножеству AD). Рассматривались и некоторые команды-фильтры: get-aduser, search-adaccount и другие.
Where-object - это фильтр фильтра. Чтобы понять синтаксис команды, начнем с примера. Для вывода пользователей, не запускавших систему после 1 января 2013 года, построим следующий запрос:
get-aduser-f I where ($_.lasllogondate-le "1 January 2013") Команда get-aduser извлекает все учетные записи пользователей домена. Результаты передаются по конвейеру команде where-object, которая проверяет каждый входящий объект на соответствие определенному критерию. Критерий, заключенный в фигурные скобки, заслуживает отдельного рассмотрения. Запись - le означает «меньше или равно»; указанная справа дата также не вызывает вопросов. Остается разобраться, что такое $_.lastlogondate. Как уже было сказано, where-object анализирует приходящие по конвейеру данные. Понятно, что утверждение (нечто)- le «1 January 2013» предполагает сопоставление этого (нечто) с указанной датой. Таким образом, данное (нечто) должно быть именно тем, что в данный момент приходит по конвейеру. Для обозначения того, что передано по конвейеру, используется символ $_. Мы уже знаем, что PowerShell имеет переменные, позволяющие хранить временную информацию в памяти компьютера. Переменную можно узнать по первому символу - знаку доллара ($). Переменные можно создавать в ходе работы, но у PowerShell, как и у большинства сред построения сценариев, есть и встроенные переменные, например $true и $false, хранящие значения true и false. По аналогии логично было бы хранить текущее содержимое конвейера в переменной $pipeline, но вместо этого используется переменная $_, которая в данном случае хранит весь передаваемый по конвейеру объект - учетную запись пользователя.
Однако приведенный в нашем примере критерий предусматривает сопоставление с датой (1 января 2013 г.) не всего объекта пользователя, а лишь его свойства 'lastlogondate. Задачу извлечения лишь нужной информации решает добавление точки и имени свойства, в результате чего получается запись $_.lastlogondate. Итак, усовершенствованный с помощью where - object запрос будет выглядеть следующим образом:
get-aduser-f-pr lastlogondate I? ($_.lastlogondate - le "1 January 2012") I select samaccountname, lastlogondate I sort lastlogondate С помощью where-object и $_ можно строить любые виды фильтров. Например, вывести имена всех пользователей, чье имя (SamAccountName) начинается с F, позволяет такой запрос:
get-aduser-f I where ($_.samaccountname - like T") Может возникнуть вопрос: зачем было тратить столько времени на обсуждение параметра - filter команды get-aduser? Почему бы не применять для всех запросов единую форму:
get-aduser-f I where ($_.like"') С технической точки зрения для этого нет противопоказаний, кроме одного: такой подход может привести к излишней трате полосы пропускания и времени сервера. Команда get - aduser с фильтром посылает команду контроллеру домена (DC), и DC возвращает лишь небольшое подмножество AD. Когда же результат get-aduser-f подается на вход where-object, у DC запрашиваются все учетные записи пользователей, после чего локальный процессор отфильтровывает их, оставляя только нужные данные. Таким образом, where-object - отличный универсальный инструмент, однако следует избегать его применения, когда у исходной команды get-whatever уже есть встроенный фильтр.