Заметки о Windows и других программных продуктах Microsoft...

Управляем локальными пользователями с помощью PowerShell

Управляем локальными пользователями с помощью PowerShell

Для работы с доменными пользователями в PowerShell уже давно существует множество командлетов, но если вам потребуется управлять локальными пользователями, то здесь основным инструментом по прежнему остается графическая оснастка (lusrmgr.msc) и старая добрая утилита командной строки net.  Тем не менее, в PowerShell все же есть возможность для управления локальными пользователями на компьютерах, не входящих в домен.

Для этого можно воспользоваться интерфейсом ADSI (Active Directory Services Interface), который может применяться как для работы с Active Directory, так и с отдельно стоящими компьютерами.

Рассмотрим несколько наиболее актуальных ситуаций при работе с локальными пользователями

Создание пользователя

Первое, что необходимо сделать с пользователем — это создать его учетную запись. Для этого сначала получаем объект компьютера и помещаем его в переменную:

[adsi]$computer = ″WinNT://SRV1″

Затем с помощью метода Create создаем пользователя с именем LocalAdmin:

$user = $computer.Create(″User″, ″LocalAdmin″)

Устанавливаем флажок для того, чтобы пользователь сменил пароль при входе:

$user.Put(″PasswordExpired″, 1)

Задаем начальный пароль:

$user.SetPassword(″P@$$word″)

И добавляем описание в поле «Description»:

$user.Put(″Description″, ″Local administrator″)

Чтобы все сделанные изменения были применены, необходимо выполнить команду:

$user.SetInfo()

Для проверки можно вывести список пользователей командой:

$computer.Children | where {$_.Class -eq ″user″} | ft name, description -auto

создание нового пользователя

 

Ну или посмотреть в графической оснастке.

новый пользователь в GUI

 

А теперь представим, что требуется установить флаги «User cannot change password» и\или «Password never expired». Эти настройки хранятся в свойстве пользователя UserFlags, которое представляет из себя битовую маску. Для вычисления необходимого значения используется операция -bor (побитовое ИЛИ), например так мы установим флаг «Password never expired»:

$flag = $user.UserFlags.Value -bor 0x10000
$user.Put(″userflags″,$flag)
$user.SetInfo()

Примечание. Значения, необходимые для установки различных флагов, можно посмотреть на странице http://msdn.microsoft.com/en-us/library/aa772300(VS.85).aspx

Надо иметь в виду, что при установке одного флага остальные сбрасываются. К примеру, если установить флаг «User cannot change password» (значение 0x40), то флаг «Password never expired» будет снят. Для того, чтобы поставить оба флага, необходимо суммировать их значения, например так:

$flag = $user.UserFlags.Value -bor 0x10040
$user.Put(″userflags″,$flag)
$user.SetInfo()

установка флагов пользователя

 

Также необходимо помнить, что флаги «User cannot change password» и «Password never expired» несовместимы с «User must change password at next logon», поэтому при установке любого из них он снимается. Это очень наглядно видно в графической оснастке.

результат установки флагов в GUI

 

И еще одна операция, которая обычно производится при создании пользователя — добавление его в группу. Для примера добавим нашего пользователя в группу локальных администраторов:

[adsi]$group = ″WinNT://SRV1/Administrators, group″
$group.Add($user.Path)

Проверить содержимое группы можно такой несложной 🙂 командой:

$members = @($group.psbase.Invoke(″Members″))
$members | foreach {$_.GetType().InvokeMember(″Name″,″GetProperty″, $null, $_, $null)}

добавление пользователя в группу

Редактирование свойств пользователя

Довольно часто встречается ситуация, когда пользователь уже имеется и его надо отредактировать — сменить пароль, добавить в группу и т.п. Первым делом помещаем объект компьютера в переменную и смотрим список локальных пользователей:

[adsi]$computer = ″WinNT://SRV1″
$computer.Children | where {$_.Class -eq ″user″} | ft name, description -auto

вывод списка локальных пользователей

 

Предположим, требуется сбросить\сменить пароль для пользователя LocalAdmin. Помещаем его в переменную:

[adsi]$user = ″WinNT://SRV1/LocalAdmin,user″

Устанавливаем новый пароль:

$user.SetPassword(″newP@$$w0rd″)

Задаем смену пароля при следующем входе:

$user.Put(″PasswordExpired″,1)

и сохраняем изменения:

$user.SetInfo()

сброс пароля пользователя

 

А теперь передвинем его из группы локальных администраторов (Administrators) в группу пользователей удаленного рабочего стола (Remote Desctop Users). Для этого помещаем обе группы в переменные:

[adsi]$admins = ″WinNT://SRV1/Administrators,group″
[adsi]$rdpusers = ″WinNT://SRV1/Remote Desktop Users,group″

Затем, используя метод Remove, удаляем пользователя из одной группы:

$admins.Remove($user.Path)

и добавляем в другую с помощью метода Add:

$rdpusers.Add($user.Path)

перемещение пользователя в другую группу

Отключение\удаление пользователя

Ну и конечно может потребоваться отключить или удалить учетную запись пользователя. За отключение отвечает флаг «Account is disabled», который также хранится в UserFlags. Сначала помещаем в переменную значение, соответствующее отключенной записи:

$disabled = 0x0002

Затем с помощью операции -band (побитовое И) проверяем, включена ли учетная запись. Результат выводим в логическом (boolean) виде:

($user.UserFlags.Value -band $disabled) -as [bool]

Если команда вернула False, значит учетная запись активна. Задаем новое значение флага:

$flag = $user.UserFlags.Value -bor $disabled

И изменяем текущее значение:

$user.Put(″userflags″, $flag)
$user.SetInfo()

Обновляем кэш и еще раз проверяем, включена ли учетная запись:

$user.RefreshCache()
($user.UserFlags.Value -band $disabled) -as [bool]

Теперь команда возвращает True, что означает успешное выключение. Ну а для обратного включения требуются ровно те-же действия, только вместо операции -bor (включающее ИЛИ) используется операция -bxor (исключающее ИЛИ):

$disabled = 0x0002
$flag = $user.UserFlags.Value -bxor $disabled
$user.Put(″userflags″, $flag)
$user.SetInfo()

выключение учетной записи пользователя

 

Ну и для окончательного удаления пользователя воспользуемся методом Delete:

[adsi]$computer = ″WinNT://SRV1″
$computer.Delete(″user»,$user.Name.Value)

И проверим результат командой:
$computer.Children | where {$_.Class -eq ″user″} | ft name, description -auto

удаление учетной записи пользователя

 

На этом у меня все о PowerShell и локальных пользователях. Если это вам покажется недостаточным, то более подробно свойства и методы локальных пользователей описаны на MSDN.

 
 
Комментарии

Спасибо! Отличное руководство, полезное!
Но я бы посоветовал пользоваться переменными:
вместо [adsi]$computer = ″WinNT://SRV1″ использовать [adsi]$computer = ″WinNT://$env:COMPUTERNAME″.

Также в статье замечена ошибка в переменных:
[adsi]$admins = ″WinNT://SRV1/Administrators,group″
!!![adsi]$admins = ″WinNT://SRV1/Remote Desktop Users,group″

а далее
$admins.Remove($user.Path)
$rdpusers.Add($user.Path)

Про переменные — согласен, скрипт будет более универсален. Просто в примере всего один сервер, поэтому переменные не потребовались.
Ошибку исправил, спасибо.