Active Directory Powershell – Расширенный фильтр
Чтение/написание LDAP-фильтров вызывает у вас затруднения? Вы бы хотели писать LDAP-фильтры в более естественном виде? Вы бы хотели, чтобы парсер LDAP-фильтров указывал вам на ошибочный символ, вместо показа расплывчатого сообщения об ошибке LDAP_FILTER_ERROR (87)? Вам непонятно, как указывать OID в фильтре? Если хотя бы на один из этих вопросов вы ответили «да», имеет смысл дочитать этот пост до конца...
Active Directory Module for Windows Powershell представляет новую мощную замену LDAP-фильтрам; мы называем это «Расширенный фильтр» («The Advanced Filter»). Расширенный фильтр поддерживается с помощью параметра – Filterво всех командлетах вида Get-AD*.
Так что же такого «расширенного» в этом фильтре?
1. Простота написания – Новый фильтр удобен в чтении и написании. Он использует инфиксную запись (например: { GivenName –eq “John” –and SurName –eq “Smith” } ), которая более удобна по сравнению с префиксной записью (например: (&(givenName=john)(sn=smith)) ).
Новый синтаксис фильтров аналогичен языку выражений PowerShell (Powershell Expression Language) и используется в параметре FilterScript командлета Where-Object. Так что для пользователей Powershell становится просто делать запросы к AD без знаний в области Ldap-фильтрации. Большинство используемых операторов стандартны для Powershell (например: -eq, -like, -band и т.п.). Также представлены несколько новых операторов – таких, как -recursivematch и т.п.
2. Улучшенные сообщения об ошибках парсинга фильтра – Давайте попробуем задать в параметре –Filter некорректную строку запроса.
PS D:\Users\Administrator> Get-ADUser -Filter { Name -isequal "Administrator" }
Get-ADUser : Error parsing query: ' Name -isequal "Administrator" ' Error Message: 'Operator Not supported: -isequal' at position: '7'.
At line:1 char:11
+ Get-ADUser <<<< -Filter { Name -isequal "Administrator" }
+ CategoryInfo : ParserError: (:) [Get-ADUser], ADFilterParsingException
+ FullyQualifiedErrorId : Error parsing query: ' Name -isequal "Administrator" ' Error Message: 'Operator Not supported: -isequal' at position: '7'., Microsoft.ActiveDirectory.Management.Commands.GetADUser
Таким образом, сообщение об ошибке для парсера расширенных фильтров корректно указывает, что оператор “-isequal” не поддерживается. Возьмем другой пример – не включим строковое значение в кавычки.
PS D:\Users\Administrator> Get-ADUser -Filter { Name -like Administrator }
Get-ADUser : Error parsing query: ' Name -like Administrator ' Error Message: 'syntax error' at position: '13'.
At line:1 char:11
+ Get-ADUser <<<< -Filter { Name -like Administrator }
+ CategoryInfo : ParserError: (:) [Get-ADUser], ADFilterParsingException
+ FullyQualifiedErrorId : Error parsing query: ' Name -like Administrator' Error Message: 'syntax error' at position: '13'., Microsoft.ActiveDirecto ry.Management.Commands.GetADUser
Здесь сообщение об ошибке для парсера расширенных фильтров указывает на позицию в строке, где синтаксис некорректен. Корректным будет такой фильтр: -Filter { Name -like "Administrator" }
3. Внутри фильтра можно использовать переменные Powershell ! – Расширенный Фильтр позволяет получать доступ к переменным Powershell внутри фильтра. Вы можете также получать доступ к свойствам переменных Powershell внутри фильтра.
PS D:\> $JohnSmith = Get-ADUser JohnSmith
PS D:\> Get-ADUser -Filter { manager -eq $JohnSmith.DistinguishedName }
## Получаем все учетные записи пользователей, где менеджер - JohnSmith
Внимание: Расширенный Фильтр не поддерживает индексатор (например: $a[0]) и вызов функции (например: $a.ToString()) внутри фильтра.
4. Автоматическое кодирование в Ldap – Ldap-кодирование значений (таких, как байты и т.д.) автоматически обрабатывается конвертерами Расширенных Фильтров. Например, если вы хотите найти пользователей по параметру «Время входа», не нужно задумываться о кодировании байтового значения Logon Hour в строковый формат LDAP. Расширенный Фильтр сделает это сам. Вы можете просто указать массив байт внутри Расширенного Фильтра.
PS D:\> $u = Get-ADUser Administrator -Properties *
PS D:\> $byt = $u.logonHours
PS D:\> $byt.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Byte[] System.Array
С помощью Расширенного Фильтра:
PS D:\> Get-ADUser -Filter { logonHours -eq $byt }
Спомощью LDAP- фильтра :
## Каким-либо образом Ldap-кодируем byte[] в строку и помещаем ее в фильтр.
PS D:\> Get-ADUser -LdapFilter "(logonHours=\00\0B\FF\FF\FF\1F\FB\FF\AF\FF\FF\FC\FF\0A\FF\FF\FF\FF\FF\FF\1B)"
5. Поддержка значений в расширенном формате – Расширенный Фильтр поддерживает значения в расширенном формате .NET объектов и подходящих строковых форматах. Он также делает необходимое преобразование в формат поиска Ldap. Например:
PS D:\> Get-ADGroup -Filter {isCriticalSystemObject -eq $true } ## Получаем все системные критические группы
PS D:\> $SixtyDaysAgo = (Get-Date).Subtract((New-TimeSpan -Days 60))
PS D:\> Get-ADUser -Filter { lastLogonTimeStamp -notlike "*" -or lastLogonTimeStamp -le $ SixtyDaysAgo }
## Получаем объекты всех пользователей, которые не входили в систему за последние 60 дней
PS D:\> Get-ADGroup -filter { groupType -band 0x80000000 } ## Получаем все группы безопасности, представляя целое значение в шестнадцатеричном формате.
## Аналогичный запрос LDAP выглядел бы так:
## (&(objectCategory=group)(groupType:1.2.840.113556.1.4.803:=2147483648))
Вот список поддерживаемых типов .NET:
- System.Guid, System.Security.Cryptography.X509Certificates.X509Certificate, System.Security.Principal.SecurityIdentifier, System.DirectoryServices.ActiveDirectorySecurity
- Значения этих типов конвертируются в byte[] и затем кодируются в строку поиска Ldap.
- System.DateTime
- Значения этого типа конвертируются в соответствующий формат даты Ldap - Large Integer/Interval, Generalized Time, UTC Coded Time.
- System.String, System.Int32, System.Int64, System.UInt32, System.UInt64, System.Boolean, System.Byte, System.SByte, System.Int16, System.UInt16, System.Char, System.Single, System.Single, System.Double, System.Decimal
- Значения этих типов конвертируются в строковый формат.
На заметку: Все командлеты вида Get-AD* также поддерживают Ldap-фильтрацию через параметр - LdapFilter.
Cheers!
Swami
--
Swaminathan Pattabiraman [MSFT]
Developer – Active Directory Powershell Team
Filed under: Filter
Перевод: Илья Лушников