Для работы с доменными пользователями в 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
Ну или посмотреть в графической оснастке.
А теперь представим, что требуется установить флаги «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», поэтому при установке любого из них он снимается. Это очень наглядно видно в графической оснастке.
И еще одна операция, которая обычно производится при создании пользователя — добавление его в группу. Для примера добавим нашего пользователя в группу локальных администраторов:
[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)