Сценарий Powershell для пользователей AD, срок действия которых скоро истечет

По сути, у меня есть скрипт, который сканирует импортируемый им CSV-файл и для каждой записи в электронной таблице, за исключением людей в RANDOM.DOMAIN, находит адрес электронной почты менеджера и отправляет автоматическое электронное письмо на адрес менеджер говорит им, что срок действия пользователя XYZ скоро истечет, и им нужно что-то с этим сделать.

Если электронная почта менеджера по какой-либо причине недоступна, то по умолчанию она отправляет электронное письмо мне. Этот скрипт работает хорошо.

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

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

МОЙ ВОПРОС:

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

$datai = Import-Csv "Soon-to-expire User Accounts22.csv" | select 'Display Name',Manager,'Domain Name','Account Expiry Time'
Connect-QADService -Service another.DC | Out-Null
$expiringUsers = @{}



foreach ($i in $datai) {
        $dn = $i.'Display Name'
        $dn1 = $i.'Domain Name'
        $man = $i.'Manager'
        $aet = $i.'Account Expiry Time'
        $subject = "Account about to expire: $dn"



$getmail = get-qaduser "$man" -LdapFilter '(mail=*)' | select mail
$emailAD = $getmail.mail

if ($man -eq "-" -or $man -like 'CN=*' -or $getmail -eq $null -or $man -eq "") {
$man = "Aaron T"
$getmail = get-qaduser "$man" -LdapFilter '(mail=*)' | select mail
$emailAD = $getmail.mail
}



if ($expiringUsers.Contains($emailAD)) {
  $expiringUsers[$emailAD]["dn"] += $dn += "`n"
  $expiringUsers[$emailAD]["aet"] += $aet += "`n"
  $expiringUsers[$emailAD]["man"] += $man += "`n"
} else {
  $expiringUsers[$emailAD] = @{
    #"dn1" = $dn1
    #"aet" = $aet
   #"man" = $man
  # "dn"  = @( $dn )
     }
  }
}


$expiringUsers | fc #as suggested


foreach ($emailAD in $expiringUsers.Keys) {
$dn  = $expiringUsers[$emailAD]["dn"]
$dn1 = $expiringUsers[$emailAD]["dn1"]
$man = $expiringUsers[$emailAD]["man"]
$aet = $expiringUsers[$emailAD]["aet"]
$subject = "Account/s About to Expire!"
$content = @"
Hi,
$dn `n
$dn1 `n
$man `n
$aet `n

$emailAD `n
Technology Services
 "@
 Send-MailMessage -from "[email protected]" `
-To $emailAD `
-Subject $subject `
-Body $content `
-Priority high `
-smtpServer "relay.server"


#using this as a test instead of sending mass emais all the time
Write-Host $content
}

ОБНОВЛЕНО с новым скриптом по запросу.... все еще есть проблемы.

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


person Aaron Tanner    schedule 14.05.2013    source источник


Ответы (2)


Для этого вам необходимо отложить обработку электронной почты. Соберите пользователей в хэш-таблицу, например. по электронному адресу менеджера:

...

$expiringUsers = @{}

foreach ($i in $datai) {
  If ($i.'Domain Name' -notmatch "RANDOM.DOMAIN") {
    ...
    if ($expiringUsers.Contains($emailAD)) {
      $expiringUsers[$emailAD]["dn"] += $dn
    } else {
      $expiringUsers[$emailAD] = @{
        "dn1" = $dn1
        "aet" = $aet
        "man" = $man
        "dn"  = @( $dn )
      }
    }
  }
}

и переместите фактическую обработку электронной почты за пределы цикла:

foreach ($emailAD in $expiringUsers.Keys) {
  $dn1 = $expiringUsers[$emailAD]["dn1"]
  $man = $expiringUsers[$emailAD]["man"]
  $aet = $expiringUsers[$emailAD]["aet"]
  $subject = "Account about to expire: $($expiringUsers[$emailAD]["dn"])"
  $content = @"
Hi,
...
Technology Services
"@
  Send-MailMessage -from "Test Script - Powershell <[email protected]>" `
    -To "$emailAD" `
    -Subject $subject `
    -Body $content `
    -Priority high `
    -smtpServer servername
  Write-Host "Mail Sent to $man"
}

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

$expiringUsers[$emailAD]["expiry"] += @{
  "name" = $dn;
  "date" = $aet;
}

вместо

$expiringUsers[$emailAD]["dn"] += $dn
person Ansgar Wiechers    schedule 14.05.2013
comment
Спасибо за ваш ответ - я могу быть немного тугим, но я не могу заставить ваш код работать правильно. Кажется, он сообщает о КАЖДОЙ записи в электронном письме, которое он отправляет. Вроде вообще не фильтрует. Хотя то, что вы говорите, определенно имеет смысл! - person Aaron Tanner; 15.05.2013
comment
Работает для меня, когда я тестировал некоторые фиктивные данные (здесь нет AD). Проверьте содержимое $expiringUsers после первого цикла чем-то вроде $expiringUsers | fc. Если это не поможет разобраться, обновите свой вопрос, указав измененный код. - person Ansgar Wiechers; 15.05.2013
comment
Хм.. Итак, я еще немного поиграл, теперь я сталкиваюсь с другими проблемами... Я не могу заставить его хорошо отображаться в электронном письме (т.е. он объединяет детали, которые все пользователи отображают в одном блок, остальное в другом).. Думаю, мне нужно больше узнать о хеш-таблицах. Это похоже на то, что ему нужен оператор foreach рядом. Вскоре я обновлю свой вопрос с помощью предоставленного вами сценария. - person Aaron Tanner; 16.05.2013

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

Я также изменил метод ввода; он извлекает информацию непосредственно из AD, вместо использования CSV-файла, который раньше генерировался из приложения под названием «AD Manager Plus» (ненавижу его).

Помните, здесь мы используем Quest CMDlets, потому что у нас нет среды 2008 года. (поэтому используйте Get-QADUser вместо Get-ADuser)

К вашему сведению, я разместил здесь только код, который сортирует данные в отдельные таблицы — вы можете решить, как вы хотите использовать эти результаты. Для нашей среды я создаю хорошую HTML-таблицу и тело, а затем отправляю их соответствующему менеджеру для обработки.

#user data input
$data = get-qaduser -SizeLimit 0 -includedproperties accountexpires | where {$_.AccountExpires -ne $null -and $_.AccountExpires -le ((Get-Date).AddDays(45)) }

#get a list of managers, unique.
$uniqueMan = $data | select Manager -Unique

#foreach manager from $uniqueman
Foreach ($manager in $uniqueman) {
    #create the array variable / clear it out for the next manager.
    $myarray = @()
            #foreach User found in in $data query
            Foreach ($user in $data) {

            #Search the $user's query for people with the same manager as that of the $uniqueman list.
            If ($user.Manager -eq $manager.Manager) {

                    #do what with the result.
                    #add the person to an array
                    $myarray += New-Object psobject -Property @{
                        Name = $user.'Name'
                        UserName = $user.'SAMAccountName'
                        AccountExpires = $user.'AccountExpires'
                        Manager = $user.Manager
                        }


            }


    #for testing, to output the results to an HTML file.
    #$myarray | ConvertTo-Html | Out-File ("C:\test\" + $manager.Manager + ".html")

        }


}
person Aaron Tanner    schedule 25.04.2014