29 марта 2024, 01:51

Цитата дня:

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


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

Автор STALKER_SLX, 07 апреля 2020, 21:30

« предыдущая тема - следующая тема »

0 Пользователей и 2 Гостей просматривают эту тему.

Вниз

STALKER_SLX

07 апреля 2020, 21:30 Последнее редактирование: 07 апреля 2020, 21:45 от STALKER_SLX
Доброго времени суток уважаемые форумчане!
В нашей компании основная работа пользователей сосредоточена на терминальных серверах под управлением ОС «Windows Server 2019».
Думаю, Вы неоднократно сталкивались с ситуацией, когда пользователь «забывает» вовремя сменить свой доменный пароль и жалуется сразу руководству, что он не может работать…
Такие ситуации бывают по разным причинам: отсутствие для этого должных знаний, лень, здравый пофигизм etc.

В связи с чем, возникла необходимость за 5-7 дней до окончания срока действия пароля доменного пользователя автоматически предлагать ему сменить пароль, как это описано тут:
«Когда истекает пароль пользователя в AD, оповещаем пользователей о необходимости сменить пароль»
https://winitpro.ru/index.php/2020/02/25/ad-user-password-expiration/

Для этого создал powershell-скрипт со следующим содержимым (приведу его для лучшей наглядности):

$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' { }
}
}
}


И тут столкнулся с проблемой: при выполнении указанного содержимого в «PowerShell ISE» все отрабатывает корректно без ошибок, но если запускаю сохраненный скрипт из оболочки «PowerShell» от обычного пользователя или через GPO, то появляется ошибка (более детально смотри скрин во вложении):

«Не удалось найти тип [System.Windows.MessageBox].
C:\Users\имя_пользователя\Documents\ad_user_pass_expired.ps1:5 знак:16
+ $msgBoxInput = [System.Windows.MessageBox]::Show("Ваш пароль истекает ...
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Windows.MessageBox:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound »



Немного погуглив, народ рекомендует использовать такую строку:
Add-Type PresentationFramework


либо вот такую
Add-Type -AssemblyName System.Windows.Forms

Но только я не пойму куда именно в скрипте (после каких строк или команд) нужно подставлять одну из приведенных строк…

Сразу признаюсь, что я не силён в программировании «PowerShell», поэтому прошу Вас помочь мне разобраться в этой задаче!




Уваров А.С.

Примерно так, в самом начале скрипта:

try{
    Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms
} catch {
    Throw "Failed to load Windows Presentation Framework assemblies."
}

STALKER_SLX

Спасибо Вам за помощь! Но, вот при тестировании этого скрипта появилась еще одна проблема!
1.При его запуске неправильно отображается количество дней до окончания срока действия пароля (см.вложение "ad_user_pass.png").
2.Также окошко показывается ВСЕМ пользователям даже тем, у кого до окончания срока больше 10 дней

Подскажите, пожалуйста, что тут не так?

STALKER_SLX

Да, на всякий случай, приведу текст итогового скрипта (может я что-то не так понял...):
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")

Почему - нужно разбираться.


Уваров А.С.

А вот и причина - командлет Get-ADUser

STALKER_SLX

А вот и причина - командлет Get-ADUser
так я установил этот командплет, как на контроллере домена, так и на терминальных серверах!

делал вот по этой инструкции:
"Использование Get-ADUser для получения разной информации о пользователях домена AD"
https://winitpro.ru/index.php/2015/05/21/powershell-get-aduser-poluchenie-dannih-o-polzovatelyax-active-directory/

STALKER_SLX

Вот и скриншот выполнения командплета "Get-ADUser" на терминальном сервере:

STALKER_SLX

В Windows Server 2012 и выше модуль "RSAT-AD-PowerShell" устанавливается по-умолчанию при развертывании на сервере роли Active Directory Domain Services (AD DS).
Для установки модуля на рядовом сервере домена нужно выполнить команду:

Install-WindowsFeature -Name "RSAT-AD-PowerShell" -IncludeAllSubFeature

Я так и сделал.

Уваров А.С.

Загружайте скрипт в PowerShell ISE и отлаживайте. Пока что получается, что

[datetime]::FromFileTime($curruser."msDS-UserPasswordExpiryTimeComputed")

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

STALKER_SLX

Андрей, спасибо Вам за помощь!
Проблему решил следующим образом.
Установил компоненту "Модуль Active Directory для Windows PowerShell" через графическую оболочку - "Диспетчер серверов"!
Может был не достаточно внимательным при установке указанной компоненты из консоли PowerShell или какой-то баг 2019 сервера...

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

Вверх