Powershell ... 'enabled eq $ true' vs где {$ _. Enabled -eq $ true} - PullRequest
2 голосов
/ 28 января 2020

Я очень мало знаю о PowerShell.

Мне интересно, может ли кто-нибудь указать мне на то, что мне нужно узнать, чтобы объяснить следующее:

PS C:\Users\username> (Get-Aduser -Filter 'Enabled -eq $true').count
1234
PS C:\Users\username> (Get-Aduser -filter * | where {$_.Enabled -eq $true }).count
13

Они читают довольно аналогичный... ? Что такое «Включено» и чем оно может отличаться от $_, которое я прочитал, относится к «текущему объекту в конвейере», которое, как я полагаю, повторяется с «где».

Спасибо!

1 Ответ

3 голосов
/ 28 января 2020

В общем случае - этот

Get-Aduser -Filter "something -eq 'some value'"

отправляет фильтр на сервер (т. Е. Контроллер домена), и сервер возвращает только соответствующих пользователей, тогда как этот

Get-Aduser -filter *

получает всех пользователей с сервера и фильтрует их на втором этапе внутри скрипта (используя where).

Очевидно, что первый подход гораздо более эффективен, даже если результатом является то же самое.


Что касается проверки Enabled, все немного сложнее. Пользовательские объекты в AD на самом деле не имеют свойства Enabled - это свойство добавляется на стороне клиента. Это означает, что вы не можете передать Enabled -eq $true на сервер, он не будет знать, что с этим делать.

Объекты учетной записи пользователя AD имеют свойство userAccountControl , которое собирает все виды флагов:

SCRIPT            0x0001   1
ACCOUNTDISABLE    0x0002   2
HOMEDIR_REQUIRED  0x0008   8
LOCKOUT           0x0010  16
PASSWD_NOTREQD    0x0020  32

и еще немало. Учетная запись отключается, если установлен флаг 2. Вы можете запросить сервер, если этот флаг установлен, используя фильтр LDAP:

# all disabled users
Get-ADUser -LdapFilter "(userAccountControl:1.2.840.113556.1.4.803:=2)"

# all NOT disabled users
Get-ADUser -LdapFilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"

Это немного громоздко, но LDAP это делает так. (:1.2.840.113556.1.4.803: представляет оператор «побитовое И» в LDAP. Они почему-то не сделали для него более простой символ.)

С этим фильтром фильтрация фактически выполняется на сервере опять же, что означает, что он должен быть значительно быстрее, чем альтернатива, особенно когда в AD много учетных записей пользователей.

Я не думаю, что есть способ express эту конкретную вещь в "дружественном "-Filter синтаксис Get-ADUser, но другие фильтры будут работать на стороне сервера

# all users whose first name starts with an A
Get-ADUser -Filter "givenName -like 'A*'"

Что внутренне делает Get-ADUser, это анализирует строку -Filter и создает LDAP фильтруйте это, поскольку синтаксис фильтра LDAP - единственное, что сервер понимает:

Фильтр "PowerShell-style" givenName -like 'A*' будет преобразован в фильтр LDAP (givenName=A*).

Но кажется, что при попытке с Enabled -eq $true что-то идет не так внутри Get-ADUser, кажется, что это полностью игнорируется, возможно потому, что он недостаточно умен, чтобы перевести это в (!(userAccountControl:1.2.840.113556.1.4.803:=2)). Таким образом, фильтр LDAP остается пустым, и сервер возвращает все учетные записи.

Это причина, по которой я склонен писать фильтры LDAP с самого начала. Его не так сложно освоить, он более универсален, чем синтаксис PowerShell, быстрее, чем фильтрация на стороне клиента, и отправляется на сервер «как есть», с этим ничего не мешает заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...