So basically, what I have here is a script that will scan a CSV that it imports, and for every entry in the spreadsheet, except for people in the RANDOM.DOMAIN, it will find the managers email address and send an automated email to the manager telling them user XYZ is about to expire soon, and they need to do something about it.
If the managers email is unavailable for some reason, then it defaults to sending the email to me.
This script works well.
The problem I am running into is, I want to make it so only one email is sent to each manager, despite multiple users (or entries) from the spreadsheet, list them as the manager.
I.e. if Joe Bloggs has a manager Aaron T and Jane Doe has the manager Aaron T, then Aaron T will get two emails, one email for each user.
MY QUESTION:
Is there an easy way to only get it to send one email per manager, even if that manager has multiple users reporting to them that are about to expire?
$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 "aaron#website.com" `
-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
}
UPDATED with the new script as requested.... still having issues.
Is there an easy way to only get it to send one email per manager, even if that manager has multiple users reporting to them that are about to expire?
For this you need to defer e-mail processing. Collect the users in a hashtable, e.g. by manager e-mail address:
...
$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 )
}
}
}
}
and move the actual e-mail processing outside the loop:
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#test.com>" `
-To "$emailAD" `
-Subject $subject `
-Body $content `
-Priority high `
-smtpServer servername
Write-Host "Mail Sent to $man"
}
Note that for simplicity reasons the above code only records the expiry date of the first user. If you want the expiry date of each user recorded separately, you'll have to take additonal steps, e.g.
$expiringUsers[$emailAD]["expiry"] += #{
"name" = $dn;
"date" = $aet;
}
instead of
$expiringUsers[$emailAD]["dn"] += $dn
So I finally decided to revisit this script, after many, many months.
I'm get a little better at PowerShell and while I'm sure this isn't the most effective way to do it, this is something that works for me.
I've also changed the input method; it pulls the information directly from AD, instead of using a CSV file that used to be generated from an application called 'AD Manager Plus' (Hate it).
Remember, using Quest CMDlets here because we don't have a 2008 environment. (so using Get-QADUser instead of Get-ADuser)
FYI, I have only posted the code here which sorts out the data into separate tables - you can decide how you want to utilize those results. For our environment, I have it build an nice HTML table and body, then send it to the appropriate manager to deal with.
#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")
}
}
Related
Hello I am new to PowerShell and I am trying to figure out how to send emails to user's manager. In the script below I am able to send the notification if in AD ,manager field is not empty, but when is black I get an error message. How do I make it where it sends an email to myself, if the user's manager is blank? For some reason when I run this code, I keep getting line 233 manager email is null.
code is located here:
https://stackoverflow.com/a/69731370/18947133
Import-Module ActiveDirectory
$mailprops = #{
from = "test#domainname.com
smtpserver = "server.domain.com"
bodayashtml =$true
}
$startDate = Get-Date
$enddate= $startdate.addDays(x)
$props = #{ filer = "Account expirationDate -gt '$startdate' - and AccountExpiratioDate -lt '$endDate'"
Properties ='Accountexpirationdate', 'Manager' }
$Users = Get-ADuser #props
$bodyScriptBlock = {
# Group all users by their Manager
$Users | Group-Object Manager | ForEach-Object {
# Get this Manager's email address
$managerEmail = (Get-ADUser $_.Name -Properties EmailAddress).EmailAddress
# Create a string[] with the user's Name and their Account's Expiration Date
$userList = foreach($user in $_.Group)
{
'- {0} expires on {1}' -f $user.Name, $user.AccountExpirationDate
}
# Execute the Body scriptblock passing this user's list
$body = & $bodyScriptBlock -UserList $userList
# Set the remaing values for Mail props
$mailProps.To = $managerEmail
$mailProps.Subject = "Account Expiration Notification for Managees" # ??? No idea what to put here
$mailProps.Body = $body
# Send the email with the list of users
Send-MailMessage #mailProps
Have you tried
if ($null -eq $ManagerEmail)
{$ManagerEmail = "yourEmail#domain.com"}
So, I we have a few users that their computers are not on the domain. One of the annoying things about that is windows will not notify them that their domain password is expired obviously. So I decided I was going to put together a little script using powershell in windows that checks AD to see when their password expires and then if it's about to expire in 3 days to send the user an email to notify them that they should change their password.
I have it set up right now to look at the users distinguished name to pull all the necessary information. but I can only do that for one person, I need to look at two user's distinguished names and send each of them an email when their password is about to expire. I tried creating another $DN variable that I could put the other Distinguished name into and put get-aduser -searchbase $DN, $DN2 but that didn't work for me. Probably was a dumb thing to try, but not sure the syntax needed to accomplish this. Below is my code.
$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#domain.com", #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
I am just trying to get some insight on how I could modify my code to use two Distinguished names instead of just the one. I'm sure this isn't the best way to do this, but I'm not too good with coding yet. Hopefully this all makes sense, I appreciate the help!
As you have discovered, you can store the DN values in an array $DNs and process each element of the array. The two expressions inside of the parentheses differ by only the $DN variables that you supply. Using a Foreach loop slightly performs better than piping to ForEach-Object, but in your case it will be negligible.
$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)
There are added benefits of doing it this way:
Removal of the Where-Object: Get-ADUser has its own filter as a parameter that can dramatically increase performance over using where in certain queries. It should be faster for you here as the number of returned users from the Get-ADUser query increases.
Got it!!
I changed $DN to:
$DN = "Distinguished name","Distinguished name"
then changed my get-aduser code to:
$users= $DN | ForEach-Objects {get-aduser -SearchBase $PSItem -filter * .....
thanks,
I am having a bit of a tough time writing a script for exchange. I have an environment, that has a hybird environment. I am trying to make a power shell script to find all large distro groups and email the owners of the groups to clean them up. However, I am having issues with pulling the owner email and and name for the email portion of the script.
But, there are a few restrictions, I can't use AD powershell, exchange only. and I can't use the get-mailbox cmdlet.
add-pssnapin microsoft.exchange.management.powershell.e2010
set the scope of the search
Set-ADServerSettings -ViewEntireForest $true
$DistGroups = Get-DistributionGroup -ResultSize 2
ForEach ($Group in $DistGroups) {
#Get each group details
$MemberCount = (Get-DistributionGroupMember $Group).count
$GroupName = (Get-DistributionGroup $Group).DisplayName
$Owner = (Get-DistributionGroup $Group).ManagedBy
$OwnerEmail = Get-recipient -identity $Owner | select PrimarySmtpAddress
$OwnerFN = Get-Recipient -identity $Owner | Select FirstName
If ( $MemberCount > 50000) {
#define email stuff
$messageBody = "Hi, <b>$OwnerFN,</b><p>"
$messageBody += "We are auditing distribution groups in our environment and your group, $GroupName, was flagged as being
<font color=red>really large</font>. The current member count is <font color=red> $MemberCount</font>.<p>"
$messageBody += "Please take steps to update the group and clear out unnecessary or old group members… <p>"
$messageBody += "Thanks, <p>"
$messageBody += "The Exchange Admin Team"
#Send the mail
$email = New-Object System.Net.Mail.MailMessage
$email.From = "Email_Group_Admin_Report#Internal.Mail.company.com"
$email.To.Add("me#company.com")
#$email.To.Add("$OwnerEmail")
#$email.CC.Add("#company.com")
#$email.BCC.Add("admin#company.com")
$email.DeliveryNotificationOptions = [System.Net.Mail.DeliveryNotificationOptions]::OnSuccess
$email.IsBodyHtml = $True
$email.Priority = [System.Net.Mail.MailPriority]::High
$email.Subject = "Distribution Group Audit"
$email.Body = $messageBody | Out-String
$smtp = New-Object System.Net.Mail.SmtpClient
$smtp.Host = "mail.compnany.com"
$smtp.Send($email)
}
}
I am able to get the count, and the Distro name, I can't seem to get the managed by property or the other stuff, it spits out an entire list of primary emails and Firstnames and such... The managed by property doesn't seem to appear....
$OwnerEmail = Get-recipient -identity $Owner | select PrimarySmtpAddress
This will return an object, but when you send the email you're acting as if you have a string.
email.To.Add("$OwnerEmail")
Option A:
($OwnerEmail = Get-recipient -identity $Owner).PrimarySmtpAddress
email.To.Add($OwnerEmail)
Option B:
$OwnerEmail = Get-recipient -identity $Owner | select PrimarySmtpAddress
email.To.Add($OwnerEmail.PrimarySmtpAddress)
I had a tough time with the output formats, but I finally got it working as expected. Thought I would post the working script here... Maybe you will find it useful.
add-pssnapin microsoft.exchange.management.powershell.e2010
# Find all Distros
$DistGroups = Get-DistributionGroup -ResultSize unlimited
ForEach ($Group in $DistGroups) {
#Get each group details
if ($Group.managedby -ne $null) {
$t = $Group.Managedby
$t | foreach { $Owner = $_.Name }
}
else {
$Owner = "Unknown"
$DL_Name = $Group.displayname
}
$MemberCount = (Get-DistributionGroupMember $Group).count
if ($Owner -eq "Unknown") { echo "The owner is unknown!"
}
#set membercount catch here
elseIf ( $MemberCount -gt 2000) {
$OwnerEm = get-recipient $Owner | select PrimarySmtpAddress | ft -HideTableHeaders | out-string
#$OwnerEm = get-recipient me#company.com | select PrimarySmtpAddress | ft -HideTableHeaders | out-string
#define email stuff
$messageBody = "Hi, <b>$Owner,</b><p>"
$messageBody += "We are auditing distribution groups in our environment and your group, $DL_Name, was flagged as being <font color=red>really large</font>. The current member count is <font color=red> $MemberCount</font>.<p>"
$messageBody += "Please take steps to update the group and clear out unnecessary or old group members… <p>"
$messageBody += "Thanks, <p>"
$messageBody += "The Exchange Admin Team"
#Send the mail
$email = New-Object System.Net.Mail.MailMessage
$email.From = "Email_Group_Admin_Report#Internal.Mail.company.com"
#$email.To.Add("me#company.com")
$email.To.Add("$OwnerEm")
#$email.CC.Add("#company.com")
#$email.BCC.Add("admin#company.com")
$email.DeliveryNotificationOptions = [System.Net.Mail.DeliveryNotificationOptions]::OnSuccess
$email.IsBodyHtml = $True
$email.Priority = [System.Net.Mail.MailPriority]::High
#$attachment = "C:\myfile.txt"
#$email.Attachments.Add( $attachment )
$email.Subject = "Distribution Group Audit"
$email.Body = $messageBody | Out-String
$smtp = New-Object System.Net.Mail.SmtpClient
$smtp.Host = "mail.company.com"
$smtp.Send($email)
echo "the $DL_Name has a high member count. The member count is $MemberCount. The manager has been sent and email at $OwnerEm"
}
else {
echo "the $DL_Name seems fine! The member count is $MemberCount. The manager '$Owner' is doing great!"
}
}
I left the echo statements in so you can view the statuses via a console, or pipe them to a file.... or something...
ok fellas, I've been reading, researching, learning and testing about powershell. Within the last 20 days, here is what I've been able to come up with.
get-mailbox -identity $_.name | select name,userprincipalname,#{label="Size";expression={$size = Get-Mailboxstatistics $_.identity;$size.TotalItemSize.Value.ToMB()}},#{label="Items";expression={$items = Get-Mailboxstatistics $_.name;$item.ItemCount}}
I stored this in a script called accountsizes.ps1. It works exactly as I expected by outputting all the email accounts with the sizes, but in order for me to get only the mailboxes over 2048MB, I have to call it like this:
PS C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size
And this works by return the email addresses and mailbox sizes in MBs. But now my dilemma is; how do I enumerate through the results and extract each email address and send an email to that user and myself, warning them that their mailbox is too large and they need to archive. From what I been reading and learning, I would have to use a ForEach loop and the send-mailmessage cmdlet. I cannot figure out how to use the ForEach and incorporate it with the script: Here is I go brain dead with the ForEach:
PS C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size | ForEach($user in userprincipalname){$_.userprincipalname}
I do not know the right way to go about doing this (so, don't ask me why I'm doing this way :)), I have no previous knowledge about scripting and coding.
Here is my email part:
$smtpserver = "domain.com"
$smtpFrom = "me#domain.com"
$smtpTo = "you#domain.com"
$messageSubject = "Warning Email Mailbox Too Large"
$body = "blah blah blah blah"
send-mailmessage -from $smtpFrom -to $smtpTo -subject $messageSubject -body $body
Thanks in advance for your helpful advice.
The foreach keyword and the ForEach-Object cmdlet are two different things.
If you use the foreach keyword, you give a name to the iteration variable, and you iterate on a collection. For example:
$collection = #("one", "two")
foreach ($item in $collection) {
Write-Host $item
}
Instead, if you pipe commands outputs, you have to use the ForEach-Object cmdlet with a script block. Inside the script block, you refer to the iteration variable with the special variable $_. Example:
$collection = #("one", "two")
$collection | ForEach-Object {
Write-Host $_
}
You can shorten ForEach-Object with %:
$collection | % {
Write-Host $_
}
So, in your case you should probably do this:
C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size | % { $_.userprincipalname }
Paolo provided excellent information and deserves upvotes if nothing else. As to your question of how to enumerate and send email you probable need something like:
C:\accountsizes.ps1 | where size -gt "2048" | %{
$smtpServer = "smtp.domain.com"
#Creating SMTP server object
$SMTP = new-object Net.Mail.SmtpClient($smtpServer)
#Creating a Mail object
$EMail = new-object Net.Mail.MailMessage
#Construct Email
$EMail.From = "me#domain.com"
$EMail.ReplyTo = "me#domain.com"
$EMail.To.Add($_.userprincipalname)
$EMail.subject = "Warning Email Mailbox Too Large"
$EMail.body = "blah blah blah blah"
$SMTP.Send($EMail)
}
You could get a lot more fancy, go by size and send different emails depending on how large their mailbox is, or get content from files for subject and body depending on size, but that is just going to make things complicated. You could also use Send-MailMessage, and that works just fine, I just like this way because it makes it easier to work with in my opinion than one really long line with a ton of switches. If the message and subject are going to be generic you may want to do something more like:
$smtpServer = "smtp.domain.com"
#Creating SMTP server object
$SMTP = new-object Net.Mail.SmtpClient($smtpServer)
#Creating a Mail object
$EMail = new-object Net.Mail.MailMessage
#Construct Email
$EMail.From = "me#domain.com"
$EMail.ReplyTo = "me#domain.com"
C:\accountsizes.ps1 | where size -gt "2048" | %{$EMail.BCC.Add($_.userprincipalname)}
$EMail.subject = "Warning Email Mailbox Too Large"
$EMail.body = "blah blah blah blah"
$SMTP.Send($EMail)
That would make one email and BCC everybody on it. Then you could do another email to yourself stating who warnings got sent to.
I have a script for automaticaly notifying users about AD password expiration. It needed for VPN users. But I can't find a way to solve a problem with $msg.to field. It can't accept, for example, "$msg.to = ''" and works only by $msg.to.add method. It makes not so good situation, when user, who was notified first - will recieve all next e-mails because they will be just added at the end of string, but not replacing all of data in $msg.to
There is a code:
Import-Module ActiveDirectory
#SMTP server name
$smtpServer = "mail.domain.local"
#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
$msgr = new-object Net.Mail.MailMessage
#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
#E-mail structure
Function EmailStructure($to,$expiryDate,$upn)
{
$msg.IsBodyHtml = $true
$msg.From = "notification#domain.com"
$msg.To.Add($to)
$msg.Subject = "Password expiration notice"
$msg.Body = "<html><body><font face='Arial'>This is an automatically generated message from Exchange service.<br><br><b>Please note that the password for your account <i><u>Domain\$upn</u></i> will expire on $expiryDate.</b><br><br>Please change your password immediately or at least before this date as you will be unable to access the service without contacting your administrator.</font></body></html>"
}
Function EmailStructureReport($to)
{
$msgr.IsBodyHtml = $true
$msgr.From = "notification#domain.com"
$msgr.To.Add($to)
$msgr.Subject = "Script running report"
$msgr.Body = "<html><body><font face='Arial'><pre><b>This is a daily report.<br><br>Script has successfully completed its work.<br>$NotificationCounter users have recieved notifications:<br><br>$ListOfAccounts<br><br></b></pre></font></body></html>"
}
#Set the target OU that will be searched for user accounts
$OU = "OU=Organisation,DC=domain,DC=local"
$ADAccounts = Get-ADUser -LDAPFilter "(objectClass=user)" -searchbase $OU -properties PasswordExpired, extensionAttribute15, PasswordNeverExpires, PasswordLastSet, Mail, Enabled | Where-object {$_.Enabled -eq $true -and $_.PasswordNeverExpires -eq $false}
$NotificationCounter = 0
$ListOfAccounts = ""
Foreach ($ADAccount in $ADAccounts)
{
$accountFGPP = Get-ADUserResultantPasswordPolicy $ADAccount
if ($accountFGPP -ne $null)
{
$maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge
}
else
{
$maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}
#Fill in the user variables
$samAccountName = $ADAccount.samAccountName
$userEmailAddress = $ADAccount.ExtensionAttribute15
$userPrincipalName = $ADAccount.UserPrincipalName
if ($ADAccount.PasswordExpired)
{
Write-host "The password for account $samAccountName has expired!"
}
else
{
$ExpiryDate = $ADAccount.PasswordLastSet + $maxPasswordAgeTimeSpan
$TodaysDate = Get-Date
$DaysToExpire = $ExpiryDate - $TodaysDate
$DaysToExpireDD = $DaysToExpire.ToString() -Split ("\S{17}$")
Write-host "The password for account $samAccountName expires on: $ExpiryDate. Days left: $DaysToExpireDD"
if (($DaysToExpire.Days -eq 15) -or ($DaysToExpire.Days -eq 7) -or ($DaysToExpire.Days -le 3))
{
$expiryDate = $expiryDate.ToString("d",$ci)
#Generate e-mail structure and send message
if ($userEmailAddress)
{
EmailStructure $userEmailAddress $expiryDate $samAccountName
$smtp.Send($msg)
Write-Host "NOTIFICATION - $samAccountName :: e-mail was sent to $userEmailAddress"
$NotificationCounter = $NotificationCounter + 1
$ListOfAccounts = $ListOfAccounts + $samAccountName + " - $DaysToExpireDD days left.<br>"
}
}
}
}
Write-Host "SENDING REPORT TO IT DEPARTMENT"
EmailStructureReport("itdepartment#domain.com")
$smtp.Send($msgr)
How can I drop string in $msg.to after each sent e-mail?
If you want to reuse the same message but change the address and send several times to different addresses, use the clear method on the MailAddressCollection.
So your code will look something like this:
$msg.To.Clear()
$msg.To.Add($to)