Pwdlastset что это за атрибут
Перейти к содержимому

Pwdlastset что это за атрибут

  • автор:

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

В ActiveDirectory у каждой учетной записи есть два значения, которые указывают на последнее время смены пароля учетной записи.

pwdLastSet и PasswordLastSet

Отличаются они форматом записи даты.

pwdLastSet хранит время назначения пароля в виде большого числа, которое представляет собой число интервалов по 100 наносекунд (OMG��), начиная отчет с 1.01.1601 года в стандарте UTC ( Coordinated Universal Time )

pwdLastSet

Следующей командой можно перевести значение свойства pwdLastSet в формат читаемой даты:

ConvrtFromFileTime

PasswordLastSet в свою очередь, отображает дату в читаемом формате. Но рассказ совсем не про этот параметр…

Сбрасываем время задания пароля

Параметр pwdLastSet помимо времени в наносекундах может принимать еще два значения:

  • 0 — сбрасывает счетчик в состояние «Пароль никогда не был задан»
  • -1 — сбрасывает значение на текущую дату и время

Вводить нужно команды последовательно.
Сначала задаем «0», потом «-1»

Проверяем результат

Введя эту команду мы увидим что значения pwdLastSet и PasswordLastSet изменились на текущую дату и время

Когда это может понадобится?

При активации парольной политики .
Если по какой то причине, вы использовали учетные записи с включенным свойством PasswordNeverExpires.
После активации политики, вы вероятно захотите снять данную галочку со всех учетных записей, и таким образом заблокируете эти учетки.
Это произойдет по той причине, что значение парольной политики «Enforce minimum password age» по умолчанию равно единице.
А дата установки пароля, вычтенная из
(Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.Days

при активации политики, будет иметь отрицательное значение(меньше единицы),
что приведет к автоматической блокировке учеток

Одна мысль про “Продление действия пароля учетной записи”

Какая замечательная информация. Такие грабли и конструкции для включения политики придуманы были.. ) Спасибо, может еще пригодиться. Очень хорошая инфа.

Когда истекает пароль пользователя в AD, оповещаем пользователей о необходимости сменить пароль

date16.04.2021
useritpro
directoryActive Directory, PowerShell, Windows 10, Windows Server 2016
commentsкомментария 44

В этой статье мы покажем, как с помощью PowerShell узнать, когда истекает пароль учетной записи пользователя в Active Directory, установить бессрочный пароль для учетной записи (PasswordNeverExpires = True) и заблаговременно оповестить пользователей о необходимости сменить пароль.

Если срок действия пароля пользователя в домене истек, учетная запись не блокируется, но не может использоваться для доступа к доменным ресурсам до тех пор, пока пользователь не сменит свой истекший пароль на новый. Чаще всего проблемы с истекшими паролями возникает у удаленных пользователей, которые не могут сменить свой пароль стандартными средствами.

Текущие настройки политики срока действия паролей в домене можно получить с помощью команды PowerShell

В нашем примере максимальный срок действия пароля пользователя в домене – 60 дней.

Get-ADDefaultDomainPasswordPolicy срок действия пароля в домене MaxPasswordAge

Как узнать срок действия пароля пользователя в Active Directory?

Можно узнать срок действия пароля и дату его последней смены из командной строки с помощь команды Net user:

net user aaivanov /domain

net user получить срок действия пароля

Необходимые данные присутствуют в значениях:

  • Password last set — 1/21/2020 11:18:37 AM
  • Password expires — 3/21/2020 11:18:37 AM
  • Password changeable — 1/22/2020 11:18:37 AM

Для получения параметров учетных записей в AD мы будем использовать специальный модуль PowerShell для Active Directory, который позволяет получить значения различных атрибутов объектов AD (см. как установить и импортировать модуль AD PowerShell в Windows 10 и Windows Server 2012 R2/2016).

С помощью командлета Get-AdUser можно получить время последней смены пароля пользователя и проверить, установлена ли опция бессрочного пароля (PasswordNeverExpires):

get-aduser aaivanov -properties PasswordLastSet, PasswordNeverExpires, PasswordExpired |ft Name, PasswordLastSet, PasswordNeverExpires,PasswordExpired

Get-aduser PasswordLastSet - время последней смены пароля

  • PasswordLastSet — время последней смены пароля пользователя;
  • PasswordNeverExpires – возвращает значение True, если пароль пользователя никогда не устаревает;
  • PasswordExpired – если пароль пользователя устарел — возвращает True, если пароль не устарел – False;

Но как вы видите, в оснастке указана только время смены пароля. Когда истекает срок действия пароля — непонятно.

pwdLastSet в свойтсвах пользователя

Чтобы получить не время последней смены пароля, а дату окончания его срока действия, нужно использовать специальный constructed-атрибут msDS-UserPasswordExpiryTimeComputed. Значение атрибута msDS-UserPasswordExpiryTimeComputed автоматически вычисляется на основании времени последней смены пароля и парольной политики домена

Параметр UserPasswordExpiryTimeComputed возвращает время в формате TimeStamp и для преобразования его в человеко-понятный вид я использую функцию FromFileTime:

Таким образом мы получили время истечения срока действия пароля пользователя.

атрибут UserPasswordExpiryTimeComputed - время истечения пароля пользователя

Чтобы получить срок действия паролей для всех пользователей их определенного контейнера (OU) AD, можно воспользоваться таким скриптом PowerShell:

$Users = Get-ADUser -SearchBase ‘OU=Users,OU=SPB,DC=corp,DC=winitpro,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
$Users | select Name, @>, PasswordLastSet

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

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

Можно вывести только список пользователей, чей пароль уже истек:

$Users = Get-ADUser -SearchBase ‘OU=Users,OU=SPB,DC=corp,DC=winitpro,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
foreach($user in $Users)<
if( [datetime]::FromFileTime($user.»msDS-UserPasswordExpiryTimeComputed») -lt (Get-Date)) <
$user.Name
>
>

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

Если вам нужно сделать срок действия пароля определенной учетной записи неограниченным, нужно включить опцию Password Never Expires в свойствах пользователя в AD (это одно из битовых значений атрибута UserAccountControl).

Password Never Expires

Либо вы можете включить эту опцию через PowerShell:

Get-ADUser aaivanov | Set-ADUser -PasswordNeverExpires:$True

Можно установить флаг Password Never Expires сразу для нескольких пользователей, список которых содержится в текстовом файле:

$users=Get-Content «C:\PS\users_never_expire.txt»
Foreach ($user in $users) <
Set-ADUser $user -PasswordNeverExpires:$True
>

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

Get-ADUser -filter * -properties Name, PasswordNeverExpires | where <$_.passwordNeverExpires -eq "true" >| Select-Object DistinguishedName,Name,Enabled |ft

Политика оповещения об окончании срока действия пароля

В Windows есть отдельный параметр групповой политики, позволяющий оповещать пользователей о необходимости сменить пароль.

Политика называется Interactive logon: Prompt user to change password before expiration и находится в разделе GPO Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Local Policies -> Security Options.

По умолчанию эту политика включена на уровне локальных настроек Windows и уведомления начинают появляться за 5 дней до истечения срока действия пароля. Вы можете изменить количество дней, в течении которых должно появляться уведомление о смене пароля.

политика уведомления о неоходимости смены пароля Interactive logon: Prompt user to change password before expiration

После включения этой политики, если пароль пользователя истекает, то при входе в систему в трее будет появляться уведомление о необходимости сменить пароль.

Consider changing your password

Также вы можете использовать простой PowerShel скрипт, который автоматически вызывает диалоговое окно со предложением сменить пароль, если он истекает менее чем через 5 дней:

Add-Type -AssemblyName PresentationFramework
$curruser= Get-ADUser -Identity $env:username -Properties ‘msDS-UserPasswordExpiryTimeComputed’,’PasswordNeverExpires’
if ( -not $curruser.’PasswordNeverExpires’) <
$timediff=(new-timespan -start (get-date) -end ([datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»))).Days
if ($timediff -lt 5) <
$msgBoxInput = [System.Windows.MessageBox]::Show(«Ваш пароль истекает через «+ $timediff + » дней!`nХотите сменить пароль сейчас?»,»Внимание!»,»YesNo»,»Warning»)
switch ($msgBoxInput) <
‘Yes’ <
cmd /c «explorer shell. <2559a1f2-21d7-11d4-bdaf-00c04f60b9f0>«
>
‘No’ < >
>
>
>

Если пользователь нажимает ДА, появляется диалоговое окно Windows Security, которое вы видите при нажатии Ctrl+Alt+Del или Ctrl+Alt+End (при RDP подключении).

Данный скрипт нужно поместить в автозагрузку или запускать как logon скрипт групповых политик.

PowerShell скрипт для email-уведомления об истечении срока действия пароля

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

$Sender /cdn-cgi/l/email-protection» data-cfemail=»c5acaba3aa85b2acabacb1b5b7aaebb7b0″>[email protected]»
$Subject = ‘Внимание! Скоро истекает срок действия Вашего пароля!’
$BodyTxt1 = ‘Срок действия Вашего пароля для’
$BodyTxt2 = ‘заканчивается через ‘
$BodyTxt3 = ‘дней. Не забудьте заранее сменить Ваш пароль. Если у вас есть вопросы, обратитесь в службу HelpDesk.’
$smtpserver =»smtp.domain.com»
$warnDays = (get-date).adddays(7)
$2Day = get-date
$Users = Get-ADUser -SearchBase ‘OU=Users,DC=corp,DC=winitpro,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, EmailAddress, Name | select Name, @>, EmailAddress
foreach ($user in $users) <
if (($user.ExpirationDate -lt $warnDays) -and ($2Day -lt $user.ExpirationDate) ) <
$lastdays = ( $user.ExpirationDate -$2Day).days
$EmailBody = $BodyTxt1, $user.name, $BodyTxt2, $lastdays, $BodyTxt3 -join ‘ ‘
Send-MailMessage -To $user.EmailAddress -From $Sender -SmtpServer $smtpserver -Subject $Subject -Body $EmailBody
>
>

Скрипт проверяет всех активных пользователей домена с истекающими паролями. За 7 дней до истечения пароля пользователю начинают отправляться письма на email адрес, указанный в AD. Письма отправляются до тех пор, пока пароль не будет изменен или просрочен.

Данный PowerShell скрипт нужно запускать регулярно на любом компьютере/сервере домена (проще всего через Task Scheduler). Естественно, нужно на вашем SMTP сервере добавить IP адрес хоста, с которого рассылаются письма, в разрешенные отправители без аутентификации.

Предыдущая статьяПредыдущая статья Следующая статья Следующая статья

page

page

page

alt=»создать gpo для подключения сетевых дисков» width=»58″ height=»56″ /> Подключение сетевых дисков в Windows через групповую политику
alt=»подключение принтеров пользователя через групповую политику» width=»58″ height=»56″ /> Установка принтеров с помощью групповых политик Active Directory
alt=»групповые политики office в домене» width=»58″ height=»56″ />Административные шаблоны MS Office (ADMX) групповых политик
Критическая уязвимость Active Directory Zerologon (CVE-2020-1472)

Последние официальные рекомендации — не включать функцию истечения паролей. Безопасности не прибавляет и даже наоборот — снижает. И геморроя прибавляет изрядно.

Дайте ссылку пожалуйста на официальную рекомендацию.

Здесь история вопроса: https://habr.com/ru/post/357406/
Здесь про рекомендации MS и некоторые разъяснения: https://habr.com/ru/company/globalsign/blog/457036/
Там же и ссылка на Technet есть.

Здесь больше интересна именно история вопроса — откуда это пошло и к чему в итоге пришло. MS здесь не выступает первоисточником но и они в итоге сейчас рекомендуют отказаться от этой практики.

А теперь на секунду представьте на секунду — Вы в отпуске, а у пользователей истек срок действия паролей, естественно «у меня ничего не получилось», в итоге «работа простаивает, мне надо срочно» — уже нравится? Так можно делать когда все пользователи достаточно грамотные, чтобы разобраться самостоятельно, но, учитывая повальную экономию на всём — ситуация далеко не такая радостная.

Можно скрипт с аутентификацией по SMTP?

$emailSmtpServer = «mail_server»
$emailSmtpServerPort = «xxx»
$emailSmtpUser = «user_name_1»
$emailSmtpPass = «Password»
$emailFrom = «[email protected]»
$emailTo = «[email protected]»
$encoding = [System.Text.Encoding]::UTF8

нету таких команд, зачем вводить заблуждение людей ?

1)
Класс [System.Windows.MessageBox] будет работать только после добавления ассамблеи PresentationFramework через Add-Type. В противном случае будете получать ошибку «Unable to find type [System.Windows.MessageBox]». Соответственно это необходимо добавить в начале скрипта.

2)
cmd /c «explorer shell. <2559a1f2-21d7-11d4-bdaf-00c04f60b9f0>» Не будет это работать в консольной сессии. Это работает при подключении к серверу по RDP

3)
Get-ADUser -filter * -properties Name, PasswordNeverExpires | where <$_.passwordNeverExpires -eq «true» >
Зачем делать -filter * и потом выбирать из этого массива?? лучше и быстрее использовать server-side фильтры Get-ADUser -filter ‘PasswordNeverExpires -eq True’

4) В начале в паре мест лишним берете свойство ‘CannotChangePassword’ и потом его не используете. Нужно убрать его, чтобы не отвлекало.

дальше уже стало неинтересно проверять. На мой взгляд необходимо доработать и проверять перед публикацией в будущем.

Подскажите, пожалуйста, по Вашему первому пункту: в какую часть скрипта (после каких команд или строк) нужно добавить асамблею «PresentationFramework через Add-Type», чтобы избавиться от ошибки Unable to find type [System.Windows.MessageBox]» ?! И если не сложно, то как будет выглядеть ПРАВИЛЬНЫЙ итоговый скрипт в данном случае?!

Добавил в скрипт строку Add-Type -AssemblyName PresentationFramework

Погуглил, как на русскоязычных сайтах так и на буржуйских, а также поспрашивал на форумах по этому вопросу. В итоге получается следующая конструкция:
try <
Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms
> catch <
Throw «Failed to load Windows Presentation Framework assemblies.»
>
$curruser= Get-ADUser -Identity $env:username -Properties ‘msDS-UserPasswordExpiryTimeComputed’,’PasswordNeverExpires’
if ( -not $curruser.’PasswordNeverExpires’) <
$timediff=(new-timespan -start (get-date) -end ([datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»))).Days
if ($timediff -lt 10) <
$msgBoxInput = [System.Windows.MessageBox]::Show(«Ваш пароль истекает через «+ $timediff + » дней!`nХотите сменить пароль сейчас?»,»Внимание!»,»YesNo»,»Warning»)
switch ($msgBoxInput) <
‘Yes’ <
cmd /c «explorer shell. <2559a1f2-21d7-11d4-bdaf-00c04f60b9f0>»
>
‘No’ < >
>
>
>

Но, тут опять таки — вот эта строчка в скрипте:
[datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»)

возвращает вам пустое значение, которое потом интерпретируется как 1 января 1601 года.

Прошу Вас помочь скорректировать указанную строку! Спасибо!

Попробуйте использовать такой блок:

$curruser= Get-ADUser -Identity $env:username -Properties ‘msDS-UserPasswordExpiryTimeComputed’,’PasswordNeverExpires’
if ( -not $curruser.’PasswordNeverExpires’) <
$timediff=(new-timespan -start (get-date) -end ([datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»))).Days
У меня все работает…
Если нет, после первой строки попробуйте вывести содержимое атрибута:
write-host $curruser.»msDS-UserPasswordExpiryTimeComputed»
write-host ([datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»))
Возвращаются значения?

Подскажите как сделать экспорт скрипта в файл, который указан в Вашей статье:
$Users = Get-ADUser -SearchBase ‘OU=Users,OU=SPB,DC=corp,DC=winitpro,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
foreach($user in $Users) <
if( [datetime]::FromFileTime($user.»msDS-UserPasswordExpiryTimeComputed») -lt (Get-Date)) <
$user.Name
>
>

Добавляю в начале
$lastday = ((Get-Date).AddDays(-1))
$filename = Get-Date -Format yyyy.MM.dd
$exportcsv=”c:\ps\expired_password_” + $filename + “.cvs”

В конце
Export-csv -path $exportcsv

Придется внутри цикла foreach собирать массив New-Object
Или можно добавлять данные в csv файл построчно:
$user |select-object name| Export-csv -path $exportcsv -append

У меня в итоге вот так получилось:

$filename = Get-Date -Format yyyy.dd.mm
$exportcsv=”c:\ps\expired_password_” + $filename + “.csv”
$Users = Get-ADUser -SearchBase ‘OU=xxx,DC=fmarket,DC=local’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
foreach($user in $Users) <
if( [datetime]::FromFileTime($user.»msDS-UserPasswordExpiryTimeComputed») -lt (Get-Date)) <
$user.Name
Export-csv -InputObject ($user | select DistinguishedName) -Path $exportcsv -Delimiter «;» -Encoding Unicode -NoTypeInformation -append -Force
>
>

Подскажите пжста, почему письма приходят в некорректной кодировке (вопросиками), такс написан на русском

Попробуйте задать кодировку UTF8 в скрипте:

.
$EmailBody = $BodyTxt1, $user.name, $BodyTxt2, $lastdays, $BodyTxt3 -join ‘ ‘
$encoding = [System.Text.Encoding]::UTF8
Send-MailMessage -To $user.EmailAddress -From $Sender -SmtpServer $smtpserver -Subject $Subject -Body $EmailBody -Encoding $encoding
.

Здравствуйте пишу ваш скрипт
$Users = Get-ADUser -SearchBase ‘OU=Моя компания,DC=office,DC=local’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword $Users | select Name, @>, PasswordLastSet

Непредвиденная лексема «(» в выражении или операторе.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken

что не так подскажите

Попробуйте отладить команду частями. Возможно какие-то символы неправильно скопировались с сайта (есть у WordPress такой глюк). Проверьте двойные кавычки, не больно быть елочек.

А можно изменить само сообщение о том, что «пароль не соответствует требованиям ИБ…»? Ну например, добавить сами требования в это сообщение?

Вы про какое сообщение?
Мне кажется тут достаточно настроить правильные доменные политики паролей, которые не дадут пользователю поставить слишком простой или старый пароль.

В строке по выгрузке срока действия паролей нужно убрать пробел перед скобкой FromFileTime ($_.»msDS-

Всем привет!
Подготовлен готовый механизм оповещения пользователей по ЭЛЕКТРОННОЙ ПОЧТЕ (за 14, 7, 2 дня) о скором окончании срока действия доменного пароля. Может кому-нибудь будет интересен данный механизм:

function notificationUser <
param (
[parameter(Mandatory=$true, Position=0)]
[string]$fullName,

[parameter(Mandatory=$true, Position=1)]
[string]$email,

[parameter(Mandatory=$true, Position=2)]
[string]$daysAwayFrom
)

$SubjectMail = «Через $daysAwayFrom дня(-ей) закончится срок действия вашего доменного пароля.»
$Body = @»
ТЕМА СООБЩЕНИЯ
«@

Добрый день,
Подскажите пожалуйста, когда запрос:
Get-ADUser -Identity avivanov -Properties msDS-UserPasswordExpiryTimeComputed | select-object @>
выполняю в консоли powershell выводиться результат запроса.
Но когда запрос сохраняю в файле ps1 и выполняю его, результат выполнения запроса — пустой.
В чем может быть причина?

Может кто-нибудь подсказать по этой программе?

Запускаете вручную из-под той же учетной записи, что и команду в консоли?
Или отрабатывает некий планировщик из-под другой учетной записи.
Проверил у себя — команда отрабатывает и в консоли и в консоли через скрипт. запускаю так:
PS C:\PS> .\test_ad_powershell.ps1

Запускаете вручную из-под той же учетной записи, что и команду в консоли? — Да
Запускаю так: на файле ps1 с запросом, правой кнопкой мыши->Выполнить с помощью PowerShell и результат пустой, но, скопировав содержимое ps1 файла в консоль PowerShell и нажав ввод, получаю искомый результат. Вот не могу понять в чем дело?

Понял вас. Нужно в скрипте указывать принудительный вывод в консоль:
import-module activedirectory
$a=Get-ADUser username1 -Properties msDS-UserPasswordExpiryTimeComputed | select-object @>
write-host $a
Read-Host -Prompt «Press any key to continue «

При таком запросе результат, при «Запускаю так: на файле ps1 с запросом, правой кнопкой мыши->Выполнить с помощью PowerShell», выводиться в виде: @ — не очень красиво, т.к. со спец.символами @<>.

Сделал так, добавил вывод результата в виде списка, fl:
get-aduser -identity user -properties msds-userpasswordexpirytimecomputed | select-object @> | fl

Write-Host -NoNewLine ‘Press any key to continue…’;
$null = $Host.UI.RawUI.ReadKey(‘NoEcho,IncludeKeyDown’);

Спасибо, за помощь.

Если нужно быстро продлить пароль пользователя, и не ставить галку password newer expires, воспользуйтесь командой:
Set-ADUser -Identity username -Replace @Set-ADUser -Identity username -Replace @ Команда сбросит счетчик пароля, пользователь сможет зайти на компьютер, а уведомление сменить пароль появится только в следующий период.

Добавил в скрипт проверку сеанса, консоль или RDP, для запуска соответствуещей процедуры смены пароля. Также вывод окна сделал через vbs так-как даже через (System.Windows.Forms.Form -property @) вывод окна повер всех на Windows 7, в реализации через task, решить не удалось. Скрипт запускается через task(есть встроенные триггеры на вход, разблокировку, подключение к сеансу), команда «powershell -nologo -noninteractive -windowStyle hidden -command PasswordExpiriesEvent.ps1» для скрытого выполнения. Выполнение ctrl-alt-delete сделал через «(New-Object -COM Shell.Application).WindowsSecurity()», чтоб не запускать cmd, закоментил.

Add-Type -AssemblyName Microsoft.VisualBasic
$curruser= Get-ADUser -Identity $env:username -Properties ‘msDS-UserPasswordExpiryTimeComputed’,’PasswordNeverExpires’
if ( -not $curruser.’PasswordNeverExpires’) <
$timediff=(new-timespan -start (get-date) -end ([datetime]::FromFileTime($curruser.»msDS-UserPasswordExpiryTimeComputed»))).Days
if ($timediff -lt 180) <
$text = «Ваш пароль истекает через «+ $timediff + » дней!`nХотите сменить пароль сейчас?»
$msgboxtype = «YesNo,SystemModal,Information»
$title = «Внимание!»
$msgBoxInput = [Microsoft.VisualBasic.Interaction]::MsgBox($text,$msgboxtype,$title)
switch ($msgBoxInput) <
‘Yes’ <
$Console = quser | Select-String -Pattern «>»| Select-String -Pattern «console» -Quiet
if ( $Console ) <
Start-Process -FilePath powershell -ArgumentList «-command Set-ADAccountPassword -Identity $env:username ; pause»
>
else <
#cmd /c «C:\Windows\explorer.exe shell. <2559a1f2-21d7-11d4-bdaf-00c04f60b9f0>»
(New-Object -COM Shell.Application).WindowsSecurity()
>
>
‘No’ < >
>
>
>

ЕЩЕ
Если кто подскажет как определить сеанс (RDP/Console) более изящно, а то получилось топорно �� буду признателен. Опять же при выполнении скрипта как task, процедура получения сеанса через $env:SESSIONNAME не проходит, при выполнении как task данная переменная пуста.

Спасибо за дополнения. Я только непонял зачем нужно условие проверки консолььной сессии?
if ( $Console ) <
Start-Process -FilePath powershell -ArgumentList «-command Set-ADAccountPassword -Identity $env:username ; pause»

$env:SESSIONNAME при запуске через task будет пустым, т.к. по сути пользователь под которым запускается код не выполнил в ход

Если пользователь подключен к ПК через консоль то команда:
#cmd /c «C:\Windows\explorer.exe shell. <2559a1f2-21d7-11d4-bdaf-00c04f60b9f0>»
(New-Object -COM Shell.Application).WindowsSecurity()
не сработает.
Можно в принципе не делать использовать смену всегда через команду powershell (Start-Process -FilePath powershell -ArgumentList «-command Set-ADAccountPassword -Identity $env:username ; pause»)

Что не так? Почему ошибка? как исправить?:

Get-ADUser : Объект каталога не найден
C:\Users\bovin_km\Desktop\PassworExpiryDate_1_test.ps1:11 знак:10
+ $Users = Get-ADUser -SearchBase ‘OU=Users,DC=corp,DC=avtodor-eng,DC=ru’ -filter …
+

+ CategoryInfo : ObjectNotFound: (:) [Get-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser

сам код:
#даже если здесь вставить:
Import-Module ActiveDirectory

$Sender = «[email protected]»
$From = «[email protected]»
$Subject = ‘Внимание! Скоро истекает срок действия Вашего пароля!’
$BodyTxt1 = ‘Срок действия Вашего пароля для’
$BodyTxt2 = ‘заканчивается через ‘
$BodyTxt3 = ‘дней. Не забудьте заранее сменить Ваш пароль используя ALT+CTRL+DEL, выберите «Сменить пароль…»; либо _https://mail.contoso.ru/ecp/?rfr=owa&owaparam=modurl%3D0&p=account. Не забудьте ввести новый пароль в настройках почты в мобильном телефоне.
Если у вас есть вопросы, обратитесь в службу HelpDesk.’
$smtpserver =»mail.contoso.ru»
$warnDays = (get-date).adddays(14)
$2Day = get-date
$Users = Get-ADUser -SearchBase ‘OU=Users,DC=corp,DC=contoso,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, EmailAddress, Name | select Name, @>, EmailAddress
foreach ($user in $users) <
if (($user.ExpirationDate -lt $warnDays) -and ($2Day -lt $user.ExpirationDate) ) <
$lastdays = ( $user.ExpirationDate -$2Day).days
$EmailBody = $BodyTxt1, $user.name, $BodyTxt2, $lastdays, $BodyTxt3 -join ‘ ‘
Send-MailMessage -To $user.EmailAddress -From $Sender -SmtpServer $smtpserver -Subject $Subject -Body $EmailBody
>
>

ОТВЕТ:
для понимания зайти в AD, в свойствах контейнера в редакторе атрибутов посмотреть distinguishedName.
и без пробелов это все пишется (или копи-паст)

рабочий код:
$Sender = «[email protected]»
$From = «[email protected]»
$Subject = ‘Внимание! Скоро истекает срок действия Вашего пароля!’
$BodyTxt1 = ‘Срок действия Вашего пароля для’
$BodyTxt2 = ‘заканчивается через ‘
$BodyTxt3 = ‘дней. Не забудьте заранее сменить Ваш пароль используя ALT+CTRL+DEL, выберите «Сменить пароль…»; либо _https://mail.contoso.ru/ecp/?rfr=owa&owaparam=modurl%3D0&p=account. Не забудьте ввести новый пароль в настройках почты в мобильном телефоне.
Если у вас есть вопросы, обратитесь в службу HelpDesk.’
$smtpserver =»mail.contoso.ru»
$warnDays = (get-date).adddays(14)
$2Day = get-date
$Users = Get-ADUser -SearchBase ‘OU=Users,OU=Avtor_ENG,DC=corp,DC=contoso,DC=ru’ -filter -Properties msDS-UserPasswordExpiryTimeComputed, EmailAddress, Name | select Name, @>, EmailAddress
foreach ($user in $users) <
if (($user.ExpirationDate -lt $warnDays) -and ($2Day -lt $user.ExpirationDate) ) <
$lastdays = ( $user.ExpirationDate -$2Day).days
$EmailBody = $BodyTxt1, $user.name, $BodyTxt2, $lastdays, $BodyTxt3 -join ‘ ‘
Send-MailMessage -To $user.EmailAddress -From $Sender -SmtpServer $smtpserver -Subject $Subject -Body $EmailBody
>
>

А как добавить к -PasswordNeverExpires $false временный промежуток? Т. е. написать скрипт, чтоб, например, пароль сбрасывался через 30 дней?

Как вариант, можно создать для этого аккаунта отдельную Fine-Grained Password Policy
Или создать задание планировщика на DC..

При использовании кода

У пользователя нет галки «Срок действия пароля неограничен».
Так же пользователю менялся пароль, но всё равно PasswordLastSet -скрипт выдаёт пустое поле (хотя в свойствах пользователя в редакторе атрибутов pwdLastSet заполнена корректно.

Подскажите пожалуйста в чём может быть проблема?

Вопрос отпал.
Если у кого-то такая же проблема, надо запускать не PowerShell, а «Модуль Active Directory для Windows PowerShell» в режиме администратора. Тогда всё работает корректно.

Добрый день,
А такой вот вопрос…
а как сдлать выводимый текст в писме столбиком?
сейчас всё что написано идёт одной строкой, а вот если надо разбить на предложения и обзацы?

ИСпользуйте HTML форматирование:
$EmailBody = @»
<p>$BodyTxt1 $user.name</p>
<p>$BodyTxt2, $lastdays, $BodyTxt3</p>
«@
+ в Send-MailMessage нужно добавьть параметр -BodyAsHtml

Спасибо, получилось ��
Только теперь имя пользователя дублируется
Срок действия Вашего пароля для @.name
странно. как то ….

LDAP-фильтры для поиска объектов в Active Directory. Часть 3

У командлетов Get-ADUser, Get-ADComputer, Get-ADGroup и Get-ADObject имеется параметр LdapFilter, специально предназначенный для использования LDAP-фильтров при поиске объектов в Active Directory. Для примера найдем всех пользователей с именем Vasya с помощью такой команды:

Get-ADUser -LdapFilter «(cn=Vasya)»

команда get-aduser

Большинство командлетов для поиска являются узкоспециализированными, т.е. предназначены только для определенного типа объектов (пользователи, компьютеры и т.п.). Исключение составляет командлет Get-ADObject, который может искать любые объекты. Например:

Get-ADObject -LdapFilter «(cn=Vasya)»

команда get-adobject

При использовании Get-ADObject мы получили не только пользователей, а все объекты с указанным в фильтре именем. Если требуется найти только пользователей, то надо в фильтре добавлять дополнительные параметры. Например:

Get-ADObject -LdapFilter «(&(objectCategory=person)(objectClass=user)(cn=Vasya))»

команда get-adobject с дополнительными фильтрами

При помощи LDAP-фильтра нельзя указать область поиска. Для примера найдем всех пользователей, у которых в описании (Description) имеется слово Руководитель:

Get-ADObject -LdapFilter «(Title=Руководитель*)» -Properties * | ft -a DisplayName,Title

Эта команда произведет поиск по всему домену и выдаст всех найденных пользователей, вне зависимости от их местоположения.

поиск по всему домену

Для уточнения области поиска есть параметр SearchBase, с помощью которого можно указать для поиска конкретное подразделение (OU), например:

Get-ADObject -LdapFilter «(Title=Руководитель*)» -Properties * -SearchBase «OU=Employees,DC=Test,DC=local | ft -a DisplayName,Title

ограничение области поиска с помощью параметра Searchbase

Еще один полезный параметр Subtree, с помощью которого можно ограничить глубину поиска. Этот параметр может принимать 3 значения:

• Base (0) — поиск только по указанному в запросе объекту. В результате поиска возвращается либо один объект, либо ничего. Данная область, как правило, используется для проверки наличия объекта.
• One level (1) — поиск только по дочерним объектам указанного объекта. Поиск по вложенным объектам не производится, также в результаты поиск не попадает сам базовый объект.
• Subtree (2) — поиск по всем дочерним объектам, включая вложенные. Сам базовый объект в поиск не попадает. Это значение используется по умолчанию.

Для примера возьмем предыдущую команду и ограничим поиск верхним уровнем (OneLevel):

Get-ADObject -LdapFilter «(Title=Руководитель*)» -Properties * -SearchBase «OU=Employees,DC=Test,DC=local -SearcScope OneLevel | ft -a DisplayName,Title,DistinguishedName

ограничение глубины поиска с помощью параметра Searchscope

А затем зададим поиск по всем вложенным объектам (Subtree):

Get-ADObject -LdapFilter «(Title=Руководитель*)» -Properties * -SearchBase «OU=Employees,DC=Test,DC=local -SearcScope SubTree | ft -a DisplayName,Title,DistinguishedName

Как видите, разница очевидна.

поиск по всему дереву без ограничений

Для работы с Active Directory из командной строки существует великое множество различных утилит. Мы рассмотрим две наиболее часто используемые для поиска — dsquery и dsget.

Утилита dsquery возвращает различающееся имя (Distinquished Name) объекта, подходящего под заданные параметры, а для LDAP-фильтров у нее имеется параметр filter. К примеру, предыдущий запрос с использованием dsquery будет выглядеть так:

dsquery * OU=Employees,DC=test,DC=local -filter «(&(objectCategory=person)(objectClass=user)(Title=Руководитель*))» -Scope OneLevel

поиск с помощью dsquery

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

dsquery * OU=Employees,DC=test,DC=local -filter «(&(objectCategory=person)(objectClass=user)(Title=Руководитель*))» | dsget user -display -title -dn

совместное использование dsquery и dsget

ADSIEdit

Переходим к графическим утилитам. Оснастка ADSIEdit поддерживает использование LDAP-фильтров. Для добавления фильтра надо кликнуть по выбраному контексту именования (NC) и в контекстном меню выбрать пункт New — Query…

фильтры в ADSIEdit

В открывшемся окне указываем имя запроса, выбираем область поиска (Root of Search) и в поле Query String добавляем нужный фильтр. Для примера отберем всех отключенных пользователей. Дополнительно можно выбрать глубину поиска Subtree или One level.

создание фильтра в ADSIEdit

В результате получим что то вроде этого.

результат работы фильтра в ADSIEdit

Active Directory Users and Computers

В оснастке Active Directory Users and Computers (ADUC) имеется функция Saved Queries, которая представляет из себя сохраненные LDAP-фильтры. Для создания сохраненного запроса кликаем правой клавишей мыши и выбираем New — Query.

фильтры в ADUC

Даем запросу понятное имя и описание, в Query root выбираем область поиска и отмечаем пункт Include subconteiners (аналог Subtree) для поиска по всем вложенным объектам. Затем жмем кнопку Define Query.

создание фильтра в ADUC

Оснастка поддерживает несколько режимов и в принципе вовсе не обязательно писать текст фильтра вручную. Для наиболее часто встречающихся ситуаций достаточно выбрать нужный пункт и\или поставить галочку. Например, для показа всех пользователей с бессрочным паролем можно просто отметить чекбокс Non expiring passwords

общие запросы

готовый фильтр в ADUC

Но мы не ищем легких путей, поэтому зададим фильтр руками. Для этого выбираем режим Custom Search и на вкладке Advanced вводим текст фильтра.

кастомные фильтрв в ADUC

В результате в папке Saved Queries появляется список пользователей, у которых пароль не истекает. Таким же образом можно отслеживать множестао различных параметров пользователей, компьютеров и т.д.

результат работы фильтра в ADUC

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

экспорт отфильтрованного списка

Примеры LDAP-фильтров

В заключение приведу примеры наиболее часто используемых LDAP-фильтров. Для удобства фильтры сгруппированы по типу объектов (пользователи, компьютеры, группы и прочие непонятные сущности).

Все пользователи:

Фильтр с использованием sAMAccountType более эффективен для объекта пользователь.

Все отключенные (Disabled) пользователи:

Все пользователи кроме отключенных:

Заблокированные (Locked) пользователи:

Здесь используется атрибут badPwdCount, в котором хранится количество неудачных попыток ввода пароля пользователем. Значение нужно указывать в соответствии с политиками безопасности вашего домена.

Пользователи, не менявшие пароль более 3 месяцев:

Атрибут pwdlastSet содержит в себе дату и время последней смены пароля пользователем. Он имеет тип Integer8 и представляет собой число временных интервалов длительностью 100 наносекунд, прошедших с 12:00 01.01.1601 (UTC). Получить требуемое значение можно с помощью PowerShell, например:

Пользователи, у которых пароль не истекает (Password newer expires):

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

Если значение атрибута pwdlastSet равно 0 и при этом в свойствах учетной записи не отмечен пункт Password newer expires, то пользователь должен сменить пароль при следующем входе.

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

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

Пользователи, у которых срок действия учетной записи не ограничен:

Атрибут accountExpires содержит дату истечения срока действия учетной записи и тоже представляет из себя число 100нс интервалов, прошедших с 01.01.1601 (UTC). Значение 0 или 9223372036854775807 (максимально возможное 64-битное число) означает, что срок действия учетной записи никогда не истечет.

Пользователи, созданные за определенный период:

В первом случае мы указываем только начальный период, во втором ограничиваем и начальный и конечный. Формат даты используется следующий:

YYYY MM DD HH mm ss.s Z

2020 01 01 00 00 00.0 Z

Кстати, таким образом можно искать не только пользователей, но и любые другие объекты в AD (компьютеры, группы и т.п.).

Пользователи, не заходившие в систему более чем 3 месяца:

Атрибуты lastLogon и lastLogonTimeStamp имеют такой же кривой тип, как pwdLastSet, и вычисляются таким же образом. Но между ними есть кардинальные различия, о которых необходимо знать.

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

lastLogonTimeStamp также изменяется при входе пользователя, при этом он реплицируется на все контроллеры домена. Но сама репликация происходит с большой задержкой, порядка 9-14 дней. Поэтому полученные с его помощью данные могут быть не очень актуальны.

Пользователи, никогда не заходившие в систему:

Пользователи с почтовыми ящиками:

Пользователи, скрытые из адресной книги:

Все компьютеры:

Все компьютеры с определенной ОС:

Вместо Windows 7 можно поставить любую требуемую ОС.

Все серверы (компьютеры с серверной ОС):

Все контроллеры домена:

Контроллеры домена, доступные только для чтения:

Все серверы, не являющиеся контроллерами домена:

SQL серверы:

Exchange серверы:

Все группы:

Все локальные (Domain local) группы:

Все глобальные (Global) группы:

Все универсальные (Universal) группы:

Все группы безопасности (Security):

Все группы рассылки (Distribution):

Во втором случае ищутся все группы, имеющие почтовый адрес. Напомню, что группы безопасности также могут иметь почтовый адрес и использоваться для рассылки.

Все локальные группы безопасности:

Атрибуты userAccountControl и groupType принимают целочисленные 32-битные значения, т.е. лежат в диапазоне от -2 31 (-2147483648) до 2 31 (2147483647). Значение атрибутов является результатом операции побитового ИЛИ. Например, значение groupType для локальной группы безопасности определяется путем применения операции ИЛИ к маске локальной группы (4) и группы безопасности (2147483648). В результате получается число 2147483652. Поскольку данное значение превышает максимально возможное для 32-битного числа, то оно конвертируется в отрицательное путем вычитания из него 2 32 (4294967296). Получается 2147483652 — 4294967296 = -2 147 483 644.

Теоретически правильно использовать отрицательное значение, на практике работают оба.

Все глобальные группы безопасности:

Все универсальные группы безопасности:

Все встроенные группы (BuiltIn):

Все глобальные группы рассылки:

У группы безопасности восьмой бит должен быть установлен в 1, соответственно значение маски равно 2147483648. У группы рассылки этот бит установлен в о, соответственно и значение маски равно 0. Отсюда получаем значение 0 (Distribution) + 2 (Global) = 2 (Global Distribution Group).

Все локальные группы рассылки:

Все универсальные группы рассылки:

Все члены группы (без учета вложенности):

Все члены группы с учетом вложенности:

Все пользователи, не являющиеся членами группы (с учетом вложенности):

Все группы, в которые входит пользователь:

Все группы, в которые входит пользователь (с учетом вложенности):

Все пустые группы:

Все подразделения (OU):

Все контейнеры (CN):

Все встроенные контейнеры:

Все объекты групповой политики:

Все отношения доверия:

Все связи между сайтами в контейнере конфигурации:

Для запросов к атрибутам конфигурации нужно использовать поиск по контейнеру Configuration (напр. cn=Configuration,dc=test,dc=local).

Объекты, защищенные AdminSDHolder:

AdminSDHolder — это механизм защиты административных учетных записей. Если пользователь является членом защищенной группы (Domain Admins, Enterprise Admins и т.п.) то его учетной записи назначаются разрешения, установленные в объекте AdminSDHolder, а атрибуту adminCount пользователя присваивается значение 1.

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

Объекты, которые не могут быть удалены:

Атрибут systemFlags определяет дополнительные свойства объекта и представляет из себя битовую маску.

Объекты, которые не могут быть перенесены:

Объекты, которые не могут быть переименованы:

Атрибуты, помеченные в схеме как конфиденциальные:

Атрибут searchFlags определяет правила поиска и индексации для атрибута и представляет из себя битовую маску.

Атрибуты, сохраняемые в объекте захоронении (tombstone) при удалении объекта:

Объекты nTDSDSA связанные с глобальным каталогом:

С помощью этого запроса можно найти серверы глобального каталога. Поиск нужно проводить по контейнеру конфигурации. Подробнее об объектах nTDSDSA и их атрибутах.

Объекты nTDSDSA связанные с ролями FSMO:

Для ролей PDC Emulator, RID Master и Infrastructure Master нужно опрашивать домен. Владельца роли Schema Master нужно искать в контейнере Schema (напр. cn=Schema,cn=Configuration,dc=test,dc=local), а владельца Domain Naming Master — в контейнере Configuration (напр. cn=Configuration,dc=test,dc=local).

Аудит учетных записей пользователей в Active Directory

Вместо предисловия
Поводом для появления данной статьи послужила информация, опубликованная в журнале Windows & .Net Magazine/RE №5 за 2003 год под названием «Утилита LDIF Directory Exchange», которая подсказала решения, которые можно было использовать для того, чтобы обеспечить необходимый уровень автоматизации при проведении аудита учетных записей пользователей в Active Directory. В статье было приведено описание основных возможностей двух утилит, Ldifde.exe и Csvde.exe, обеспечивающих добавление, изменение и удаление объектов Active Directory.
Информация, изложенная ниже, ориентирована на использование Windows-платформ и предназначена, в основном, для людей, отвечающих за вопросы компьютерной безопасности, аудиторов, специализирующихся в данной области. Надеемся, что статья будет полезна и людям, профессионально занимающимся администрированием локальных сетей.

Постановка проблемных вопросов
В определенный момент времени наступает то критическое состояние для списка пользователей локальной сети предприятия, когда нежелание остановиться и провести анализ его содержимого может повлечь большие затраты и проблемы, нежели своевременное проведение работ по аудиту и устранению выявленных недостатков.
О чем идет речь? Речь о следующем. В организациях, где число сотрудников, работающих с компьютерной техникой, превышает 100 человек, администрированием занимаются, как правило, два-три сотрудника. Не все они в силу различных обстоятельств с достаточным педантизмом относятся к работе по внесению во вновь создаваемые учетные записи информации о владельцах. Кроме того, администраторы обычно:-) не включены в список тех сотрудников, которым обязаны сообщать об увольнениях. Два этих обстоятельства являются основными причинами, из-за которых и происходит накопление учетных записей «мертвых душ».
Попробуем провести некоторую систематизацию наиболее значимых и очевидных проблем для списка пользователей Active Directory.

Во-первых, лишние записи в списке пользователей, которые могут быть:
• учетными записями уволенных сотрудников;
• учетными записями работающих сотрудников, которыми не пользуются и владельцы которых уже вряд ли помнят имена для входа в сеть (не говоря уже о паролях:-));
• учетными записями заблокированных пользователей, для которых администратор выполнил первый шаг перед удалением, но так и не закончил процедуру;
• учетными записями, созданными для тестирования, которые обычно имеют достаточно высокие привилегии и которые администратор забыл удалить, после того как процесс тестирования был завершен.

Во-вторых, к недопустимым можно отнести те учетные записи, которые однозначно не идентифицируют владельца, т.е. дополнительная информация в которых не позволяет назвать человека, определить его должность и подразделение, выяснить, как с ним можно связаться (конечно же, речь здесь не идет о стандартных учетных записях типа «Администратор», «Administrator», «Guest», «Гость», и др).
И, в-третьих, выполнение требований политики безопасности предприятия подразумевает, что усилия и администраторов, и пользователей должны быть направлены на то, чтобы учетная запись использовалась только ее владельцем. То есть, если протокол выполнения операций работы с какой-либо из программ показал, что пользователь вошел под учетной записью Иванова Ивана Ивановича, то абсолютно нерационально будет тратить время на дополнительные разборки с ситуациями, когда выясняется, что учетной записью пользуются (из-за недостаточных знаний компьютера или обычной лени) все сотрудники отдела, в котором трудится пять человек.

Обзор возможностей по работе с учетными записями
Попробуем перечислить те возможности, которые есть под руками у администратора для работы с учетными записями пользователей в Active Directory, и то, насколько они могут быть использованы для проведения аудита.
Оснастка Active Directory — пользователи и компьютеры (которую можно найти в разделе Администрирование на сервере). Замечательная возможность для добавления, редактирования свойств и удаления пользователей домена, но, к сожалению, достаточно бесполезная в вопросах проведения ревизии и аудита. К положительным моментам можно отнести возможность проведения экспорта списка пользователей, в который можно включить такие поля, как Имя входа пользователя, Имя, Выводимое имя, Фамилия, Изменен. Отметим, что поле Изменен показывает время и дату последних изменений для учетной записи администратором (производилась коррекция настроек) или владельцем (смена пароля).
Системная утилита Net.exe. С помощью этой утилиты вы можете обеспечить работу с данными конкретного пользователя (вариант вызова — Net user) — получить дату и время последней регистрации в сети, а также определить, когда завершается срок действия пароля.

Программы-сканеры, задача которых заключается в сборе информации о состоянии локальной сети или конкретного компьютера. Среди наиболее интересных программ в плане получения информации о пользователях отметим CFI LANguard Network Security Scanner (ver 3.1.5). Она предоставляет возможность получения достаточно подробной информации об учетных записях: дата и время последней регистрации; данные о том, когда пароль будет просрочен; количество регистраций пользователя в сети; значение индекса попыток входа с некорректным паролем. Кроме того, программа позволяет на основании данных двух сохраненных протоколов сканирования сформировать отчет о расхождениях и получить перечень заведенных и удаленных учетных записей. Справедливости ради отметим, что программа имеет существенные недостатки особенно для русскоязычной категории пользователей, так как некорректно обрабатывает русские названия (в именах и дополнительных параметрах учетных записей и пр.). Кроме того, отсутствует возможность сохранить в отдельном файле информацию о найденных расхождениях в списках учетных записей.
Перейдем теперь к рассмотрению утилит, которые, на наш взгляд, предоставляют возможность получения наиболее полной информации по пользователям, — Ldifde.exe и Csvde.exe.

Первая утилита позволяет экспортировать данные из Active Directory в файл формата LDIF. Стандарт файла LDIF определен в рекомендациях RFC-2849 для импорта и экспорта данных из каталогов LDAP, таких, как Active Directory. После экспорта данных можно использовать LDIF-файл для импорта тех же объектов в другой каталог LDAP.
Csvde.exe — утилита, аналогичная Ldifde.exe (параметры вызова идентичны), в которой используется другой формат хранения данных в текстовом файле — значения разделяются запятыми (CSV-формат). Данный формат поддерживается программой Microsoft Excel, понимающей файлы в CSV-формате, а также Microsoft Access.

Использование утилиты Csvde.exe
Для наглядности вместо полного описания параметров работы с утилитой приведем пример, на основе которого можно построить запросы для всех необходимых для аудита случаев.
csvde -f USERS_WOKR.CSV -b GUEST MICROSOFT *
-r «(&(objectClass=user)(! (objectClass=computer))(!(user AccountControl=514))(!(userAccountControl=66050)))»
-l «DN, memberOf, badPassword Time, lastLogon, logonCount, sAM AccountName, userAccountCon- trol, whenChanged, whenCreated»
Использование данной команды позволяет сохранить в файле наиболее интересную с точки зрения аудита информацию по действующим (незаблокированным) учетным записям пользователей.
В файл USER_WORK.CSV (параметр -f) будут записаны данные учетных записей пользователей домена. Программа будет производить обработку данных, которые должны быть доступны пользователю GUEST домена MICROSOFT, пароль для которого должен быть введен в процессе выполнения команды (параметр -b).
Из всех объектов LDAP-каталога будут отобраны только учетные записи пользователей, для которых в поле параметра userAccountControl отсутствует информация о блокировке учетной записи (параметр -r). В качестве логических операций для фильтра используются: «!» — логическое НЕТ, «&» — логическое И, «|» — логическое ИЛИ. В результате выполнения команды в CSV-файле будут сохранены данные полей, перечисленных в параметре -l (список наиболее интересных полей приведен в таблице 1).


Таблица 1.
Описание некоторых полей учетных записей LDAP-каталога

Форматы представления данных даты и времени
Если вы были наблюдательны, то заметили, что в таблице 1 имеются два различных варианта представления значений даты и времени. Если формат вида ГГГГММДДЧЧММСС.0Z (тип GeneralizedTime для ASN.1-кодирования), используемый для полей whenChanged, whenCreated по Гринвичу достаточно понятен, то такие параметры, как lastLogon, pwdLastSet, accountExpires, представляют информацию о дате и времени в 32-битном UNIX-формате и содержат значения секунд, прошедших начиная с 1 января 1970 г., GMT. Для наглядности приведем некоторые значения, которые могут содержаться в файле выгруженных значений для параметров даты и времени в Unix-формате:
126858492000000000 — соответствует 1.01.2003 00:00
127014876000000000 — соответствует 1.07.2003 00:00
127014912000000000 — соответствует 1.07.2003 01:00

Использование функций преобразований для данных CSV-формата
Информацию по учетным записям, которая выгружена с помощью команды, аналогичной указанной в начале раздела «Использование утилиты Csvde.exe», можно попытаться загрузить в Microsoft Access, однако в связи с тем, что программа некорректно обрабатывает символ-разделитель «,» в структурах типа «CN=Bill Gates,CN=Users,DC=Microsoft,DC=com», лучше воспользоваться аналогичными возможностями программы Microsoft Excel (см. рис.1). Далее информацию для удобства использования можно обработать с помощью имеющихся в Microsoft Excel возможностей (макросы, функции).
На рисунках приведена информация CVS-файла сразу после проведения его загрузки в Microsoft Excel (рис.1) и после проведенных преобразований (рис.2). Примеры таких преобразований приведены ниже. Предлагаемые варианты преобразований не претендуют на логическую законченность, но могут являться той основной, с помощью которой за короткий срок может быть разработан необходимый механизм обработки под каждый конкретный случай.

Получение данных из структуры поля DN
Для получения имени пользователя из структуры вида «…CN=Имя_пользователя,…» в ячейке A2 может быть использована следующая формула преобразования:
=ПСТР(A2;
НАЙТИ(«CN ,»; A2;
НАЙТИ( «CN CN …OU=Данные,…» в ячейке A2 может быть использована следующая формула преобразования:
=ЕСЛИ(ЕПУСТО(‘0’!A2);»»;
ЕСЛИ(ЕОШИБКА(НАЙТИ(«OU=»; ‘0’!A2)); «USERS»;
ПСТР( ‘0’!A2;
НАЙТИ(«OU ,»; ‘0’!A2;
НАЙТИ(«OU OU Отсутствует»;
СЦЕПИТЬ(
ДЕНЬ(ДАТАЗНАЧ(«1/1/2003»)+E2);
«.»;
МЕСЯЦ(ДАТАЗНАЧ(«1/1/2003»)+E2);
«.»;
ГОД(ДАТАЗНАЧ(«1/1/2003»)+E2)
)
Обработка данных даты и времени формата GeneralizedTime для ASN.1-кодирования
Преобразование числа в формате ГГГГММДДММСС.0Z в формат ДД.ММ.ГГГГ ЧЧ:ММ
=СЦЕПИТЬ(
ПСТР(N2;7;2); «.»; ПСТР(N2; 5;2); «.»; ПСТР(N2;1;4); » «;
ПСТР(N2;9;2); «:»; ПСТР(N2; 11;2)
)

Обработка значения поля userAccountControl о блокированности записи
Получение данных о состоянии учетной записи по значению поля userAccontControl, содержащемуся в ячейке G2:
=ЕСЛИ(ЕПУСТО(G2);»»;
ЕСЛИ(ИЛИG2=514; G2=66050);»За-блокированная»; «Действующая»)
)

Подробные пояснения и описание формата хранения данных в поле userAccountControl можно найти в статье Microsoft «How to Use the User AccountControl Flags to Manipulate User Account Properties» (http://support.microsoft.com/?kbid=305144). Отметим только, что, если параметры учетной записи не заданы, то десятичное значение userAccountControl равно 512; десятичное значение для блокированной учетной записи при отсутствии других параметров — 514.

Заключение
В статье был предложен достаточно простой метод получения данных для аудита учетных записей пользователей в Active Directory, не требующий специальных навыков и знаний языков программирования.
Отметим, что, кроме изложенного метода, может быть использован вариант, рекомендуемый Microsoft, предполагающий использование интерфейсов службы Active Directory (ADSI), которые предоставляют простой, мощный, объектно-ориентированный доступ к ресурсам Active Directory. Интерфейсы ADSI позволяют программистам и администраторам создавать программы каталога с использованием инструментальных средств высокого уровня, например, Microsoft Visual Basic, Java, C или Visual C++, не заботясь о различиях в пространствах имен. Интерфейсы ADSI полностью поддерживают сценарии, что облегчает их использование администраторами.
И напоследок в качестве рекомендаций перечислим те нюансы, на которые следует обратить внимание при проведении анализа данных списка пользователей, которые могут указывать на существующие проблемы при использовании учетных записей:
• заблокированные учетные записи (после анализа последней даты регистрации могут быть удалены в случае, если необходимость в них отсутствует);
• данные учетной записи о том, что последняя регистрации в сети происходила три и более месяцев назад, могут указывать на то, что сотрудник, которому принадлежала учетная запись, уже уволен;
• если количество регистраций в сети для учетной записи равно нулю, а со времени ее создания прошло больше одного месяца, то это может говорить о том, что созданная учетная запись оказалась невостребованной;
• большое количество регистраций в сети может указывать на то, что учетная запись используется для входа в сеть не только владельцем.

Компьютерная газета. Статья была опубликована в номере 39 за 2003 год в рубрике безопасность :: разное

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *