В предыдущих статьях рубрики я рассказывал о том, как с помощью конвейера (|), объединяющего несколько команд PowerShell в цепочку, можно создавать простые отчеты, например:
get-aduser –f * -pr lastlogondate | select samaccountname,lastlogondate | sort lastlogondate
Эта комбинация команд позволяет вывести список имен пользователей, выбрать только имена и даты последней регистрации и отсортировать результаты по дате последней регистрации. Результат выполнения такого запроса может содержать много ненужной информации. Предположим, нам требуется вывести имена и даты последней регистрации не всех пользователей, а только тех, кто не заходил в систему в течение определенного времени.
Эту задачу позволяет решить команда where-object, которую практически никогда не вызывают по полному имени. В большинстве случаев для ее вызова используется where или знак вопроса (?). В предыдущих публикациях речь шла о дуэтах команд PowerShell, состоящих из команды-фильтра (вывод учетных записей, соответствующих определенному критерию) и команды-действия (применение определенного действия к извлеченному подмножеству AD). Рассматривались и некоторые команды-фильтры: get-aduser, search-adaccount и другие.
Where-object – это фильтр фильтра. Чтобы понять синтаксис команды, начнем с примера. Для вывода пользователей, не запускавших систему после 1 января 2013 года, построим следующий запрос:
get-aduser -f * | where {$_.lastlogondate -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 |? {$_.lastlogondate -le «1 January 2012»} | select samaccountname,lastlogondate | sort lastlogondate
С помощью where-object и $_ можно строить любые виды фильтров. Например, вывести имена всех пользователей, чье имя (SamAccountName) начинается с F, позволяет такой запрос:
get-aduser -f * | where {$_.samaccountname -like «f*"}
Может возникнуть вопрос: зачем было тратить столько времени на обсуждение параметра -filter команды get-aduser? Почему бы не применять для всех запросов единую форму:
get-aduser -f * | where {$_. -like»"}
С технической точки зрения, для этого нет противопоказаний, кроме одного: такой подход может привести к излишней трате полосы пропускания и времени сервера. Команда get-aduser с фильтром посылает команду контроллеру домена (DC), и DC возвращает лишь небольшое подмножество AD. Когда же результат get-aduser -f * подается на вход where-object, у DC запрашиваются все учетные записи пользователей, после чего локальный процессор отфильтровывает их, оставляя только нужные данные. Таким образом, .