Вслед предыдущей статье, где мы рассматривали способы фильтрации с использованием значений флагов в атрибутах, представленных в виде битовых масок, давайте поговорим о подходах к изменению значений таких атрибутов.
В атрибутах такого типа каждый бит является отдельным флагом и имеет свое собственное значение. Примерами таких атрибутов являются UserAccountControl для объектов пользователей и компьютеров и GroupType для объектов групп.
В качестве примера давайте опять же обратимся к второму флагу — ADS_UF_ACCOUNTDISABLE — атрибута UserAccountControl, указывающему, является ли учетная запись пользователя или компьютера активной — значение 0, или же она деактивирована — значение 1.
Так как это второй бит, его десятичное значение — 2. Это нам еще понадобится.
Получить значение этого атрибута мы можем несколькими способами. С использованием командлетов модуля ActiveDirectory это будет выглядеть так:
$user = Get-ADUser someuser -Properties UserAccountControl $user.UserAccountControl 512
Если мы решим использовать ADSI — Active Directory Service Interfaces — запрос будет выглядеть следующим образом:
$adsiuser = [ADSI]"LDAP://CN=someuser,DC=domain,DC=com" $adsiuser.userAccountControl 512
Значение 512, которое в шестнадцатеричном виде будет выглядеть как 0x200, говорит нам о том, что установлен флаг ADS_UF_NORMAL_ACCOUNT. Наличие этого флага говорит о том, что это обычный пользовательский аккаунт.
Теперь давайте решим, что мы хотим деактивировать учетную запись пользователя someuser.
ADAccount
Для этого, опять же, существует несколько способов. Наиболее простой из них, тот, который вы скорее всего и будете применять — это использование командлета Disable-ADAccount.
Например, так:
Get-ADUser someuser | Disable-ADAccount
Теперь, если мы выполним команду
Get-ADUser someuser -Properties UserAccountControl | Format-List -Property Enabled, UserAccountControl Enabled : False UserAccountControl : 514
мы увидим, что, свойство Enabled установлено в False, а значение UserAccountControl увеличилось на 2 за счет установки второго бита — ADS_UF_ACCOUNTDISABLE — в значение 1.
Вернуть все на место мы можем при помощи командлета Enable-ADAccount.
Get-ADUser ivanov | Enable-ADAccount Get-ADUser ivanov -Properties UserAccountControl | Format-List -Property Enabled, UserAccountControl Enabled : True UserAccountControl : 512
+2
В случае, если нам недоступен модуль ActiveDirectory, мы можем поступить следующим образом.
Так как значение атрибута UserAccountControl по умолчанию представляется в виде десятичного числа, мы тоже можем не вдаваться в двоичную или шестнадцатеричную систему счисления и установить этот флаг путем увеличения значения UserAccountControl на два. А сбросить его мы можем путем вычитания того же числа 2 из исходного значения.
Почему именно два? Потому что в данном случае 2 — это десятичное значение флага ADS_UF_ACCOUNTDISABLE. Для других позиций битов оно будет другим.
Для того, чтобы деактивировать аккаунт someuser, мы можем поступить так:
$adsiuser = [ADSI]"LDAP://CN=someuser,DC=domain,DC=com" $adsiuser.userAccountControl 512 $disable = $adsiuser.userAccountControl[0] + 2 $disable 514 $adsiuser.Put('UserAccountControl', $disable) $adsiuser.SetInfo()
Активировать учетную запись мы можем следующим образом:
$adsiuser = [ADSI]"LDAP://CN=someuser,DC=domain,DC=com" $adsiuser.userAccountControl 514 $enable = $adsiuser.userAccountControl[0] - 2 $enable 512 $adsiuser.Put('UserAccountControl', $enable) $adsiuser.SetInfo()
Почему мы при операциях сложения и вычитания обращаемся к $adsiuser.userAccountControl[0], так это потому, что значением $adsiuser.userAccountControl является объект System.DirectoryServices.PropertyValueCollection, что по сути представляет из себя массив, поэтому, чтобы обратиться к значению его первого (а на самом деле единственного) элемента, мы добавляем индекс [0].
Гораздо более важной вещью тут является то, что перед тем, как увеличить значение атрибута UserAccountControl на 2, нам необходимо удостовериться, что второй его бит равен нулю. Потому как, даже если он уже установлен в 1, увеличить значение UserAccountControl еще на 2 нам никто не помешает, и в этом случае последствия будут гораздо более любопытными.
То же самое касается и вычитания, когда перед снятием флага, нам необходимо удостовериться, что в исходном значении он установлен.
-bor, -band и -bnot
Более предсказуемым способом будет использование двоичных операторов: -bor, -band и -bnot, поскольку в этом случае попытка установить уже существующий флаг (равно как и снять отсутствующий) не приведет к каким-либо негативным последствиям.
Итак, мы знаем, что десятичное значение второго флага атрибута UserAccountControl — это 2. Для удобства использования сохраним его в переменной.
$ADS_UF_ACCOUNTDISABLE = 2
Теперь, чтобы установить второй бит в значение 1, мы воспользуемся оператором -bor — побитовое ИЛИ.
$adsiuser = [ADSI]"LDAP://CN=someuser,DC=domain,DC=com" $adsiuser.Put('UserAccountControl', $($adsiuser.userAccountControl[0] -bor $ADS_UF_ACCOUNTDISABLE)) $adsiuser.SetInfo()
Для того, чтобы снять флаг ADS_UF_ACCOUNTDISABLE, нам потребуется оператор -band. В качестве аргументов с одной стороны будет исходное значение атрибута UserAccountControl, а с другой — инвертированное значение переменной $ADS_UF_ACCOUNTDISABLE.
Инвертировав переменную $ADS_UF_ACCOUNTDISABLE — что мы можем сделать при помощи оператора -bnot — мы получим значение, в котором будут установлены все флаги, кроме второго. Последующая операция -band — побитовое И — скопирует все биты исходного значения атрибута UserAccountControl, кроме второго, который будет установлен в 0.
Сделать это мы можем следующим образом:
$adsiuser = [ADSI]"LDAP://CN=someuser,DC=domain,DC=com" $adsiuser.Put('UserAccountControl', $($adsiuser.userAccountControl[0] -band (-bnot $ADS_UF_ACCOUNTDISABLE))) $adsiuser.SetInfo()
Страницы в социальных сетях:
Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell