Напоминание об истечении срока действия пароля по электронной почте для нескольких пользователей

Итак, у меня есть несколько пользователей, у которых компы не в домене. Одна из раздражающих вещей в этом заключается в том, что Windows не будет уведомлять их о том, что срок действия их доменного пароля явно истек. Поэтому я решил, что собираюсь собрать небольшой скрипт, используя powershell в Windows, который проверяет AD, чтобы увидеть, когда истечет срок действия их пароля, а затем, если он истечет через 3 дня, чтобы отправить пользователю электронное письмо, чтобы уведомить их о том, что они должны изменить свой пароль. .

Я настроил его прямо сейчас, чтобы посмотреть на отличительное имя пользователя, чтобы получить всю необходимую информацию. но я могу сделать это только для одного человека, мне нужно просмотреть различающиеся имена двух пользователей и отправить каждому из них электронное письмо, когда срок действия их пароля истекает. Я попытался создать еще одну переменную $DN, в которую я мог бы поместить другое отличительное имя и поставить get-aduser -searchbase $DN, $DN2, но это не сработало для меня. Вероятно, было глупо пытаться, но не уверен, что синтаксис необходим для этого. Ниже мой код.

$smtpServer = "smtp.office365.com" # Office 365 official smtp server 
$expireindays = 100 # number of days for password to expire  
$from =  # email from  
#$logging = "$true" # Set to Disabled to Disable Logging 
$logFile = "c:\Scripts\PasswordChangeNotification.csv" # ie. c:\Scripts\PasswordChangeNotification.csv 
#$testing = "Disabled" # Set to Disabled to Email Users 
$testRecipient =   
$date = Get-Date -format ddMMyyyy
$DN = "Distinguished name here"
# Add EMAIL Function 
Function EMAIL{ 

    Param( 
        $emailSmtpServer = $smtpServer,   #change to your SMTP server 
        $emailSmtpServerPort = 587, 
        $emailSmtpUser = "User"
        $emailSmtpPass = "Password",   #Password for Send from email account 
        $emailFrom = "[email protected]",   #Email account you want to send from 
        $emailTo, 
        $emailAttachment, 
        $emailSubject, 
        $emailBody 
    ) 
    Process{ 

    $emailMessage = New-Object System.Net.Mail.MailMessage( $emailFrom , $emailTo ) 
    $emailMessage.Subject = $emailSubject 
    $emailMessage.IsBodyHtml = $true 
    $emailMessage.Priority = [System.Net.Mail.MailPriority]::High 
    $emailMessage.Body = $emailBody 

    $SMTPClient = New-Object System.Net.Mail.SmtpClient( $emailSmtpServer , $emailSmtpServerPort ) 
    $SMTPClient.EnableSsl = $true 
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential( $emailSmtpUser , $emailSmtpPass ); 

    $SMTPClient.Send( $emailMessage ) 
    } 
} 

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired 
Import-Module ActiveDirectory 
$users = get-aduser -SearchBase $DN -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$DefaultmaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry 
foreach ($user in $users) 
{ 
    $Name = $user.Name 
    $emailaddress = $user.emailaddress 
    $passwordSetDate = $user.PasswordLastSet 
    $PasswordPol = (Get-AduserResultantPasswordPolicy $user) 
    # Check for Fine Grained Password 
    if (($PasswordPol) -ne $null) 
    { 
        $maxPasswordAge = ($PasswordPol).MaxPasswordAge 
    } 
    else 
    { 
        # No FGP set to Domain Default 
        $maxPasswordAge = $DefaultmaxPasswordAge 
    } 

    $expireson = $passwordsetdate + $maxPasswordAge 
    $today = (get-date) 
    $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days 

    # Set Greeting based on Number of Days to Expiry. 

    # Check Number of Days to Expiry 
    $messageDays = $daystoexpire 

    if (($messageDays) -ge "1") 
    { 
        $messageDays = "in " + "$daystoexpire" + " days." 
    } 
    else 
    { 
        $messageDays = "today." 
    } 

    # Email Subject Set Here 
    $subject = "Your password will expire $messageDays" 

    # Email Body Set Here, Note You can use HTML, including Images. 
    $body  = "     
    <p>Dear $name,<br></P><br> 
    <p>Your domain password will expire $messageDays<br><br> 
    Please change your password before it expires.<br></P><br><br> 
    <p>Thanks, <br>

    } # End Send Message 

} # End User Processing  
# End

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
225
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Понятно!!

Я изменил $DN на: $DN = "Distinguished name","Distinguished name" затем изменил мой код get-aduser на: $users= $DN | ForEach-Objects {get-aduser -SearchBase $PSItem -filter * .....

Спасибо,

Ответ принят как подходящий

Как вы обнаружили, вы можете хранить значения DN в массиве $DNs и обрабатывать каждый элемент массива. Два выражения в круглых скобках отличаются только указанными вами переменными $DN. Использование цикла Foreach немного лучше, чем подключение к ForEach-Object, но в вашем случае это будет незначительно.

$users = Foreach ($DN in $DNs) {
  get-aduser -SearchBase $DN -filter {
  Enabled -eq "True" -and 
  PasswordNeverExpires -eq "False" -and 
  passwordexpired -eq "False" 
  } -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress)

У этого способа есть дополнительные преимущества:

  • Удаление Where-Object: Get-ADUser имеет собственный фильтр в качестве параметра, который может значительно повысить производительность по сравнению с использованием where в определенных запросах. Здесь у вас должно быть быстрее, так как количество вернувшихся пользователей из запроса Get-ADUser увеличивается.

Спасибо за ваш вклад, извините, я только что увидел ваш пост. Итак, если я расширяюсь и начинаю добавлять больше пользователей в свой скрипт, не будет ли лучше использовать цикл?

Luke 08.04.2019 18:12

Используйте циклы, когда вы перебираете данные и не знаете, сколько раз вам, возможно, придется выполнять итерацию. Циклы в вашем случае позволяют вашему коду быть более динамичным. Перебор двух строк не будет иметь никакого значения с точки зрения скорости. Это просто то, что следует учитывать при разработке сценариев, например. может быть компромисс между запуском Get-ADUser на каждой итерации и просто выполнением этого один раз и циклическим просмотром результата. Вы должны заменить пункты where на пункты -filter, где это возможно. Where работает намного медленнее и становится более очевидным, когда ваш Get-ADUser возвращает большое количество объектов.

AdminOfThings 08.04.2019 18:22

К удалению where добавляется тот факт, что не все атрибуты AD индексируются. Некоторые будут возвращать данные очень быстро, используя -filter, а некоторые будут медленнее. Вы должны протестировать различные проекты, если для вас важна производительность. Трудно использовать слово «всегда» для каждого сценария.

AdminOfThings 08.04.2019 18:29

ааа, хорошо, звучит хорошо... Я возился с предложенным фрагментом кода, и я получаю сообщение об ошибке Method invocation failed because [Microsoft.ActiveDirectory.Management.ADUser] does not contain a method named 'op_Addition'. Я предполагаю, что op_addition говорит о сложении двух вместе? Я читал, что мне нужно добавить $users = @() ... но это не сработало для меня. есть идеи? Благодаря тонну!

Luke 08.04.2019 20:25

Возможно, это проблема версии или того, как вы объявили $users в другом месте скрипта. Я тестировал это только на версиях 5.1 и 5.0. Объявление $users, как вы говорите, тоже должно работать.

AdminOfThings 08.04.2019 20:54

хм странно. Я только что проверил, и у меня версия 5.1... здесь что-то другое, я просто запускаю get-aduser -SearchBase $DN1 -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress, а мне пишет Get-ADUser : Cannot validate argument on parameter 'SearchBase'. The argument is null. Provide a valid value for the argument, and then try running the command again. я запускаю $DN1 в параметре SearchBase. В $DN1 содержится только отличительное имя конкретного пользователя. Раньше все работало нормально, не знаю что изменилось. Данг.

Luke 08.04.2019 23:05

На самом деле я столкнулся с этой ошибкой, я не знаю, в чем проблема, но если я просто введу отличительное имя в качестве аргумента для параметра Searchbase, это сработает. Но у меня все еще есть ошибка op_Addition

Luke 08.04.2019 23:19

Возможно, не все ваши пользовательские объекты имеют одинаковые атрибуты, присутствующие на выходе, и выдают эту ошибку. Я тестировал только с подмножеством пользователей. Если это так, то просто игнорируйте синтаксис +. Сокращение where по-прежнему полезно.

AdminOfThings 08.04.2019 23:41

Я ценю вашу помощь! Я думаю, что понял. Изначально у меня был Users = @() отдельный, который не заставлял его работать. Я уверен, что вы могли бы сказать мне это, ха-ха (дурр). Это не сработало, пока я не выразил это так: $users =@(get-aduser -searchbase "DN".... теперь работает как шарм.

Luke 09.04.2019 00:04

Другие вопросы по теме