Script: New-WelcomeEmail.ps1 – Automatically Sending a ‘Welcome’ Email to All New User Accounts
Note: I’ve updated this script to address a couple of issues. The first is that if a scheduled task was configured for a time frame other than what was configured in the script itself, this would yield sporadic results. I’ve addressed this by writing a time stamp to the registry when the script runs. This removed the requirement of configuring the time in the script itself, and provides resiliency if the script runs at different times. Run the script once manually to set the configuration. I’ve also added some code that verifies the Exchange PowerShell snapin is loaded before attempting to run. If you’d like a feature added, please let me know in the comments below.
Note #2: If you’re using a server that’s not configured for the normal U.S. style time-date format, such as in the U.K., see Neil Hobson’s post at http://neilhobson.blogspot.com/2010/11/powershell-bug.html for information.
Anything that we can do to cut down on repetitive calls to the Help Desk staff is a good thing. When a new employee starts, there are always questions about ‘what is my email address?’, and ‘how do I get to email from the web?”. For years, admins have come up with sometimes complicated methods to send a new user a canned email that tries to answer these questions. With Exchange 2007 and Exchange Management Shell (PowerShell), we can do this quite easily. In fact, the hardest part is deciding what to include in the email message. Let’s get started..
Let’s read some info from the registry to see when was the last time the script ran. If it hasn’t run before, let’s set some initial info:
$strScriptName = $MyInvocation.MyCommand.Name if (!(Get-ItemProperty HKLM:\Software\Innervation\$strScriptName -Name LastRun -EA SilentlyContinue)){ # this is the first time the script has run - let's create the registry key and value for future runs New-Item -path HKLM:\Software\Innervation -EA SilentlyContinue | Out-Null New-Item -path HKLM:\Software\Innervation\$strScriptName | Out-Null New-ItemProperty -path HKLM:\Software\Innervation\$strScriptName -Name "LastRun" -Value (Get-Date) -propertyType String | Out-Null write-host "Initial configuration completed." -ForegroundColor green } # get time stamp from registry so we know when it last ran $LastRun = Get-Date ((Get-ItemProperty -path HKLM:\Software\Innervation\$strScriptName -Name LastRun).LastRun) $ElapsedTime = ((Get-Date) - $lastrun).TotalSeconds
Let’s define some variables that we’ll use throughout the process.
$strMsgFrom = "Contoso HelpDesk " $strMsgTitle = "Welcome to Contoso!"
These set the From and Title for the email that we’ll send, as well as get today’s date, and the name of the script. Next, we create a new object to allow sending SMTP email:
$SMTPClient = New-Object Net.Mail.SmtpClient("localhost")
We can replace “localhost” with the IP address of a remote hub transport server if the script is not running on a hub transport server.
Next, we get a list of mailboxes that we need to send the email to. We’ll use a scheduled task to actually run the task. I run mine every 4 hours, but the code doesn’t care how often it runs. It will use the time stamp established above to email all mailbox created since then. We also want to avoid any mailboxes that are disabled. So our query looks like this:
$MBXArray = @(Get-Mailbox -ResultSize Unlimited | ? {($_.WhenCreated -gt (Get-Date).AddSeconds(-$ElapsedTime)) -and ($_.ExchangeUserAccountControl -ne "AccountDisabled")})
We now have an array, $MBXArray, that contains all of the mailboxes that we’ll email. We now cycle through the array via ForEach, and begin to assemble a personalized email message to each user. $mailbox holds the current account in the loop, so we can pull specific info for each user. Note that the text in $strBody is completely arbitrary – you can include whatever you want. Here’s a sample of one I did for a recent client:
ForEach ($mailbox in $MBXArray ) { $strMsgTo = $mailbox.PrimarySMTPAddress $strMsgBody = "Hello, "+$mailbox.DisplayName+", and welcome to the Contoso family! Please keep this email for future use. It contains vital information. -------------------------------------- Username and password -------------------------------------- Your network username is '"+$mailbox.SamAccountName+"'. Use your username and password to login to the network. Your password should NEVER be shared with anyone except the I.T. department, and only then when requested. Please do not write it down on anything that can be seen by your coworkers. You will be prompted to change it regularly. -------------------------------------- Email -------------------------------------- Your email address is '"+$mailbox.PrimarySMTPAddress+"'. To access your email, calendar, contacts, and tasks from outside of the building, such as from home, you can do so from any Internet connected computer. Simply open Internet Explorer and go to the Outlook Web Access (OWA) page at https://mail.contoso.com/ and log in using your username and password. Please note the 's' in https. If you’d like to have access to your email and contacts from your cell phone, you will need a cell phone that has Windows Mobile 5 or later, or an Apple iPhone. Blackberry phones are not supported. Instructions for configuring your device can be found in the Frequently Asked Questions (FAQ) section of the Contoso Intranet at https://intranet.contoso.com/helpdesk/Lists/SupportFaq/AllItems.aspx -------------------------------------- Contact information -------------------------------------- Once you’re situated, please go to http://directory/DirectoryUpdate and update your information. Log in using your username and password. It’s important that you update your information anytime something changes, such as title, department, phone number, etc. This information is used in various systems and applications, and is your responsibility to keep up to date. -------------------------------------- Computer, Email, and Internet policies -------------------------------------- Contoso, Inc. provides a computer for your work tasks. The use of personally owned computers and related equipment is not permitted on our network. Additional information about use of Contoso computers, email, Internet, etc. can be found in the Employee Handbook located in the HR section of the intranet at https://intranet.contoso.com/hr/ -------------------------------------- Technical assistance -------------------------------------- Should you need technical assistance, please check the Frequently Asked Questions (FAQ) section of the Contoso Intranet at https://intranet.contoso.com/helpdesk/Lists/SupportFaq/AllItems.aspx. If you cannot find an answer there, submit a Service Request on the Contoso intranet at https://intranet.contoso.com/helpdesk. If you are unable to access the intranet site, only then should you email HelpDesk@contoso.com. It is monitored by the whole IT department, and will ensure your issue is resolved in a timely manner. Thank you, and, again, welcome to Contoso! The Information Technology Department"
As you can see, we insert the user’s actual account name, email address, etc since that info is available in the ForEach loop. The message is just plain text, so spacing is preserved. URLs will be clickable links as well. Note: You’ll want to pay close attention to quotes and variables, as having an extra or missing quote can cause an error.
Now we actually send the message:
$SMTPClient.Send($strMsgFrom,$strMsgTo,$strMsgTitle,$strMsgBody) } # update registry here with a fresh time stamp Set-ItemProperty HKLM:\Software\Innervation\$strScriptName -Name "LastRun" -Value (Get-Date) | Out-Null
We’ll run this script on a hub transport server. So take the script, available in the DOWNLOAD section below, and save it in your \scripts folder. You’ll also need an Exchange receive connector that will accept email sent from PowerShell scripts. For that, see Creating a receive connector to use for sending email from PowerShell. Now, schedule a task to run every 4 hours using the info in Running PowerShell scripts via Scheduled Tasks.
Point of interest: In the text I send to the users, you’ll see a link to the Directory Update (http://directory/DirectoryUpdate in the example above). This is for Directory-Update, a VERY lightweight ASP app developed by fellow MVP and author Jim McBee and another developer. It’s completely customizable, and allows users to update selected fields of their AD account to help keep the Global Address List (GAL) current. It is worth the small cost, and really helps you keep the GAL full of correct info. I have another PowerShell script that checks AD account fields, and when it finds empty fields (phone number, title, etc), it sends them an email with a link to the Directory-Update web page. Combine that with Automatically updating the Global Address List with mobile numbers from Exchange ActiveSync and it’s like a self-cleaning oven!
Installation
Execution Policy: Third-party PowerShell scripts may require that the PowerShell Execution Policy be set to either AllSigned, RemoteSigned, or Unrestricted. The default is Restricted, which prevents scripts – even code signed scripts – from running. For more information about setting your Execution Policy, see Using the Set-ExecutionPolicy Cmdlet.
Donations
I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.
Download
v1.3 – 02-24-2013 – New-WelcomeEmail.v1.3.zip
ScriptImages.zip – image files used in emails
Changelog
See the changelog for this script for information on versions and what’s included/addressed in each.
Follow Me