Being able to reset user passwords with an Active Directory self service portal can save you a ton of time! I have seen many options for handling this problem – most are not free and many can be a difficult to setup. By using Exchange and PowerShell, we are going to setup a free self service password reset tool for our Active Directory users.
We are going to start off with the password reset script, then configure it for your environment, and finally cover ways to get your users to use it. Give me 30 minutes and I’ll get you out of the “I forgot my password” business.
Self Service Password Reset PowerShell Script
Copy the script and paste it into a PowerShell ISE prompt. I’ll meet you at the bottom.
#Configuration Block $SmtpServer = "MAIL.DOMAIN.COM" $ResetEmail = "reset@DOMAIN.com" $Username = "DOMAIN\reset" $Password = "P@ssw0rd" $MailServer = "https://MAIL.DOMAIN.COM/ews/exchange.asmx" $ExchangeVersion = "Exchange2010_SP1" #User who shold recieve email notifications that a password was reset or an invalid request was sent. $LoggingUser = "YOUREMAIL@DOMAIN.com" #Download for file is here: http://www.microsoft.com/en-us/download/details.aspx?id=35371 [Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll") function Create-RandomString() { $aChars = @() $aChars = "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "C", "b", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9", "_", ";" $intUpperLimit = Get-Random -minimum 8 -maximum 10 $x = 0 $strString = "" while ($x -lt $intUpperLimit) { $a = Get-Random -minimum 0 -maximum $aChars.getupperbound(0) $strString += $aChars[$a] $x += 1 } return $strString } $email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion) $email.Credentials = New-Object Net.NetworkCredential($Username, $Password) $uri=[system.URI] $MailServer $email.Url = $uri $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox) if ($inbox.UnreadCount -gt 0) { $PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text; # Set search criteria - unread only $SearchForUnRead = New-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false) $items = $inbox.FindItems($SearchForUnRead,10) #return only 10 unread mail items Import-Module -Name ActiveDirectory foreach ($item in $items.Items) { # load the property set to allow us to view the body $item.load($PropertySet) if($item.Body.text -Like "*") { $Phone = $item.From.address $Phone = $item.From.address.substring(0, $Phone.IndexOf("@")) $user = Get-ADUser -Filter {MobilePhone -eq $phone} -Properties MobilePhone If ($user -ne $null) { $PW = Create-RandomString if ($PW.length -gt 1) { Set-ADAccountPassword -identity $user.samaccountname -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $PW -Force) Unlock-ADAccount -identity $user.samaccountname $PasswordAge = (Get-ADUser $user -Properties PasswordLastSet | Select PasswordLastSet) if ($PasswordAge.PasswordLastSet -ge (Get-Date).AddMinutes(-1)){ $Body = "Password reset for " + $user.SamAccountName + "-" + $user.DistinguishedName send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Password Reset - $PW" -body $Body -SmtpServer $SmtpServer send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your password is now $PW" -SmtpServer $SmtpServer } } } else { send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Invalid Phone number" -body "Phone number $Phone not found" -SmtpServer $SmtpServer send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your phone number was not found." -SmtpServer $SmtpServer } } $item.Isread = $true $item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite) } }
This awesome script comes from Gerald Moody. If you use Office 365, see the script at the end of this post.
Configuring Password Reset Self Service with PowerShell
At the top of the script, you’ll find the Configuration Block. You will need to set each of those variables for your environment. You will also need a dedicated AD account to use with this script. The account should have just the reset password permission delegated to it in Active Directory. It should also have a simple email (ex: reset@yourdomain.com).
Next, you will need to download the Microsoft Exchange Web Services Managed API 2.0 installer from here. Install this on the machine that will be hosting the script above. It does not have to be installed on your mail server. The machine’s IP will need to be able to send emails externally. A relay connector should be configured on your Exchange server. The machine that will run the script also needs the Active Directory PowerShell module installed. On Server 2012 R2, this is found in Add Roles and Features under the Remote Server Administration Tools location.
The function Create-RandomString controls what the password will be reset to. In the version above, a user will receive a password between 8 and 10 characters. Each character is randomly chosen from the $aChars array. Here is an example password: KbSDTxNeX . The random passwords will never contain confusing characters. You will notice that o,O,(zero),(one),l, and L are not in $aChars. You can remove/add any character to that line to change the way a random password is generated. For fun, remove every character but “a” and “b”. Then it will be like a cheat code to log back in. Moving on now…
Completely random passwords might not be your cup of tea. Reader Mike Liebstein replace the Create-RandomString function with the version below. It relies on a dictionary file (.\dict.csv) that is located in the same directory as the script. If you do not want to create a wordlist yourself, you can download this one.
function Create-RandomString() { $rand = new-object System.Random $conjunction = "or", "after", "as", "if", "than", "since", "the","my","we","our","and","but" $words = get-content .\dict.csv $word1 = ($words[$rand.Next(0,$words.Count)]) $con = ($conjunction[$rand.Next(0,$conjunction.Count)]) $word2 = ($words[$rand.Next(0,$words.Count)]) $strString = $word1 + "-"+ $con + "-" + $word2 Return $strString }
Finally, two points on security. First, at no point is a user’s name delivered to the end user. For a user to reset their password, their phone number has to be pre-entered into their AD account. A malicious user would have to have the username and a way to intercept the password. If your management is skittish about this method, you can add a security question to the process. Simply modify the search body portion of this script to match another user attribute to AD. Then inform your users to text your reset email with that attribute (like a birthday). If the cell number exists and the birthday matches, it resets the password.
Testing Your Self Service Password Reset Script
Now that your script is configured, create a scheduled task. The scheduled task needs to run as a user that can reset AD passwords. Set the scheduled task execute once a minute. Don’t worry about AD performance, AD is only queried if the $ResetEmail user has an unread message in its inbox.
Let’s test this out now. Open up Active Directory Users and Computers. Find a test user and enter your cell phone number under that user’s mobile phone attribute.
From your mobile phone, text your $ResetEmail. Put something in the body of the text (ex: Reset). Wait a minute (or manually execute the script or scheduled task). You should get a text back that looks like:
To verify that the password was changed, just open CMD and type: net user /domain USERNAME . Scroll down to the password last set line and you should see that the password was changed! When the $LoggingEmail variable is set, you will also receive an email confirming that the password has been set. In testing mode, the subject includes the password. This can be removed on line 71.
If the password hasn’t changed, check these common issues:
- Is the exchange version right in the Configuration Block?
- If you didn’t receive a text back, make sure the reset text message reached the inbox of the reset user. Make sure it was marked a read (processed).
- If you received a text back but the password didn’t change – check user permissions? Can your $ResetUser manually reset the user’s password?
- Some readers reported issues with the (ConvertTo-SecureString -AsPlainText $PW -Force) line – if needed, you can remove this from the Set-ADUser line.
Convincing Users to Stop Bothering You
To distribute this to your users, you can configure a custom logon message showing the email address that automates the password reset. No need for a separate web page, no need for dedicated machines pointing to a self service portal! To do this, set the Group Policy settings Interactive Logon: Message text and Interactive Logon: Message title. Both of these settings are found under: Computer Configuration/Policies/Windows Settings/ Security Settings/Security Options.
You can take a few routes to populate Active Directory with mobile numbers. If you would like a user driven (as in you don’t do the work) approach read this How To Guide and automate that process! If you can’t trust your users to do this (or have security policies against this), you can use this PowerShell approach by reader Michael Zinn.
$ImportCSV = import-csv "\\server\share\importfile.csv" foreach ($line in $ImportCSV) { $Mobile = $line.Mobile $Mobile = "$Mobile" -Replace "[^\d]" Set-QADUser -Identity $line.Username -MobilePhone $Mobile $Date= Get-Date Get-QADUser -Identity $line.Username | Select-Object Name,UserPrincipalName,MobilePhone,@{N="Date";e={$Date}} $User= Get-QADUser -Identity $line.Username
To get users accustomed to self service, you have to have buy-in from your whole IT department. Encourage helpdesk staff to direct users to reset their own passwords. It might be a bit more difficult at first but the benefits are huge in the long run. One college IT administrator told me that 26,000 passwords have been reset with this method over two years! Talk about awesome!
Have you implemented a self service password reset tool? Tell me about your experiences in the comments below.
Office 365 Self Service Password Reset Script
[Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll") function Create-RandomString() { $aChars = @() $aChars = "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "C", "b", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9", "_", ";" $intUpperLimit = Get-Random -minimum 8 -maximum 10 $x = 0 $strString = "" while ($x -lt $intUpperLimit) { $a = Get-Random -minimum 0 -maximum $aChars.getupperbound(0) $strString += $aChars[$a] $x += 1 } return $strString } $email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010) $email.Credentials = New-Object Net.NetworkCredential('reset@YOURDOMAIN.com', 'someOldPassword') $uri=[system.URI] "https://bl2prd0711.outlook.com/ews/exchange.asmx" $email.Url = $uri $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox) if ($inbox.UnreadCount -gt 0) { $sendMailCredentials = New-Object System.Management.Automation.PsCredential 'reset@YOURDOMAIN.com',(ConvertTo-SecureString -String 'YOURPASSWORDFORRESET' -AsPlainText -Force) $PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text; # Set search criteria - unread only $SearchForUnRead = New-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false) $items = $inbox.FindItems($SearchForUnRead,20) #return only 20 unread mail items foreach ($item in $items.Items) { # load the property set to allow us to view the body $item.load($PropertySet) if($item.Body.text -Like "*Reset my password*") { $Phone = $item.From.address.substring(0, $item.From.address.IndexOf("@")) if ($Phone.substring(0, 1) -eq "1") { $Phone = $Phone.substring(1) } $user = get-aduser -filter "mobilePhone -eq $Phone" If ($user -ne $null) { $PW = Create-RandomString if ($PW.length -gt 6) { Set-ADAccountPassword -identity $user.samaccountname -NewPassword (ConvertTo-SecureString -AsPlainText $PW -Force) Unlock-ADAccount -identity $user.samaccountname send-mailmessage -to "reset@YOURDOMAIN.com" -from "reset@YOURDOMAIN.com" -subject "Password Reset" -body "Password reset for $($user.SamAccountName) - $($user.DistinguishedName)" -SmtpServer pod51018.outlook.com -UseSsl -Port 587 -Credential $sendMailCredentials send-mailmessage -to $item.From.address -from "reset@YOURDOMAIN.com" -subject " " -body "Your password is now $PW" -SmtpServer pod51018.outlook.com -UseSsl -Port 587 -Credential $sendMailCredentials } } else { send-mailmessage -to "reset@YOURDOMAIN.com" -from "reset@YOURDOMAIN.com" -subject "Invalid Phone number" -body "Phone number $Phone not found" -SmtpServer pod51018.outlook.com -UseSsl -Port 587 -Credential $sendMailCredentials send-mailmessage -to $item.From.address -from "reset@YOURDOMAIN.com" -subject " " -body "Your phone number was not found." -SmtpServer pod51018.outlook.com -UseSsl -Port 587 -Credential $sendMailCredentials } } $item.Isread = $true $item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite) } }
Good article from Gerald Moody .This Power shell script is great.Thank you for sharing this article
https://cionsystems.com/
Good article from Gerald Moody .This Powerhshell script is great.Thank you for sharing this article
Any chance someone still monitoring this thread? 🙂
I’m able to confirm the email is received when I send the text from my phone, but it is not automatically processed as read. I did find I had to modify the LoadFile method and verified the script now executes without any errors, not sure what else to check. Suggestions would be greatly appreciated, excited to get this script up and running!
What’s odd, or maybe not, is if I remove my number from the test account and send another text, the designated email address receives an email stating the phone number is not found. Will post if I make any progress.
it could be a phone carrier issue – – how Att/verizon/tmobile process text to email is different – – there may be a ‘+1areacodenumber, or just number, or areacodenumber
Okay, as silly as it may sound I think the issue is with the task I created to run the script. At first it was running with no errors but nothing was happening and I noticed this in the logs “Task Scheduler failed to launch action “C:\Windows\System32\notepad.exe” in instance..” so I set all .ps1 files to open in PowerShell – no change. In the task under Action>Settings>Start in (optional) I tried adding powershell.exe and also C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe (NO QUOTES) – either case produces an error in taskmgr which indicates the issue is formatting based on some posts I read regarding the error value, 2147942667.
Sorry, feel like I’m getting hung up on the part that should be the most simple! If anyone has ran into this any more input would be tremendously appreciated! I’ll keep posting if I make any progress.
I hope this is still being monitored – – i’m trying to implement on a 2008 server – – using Exchange 2010 SP3 – – I’ve tried both the 2.0 and 2.2 EWS Api’s and get the following:
GAC Version Location
— ——- ——–
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.Exchange.WebServices\15.0.0.0__31bf3856ad364e35\Microso…
Exception calling “Bind” with “2” argument(s): “The response received from the service didn’t contain valid XML.”
At C:\scripts\password reset\Password_Reset_Self_Service.ps1:37 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Ex …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceRequestException
Was able to resolve this issue by fixing the following variable:
$MailServer = “https://MAIL.DOMAIN.COM/ews/exchange.asmx” – – I had copied and pasted the owa link directly from the browser – which had the .aspx extension and not asmx – – also
changing the Exchange to SP1 and using the 2.0 API
This is great. I’ve been working for a tech college for a few months now, they had no sspr service going on and I was getting pretty tired of resetting passwords (especially at a start of a new semester). I had to tweak it a bit to make it work with the users personal email addresses because the main carrier here (Montreal area), Videotron, won’t let us send emails to a phone number. Also I added a random token system for added security as email addresses are more of a risk. This frees me up while the students work on a web based portal. Cheers!
Alex your updates sound great, do you have a github to contribute and share your mods to by any chance?
I do, it’s empty but I’ll try and put it up there when I have a minute or two and share the link.
Hi, will this work without Exchange on our network?
How is the script sending SMS?
will this work with G-Suite smtp relay?
thanks
How do you get this to work with Exchange online?
Has anyone handled the attachment “text_0.txt” that some send with the body of the text message?
here is what I cam up with:
$result = $item.Body.Text #set message body to $result
if ($item.HasAttachments) #check for attachment and get that message for $result
{
foreach ($attach in $item.Attachments)
{
$attach.load()
$result = [System.Text.Encoding]::UTF8.GetString($attach.content) #set $result to attachmet content
}
}
Help!
I get the following when I run this:
PS C:\Windows> C:\Softlib\pwreset.ps1
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The request failed. The remote server returned an error: (401)
Unauthorized.”
At C:\Softlib\pwreset.ps1:37 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Ex …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceRequestException
Thanks. In advance.
Peter.
Does it store attributes on an AD User account?
Because that is read-permitted to all domain users, and would concern me.
Or does it store on a backend encrypted database?
Hi Gary – that password isn’t stored in AD at all.
Hi,
At first thanks for the script.
I’m working on an IT Department and my boss ask me to implement a system like that to AD passwords reset. I’m trying to implement your script in our LAB environment, although, We have hmailserver configured to send emails, I know that I need to change all exchange lines on your script to smtp scenario but I can’t found how.
Can you help me?
regards,
João Torres
Hi,
Sorry for replying to this old string. I would like to know, what mechanism required to send SMS? I could not notice any mention here how the carrier is used to send messages.
Hope someone could assist.
Thanks
I know this is an old post but, I am hoping someone could help me. I have the same issue that Doug had with T-Mobile and you can also add Goole Fi to that where the phone numbers are coming across with +1 in there. Has anyone come up with a way to drop the +1 when i comes across?
I keep getting the following error, not sure if its the relay connector ?
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The request failed. The underlying connection was closed:
Could not establish trust relationship for the SSL/TLS secure channel.”
At line:37 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Ex …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceRequestException
Hello Joesph,
Can we have some script for web based solution, instead of mobile phone, means a user can login from fellow user machine and would able to reset and unlock his or her password using the web login and answering few security questions.
Hello Joseph,
I am experiencing the below error when executing your script. FYI i am using exchange version 14.3.235.4001 and i don’t have the ability to run this from the exchange server. Is there anything you can tell me about the error to push me in the right direction?
GAC Version Location
— ——- ——–
True v2.0.50727 C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Exchange.WebServices\15.0.0.0__31bf3856ad364e35\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The response received from the service didn’t contain valid XML.”
At C:\Users\JAbreu.ASRC\Desktop\test.ps1:37 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[M …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceRequestException
Hi Jeff
Try this Exchange plugin instead of the one above in the post
http://www.microsoft.com/en-us/download/confirmation.aspx?id=42951
I wrote up a blog post on doing the verification through email rather than through a phone.
have a look if you are interested, works with o365 and you are welcome to copy it onto this page as well.
http://halcoberry.blogspot.com.au/2015/08/reset-user-passwords-with-ad-self.html
Sorry, thought I would clarify as well.
All our users have an AD attribute which has a recovery email address which is outside our email domain meaning they can reset the AD account as long as they have access to the recovery email address set in AD.
Has anyone had any problems with Verizon as a carrier? It looks like on Android devices they’ve implemented some kind of integrated messaging and the texts have a from address of [username]@vtext.com On iPhone, the from address is right, but instead of actually getting the text in the body of the email, it’s sent as a .txt attachment.
I’m trying to work this out, but having some issues. At first I was getting messages back saying it couldn’t match my phone number. I ran the query manually and the test account came right back. Then I looked at the emails that the reset mailbox was getting and from my provider(T-Mobile) includes +1 in front of my 10 digit cell phone number. It seems like this does invite some randomness into the results depending on how a particular provider inputs the numbers.
I tried fixing it by using:
$Phone = $item.From.address.substring(($Phone.IndexOf(“@”)-10), $Phone.IndexOf(“@”))
However for some reason when I echo $phone after that operation, I get [10 digit phone number]@t. I’m not sure why the string is ending there instead of at the @ like it does in the original script. Thoughts?
I know this thread is a bit dated. Just wanted to see if it was possible to allow modify the script to allow a user to choose the password?
In the Set-ADUser line, you can replace the $PW variable with $item.Body.text
Then the password would be set to what was in the subject of the text message that the user sends to the service.
Would it be possible to modify this script to also allow self-service account unlocks?
When the password is reset, it unlocks the account as well.
Or do you just want it to unlock the account for the user without resetting the password?
I’d like to have a trigger word that would only unlock the account instead of resetting the password.
Give this a test.
#Configuration Block
$SmtpServer = "MAIL.DOMAIN.COM"
$ResetEmail = "reset@DOMAIN.com"
$Username = "DOMAIN\reset"
$Password = "P@ssw0rd"
$MailServer = "https://MAIL.DOMAIN.COM/ews/exchange.asmx"
$ExchangeVersion = "Exchange2010_SP1"
#User who shold recieve email notifications that a password was reset or an invalid request was sent.
$LoggingUser = "YOUREMAIL@DOMAIN.com"
#Download for file is here: http://www.microsoft.com/en-us/download/details.aspx?id=35371
[Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll")
function Create-RandomString()
{
$aChars = @()
$aChars = "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "C", "b", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9", "_", ";"
$intUpperLimit = Get-Random -minimum 8 -maximum 10
$x = 0
$strString = ""
while ($x -lt $intUpperLimit)
{
$a = Get-Random -minimum 0 -maximum $aChars.getupperbound(0)
$strString += $aChars[$a]
$x += 1
}
return $strString
}
$email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion)
$email.Credentials = New-Object Net.NetworkCredential($Username, $Password)
$uri=[system.URI] $MailServer
$email.Url = $uri
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
if ($inbox.UnreadCount -gt 0)
{
$PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
# Set search criteria - unread only
$SearchForUnRead = New-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false)
$items = $inbox.FindItems($SearchForUnRead,10) #return only 10 unread mail items
Import-Module -Name ActiveDirectory
$Unlock = $False
foreach ($item in $items.Items)
{
# load the property set to allow us to view the body
$item.load($PropertySet)
if($item.Body.text -Like "unlock")
{
$Phone = $item.From.address
$Phone = $item.From.address.substring(0, $Phone.IndexOf("@"))
$user = Get-ADUser -Filter {MobilePhone -eq $phone} -Properties MobilePhone
If ($user -ne $null)
{
Unlock-ADAccount -identity $user.samaccountname
$Body = "Account unlocked for " + $user.SamAccountName + "-" + $user.DistinguishedName
send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Unlock Reset" -body $Body -SmtpServer $SmtpServer
send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your account is now unlocked." -SmtpServer $SmtpServer
$Unlock = $True
}
}
if($item.Body.text -Like "*" -and $Unlock -eq $false)
{
$Phone = $item.From.address
$Phone = $item.From.address.substring(0, $Phone.IndexOf("@"))
$user = Get-ADUser -Filter {MobilePhone -eq $phone} -Properties MobilePhone
If ($user -ne $null)
{
$PW = Create-RandomString
if ($PW.length -gt 1)
{
Set-ADAccountPassword -identity $user.samaccountname -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $PW -Force)
Unlock-ADAccount -identity $user.samaccountname
$PasswordAge = (Get-ADUser $user -Properties PasswordLastSet | Select PasswordLastSet)
if ($PasswordAge.PasswordLastSet -ge (Get-Date).AddMinutes(-1)){
$Body = "Password reset for " + $user.SamAccountName + "-" + $user.DistinguishedName
send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Password Reset - $PW" -body $Body -SmtpServer $SmtpServer
send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your password is now $PW" -SmtpServer $SmtpServer
}
}
}
else
{
send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Invalid Phone number" -body "Phone number $Phone not found" -SmtpServer $SmtpServer
send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your phone number was not found." -SmtpServer $SmtpServer
}
}
$item.Isread = $true
$item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
}
}
Finally got around to testing this out. The only thing I had to change is in the search for the “unlock” string, I had to use “*unlock*” because some providers provided extraneous information in the body. Thanks for the mod and for the original script!
No problem at all Doug!
This script works great. The only issue I am coming up against is that once I receive the “Password Reset” email with the LDAP user info (the logging info) it sends the script into a loop. The script then takes the “Password Reset” email and tries to find ldap info in our AD and I then receive the “invalid number” email in the “Reset Users” mailbox and then the loop starts. As a fix I have a rule for the “Password Reset” email to go to another folder but would like to see what I am missing or what could be done so I dont need to use a “work around”.
is there a way to single out the Password Reset email so its marked as “unread” and would not affect the true password reset emails from users?
Any suggestions or help would be greatly appreciated.
Thank you
M
I edited the codes to use native AD powershell and using a SMS gateway. Thanks for the original code!
Azza please post Edited Script.
Hey Can you please post edited script. Even i have sms gateway.
Running Exchange sp3 getting error:
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “Exchange Server doesn’t support the requested version.”
At C:\Scripts\EmailPasswordReset.ps1:34 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Ex …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceVersionException
I also tried updating to Microsoft Exchange Web Services Managed API 2.2 but that did not help either. http://www.microsoft.com/en-us/download/details.aspx?id=42951
If I change to SP2 it seems to run under the 2.2 API but I now get this error:
GAC Version Location
— ——- ——–
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.Exchange.WebServices\15.0.0.0__31bf3856ad364e35\Microsoft.Exchange.WebServices.dll
get-qaduser : The term ‘get-qaduser’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At C:\Scripts\EmailPasswordReset.ps1:51 char:12
+ $user = get-qaduser -MobilePhone $Phone
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (get-qaduser:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Sorry, I left out that it was exchange 2010 sp3
Hi Nick – you need to download the Quest AD Cmdlets to use the command get-qaduser.
You can use the normal AD version of this script (found a bit higher up on this page) if you would prefer to use native tools.
Hello Joseph,
I guess I’m unable to find the script that does not use Quest AD commands. Both links below use QADuser commands. Do you have a direct link to the script that does not use qaduser cmds?
Lines 51, 57-59
https://deployhappiness.com/reset-user-passwords-with-ad-self-service-portal/
Lines 53, 60-62
https://deployhappiness.com/free-self-service-password-reset-quest-active-directory
Hello. I am getting an error. I ran 1st on Windows 7 with Exchange tools installed. Then on my Exchange server. I get the same error on both.
PS C:\Users\administrator> $inbox = [Microsoft.Exchange.WebServices.Data.Folder]
::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
Exception calling “Bind” with “2” argument(s): “Exchange Server doesn’t support
the requested version.”
At line:1 char:60
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($email,[Mic
rosoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I have exchange 2007 build 83.6, which should be SP3, so I have the version in the script as Exchange2007_SP3. For the server variable at the top of the script I have my Client Access Server, $MailServer = "https://mail.mydomain.com/ews/exchange.asmx" where mydomain is the actual name.
Any help is appreciated. Thank you.
Found the cause of these errors. For some reason the script only works when set to SP1.
Thanks for the update Neil!
Hi,
I got this error
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The request failed. The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.”
At C:\Users\Akhil\Desktop\exchnage script.ps1:34 char:60
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I setup a test server for local testing and found the above error
please help me
my configuration is appended below. Please correct me if there is any mistakes
#Configuration Block
$SmtpServer = "192.168.5.167"
$ResetEmail = "user@isstest.com"
$Username = "user"
$Password = "123"
$Domain = "isstest.com"
$MailServer = "https://192.168.5.167/ews/exchange.asmx"
#Download for file is here: http://www.microsoft.com/en-us/download/details.aspx?id=35371
[Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll")
function Create-RandomString()
{
$aChars = @()
$aChars = "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "C", "b", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9", "_", ";"
$intUpperLimit = Get-Random -minimum 8 -maximum 10
$x = 0
$strString = ""
while ($x -lt $intUpperLimit)
{
$a = Get-Random -minimum 0 -maximum $aChars.getupperbound(0)
$strString += $aChars[$a]
$x += 1
}
return $strString
}
$email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$email.Credentials = New-Object Net.NetworkCredential($Username, $Password, $Domain)
$uri=[system.URI] $MailServer
$email.Url = $uri
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
if ($inbox.UnreadCount -gt 0)
{
$PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
# Set search criteria – unread only
$SearchForUnRead = New-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false)
$items = $inbox.FindItems($SearchForUnRead,10) #return only 10 unread mail items
foreach ($item in $items.Items)
{
# load the property set to allow us to view the body
$item.load($PropertySet)
if($item.Body.text -Like "*")
{
$Phone = $item.From.address
$Phone = $item.From.address.substring(0, $Phone.IndexOf("@"))
$user = get-qaduser -MobilePhone $Phone
If ($user -ne $null)
{
$PW = Create-RandomString
if ($PW.length -gt 6)
{
Set-QADUser -identity $user.samaccountname -UserPassword (ConvertTo-SecureString -AsPlainText $PW -Force)
Unlock-QADUser -identity $user.samaccountname
$PasswordAge = (Get-QADUser $user |select-object PasswordLastSet)
if ($PasswordAge.PasswordLastSet -ge (Get-Date).AddMinutes(-1)){
$Body = "Password reset for " + $user.SamAccountName + "-" + $user.DistinguishedName
send-mailmessage -to $ResetEmail -from $ResetEmail -subject "Password Reset" -body $Body -SmtpServer $SmtpServer
send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your password is now $PW" -SmtpServer $SmtpServer
}
}
}
else
{
send-mailmessage -to $ResetEmail -from $ResetEmail -subject "Invalid Phone number" -body "Phone number $Phone not found" -SmtpServer $SmtpServer
send-mailmessage -to $item.From.address -from $ResetEmail -subject " " -body "Your phone number was not found." -SmtpServer $SmtpServer
}
}
$item.Isread = $true
$item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
}
}
What happens if you run this script on your exchange server?
Exception calling “LoadFile” with “1” argument(s): “The system cannot find the
file specified. (Exception from HRESULT: 0x80070002)”
At C:\Documents and Settings\administrator.ISSTEST\Desktop\reset pswd.ps1:10 ch
ar:32
+ [Reflection.Assembly]::LoadFile( <<<< "C:\Program Files\Microsoft\Exchange\We
b Services\2.0\Microsoft.Exchange.WebServices.dll")
Unable to find type [Microsoft.Exchange.WebServices.Data.ExchangeVersion]: make
sure that the assembly containing this type is loaded.
At C:\Documents and Settings\administrator.ISSTEST\Desktop\reset pswd.ps1:30 ch
ar:126
+ $email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Micr
osoft.Exchange.WebServices.Data.ExchangeVersion]: <<<< :Exchange2007_SP1)
Property 'Credentials' cannot be found on this object; make sure it exists and
is settable.
At C:\Documents and Settings\administrator.ISSTEST\Desktop\reset pswd.ps1:31 ch
ar:8
+ $email.C <<<< redentials = New-Object Net.NetworkCredential($Username, $Passw
ord, $Domain)
Property 'Url' cannot be found on this object; make sure it exists and is setta
ble.
At C:\Documents and Settings\administrator.ISSTEST\Desktop\reset pswd.ps1:33 ch
ar:8
+ $email.U <<<< rl = $uri
Unable to find type [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]:
make sure that the assembly containing this type is loaded.
At C:\Documents and Settings\administrator.ISSTEST\Desktop\reset pswd.ps1:34 ch
ar:125
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft
.Exchange.WebServices.Data.WellKnownFolderName]: <<<< :Inbox)
I am using 2003 server for hosting exchnage
Two things – did you download the API? Did you change the exchange version in the script on line 21?
In my first comment I was run the script on a Win 7 machine. In that machine I installed the API and changed the line 21.
In second comment I run the same script in Win 2003 server. But I did not get the API for windows 2003 server. Changed the line 21.
How do I do this without an exchange serveR?
I set this PowerShell script up. but im never receive a sms back from the exchange server. I also ran the NetBIOS command to see if the password has changed and it hasn’t. Script run fine with no errors. AD has the telephone phone number in this format 1234567890 (no spaces or special characters).
Also we use iphones it makes the sms into an email but the message becomes a txt attachment. Should that even matter as long as we type “reset my password”?
Exchange 2010 SP2
Office 365 does allow text messaging ONLY in US, Canada & Romania!
Anybody in UK is out of luck
Or am I being somehow mistaken?
Hi,
I have a problem:
I have filled in the details at the top of the script.
im using Exchange 2013 with SP1 so i changed the $email line to this:
$email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)
I assumed to save the script as a .ps1 extension.
I have sent a text from “three UK” mobile phone and recieved it into the inbox of my password reset mailbox.
I have added my mobile number into the AD mobile field beginning 44 (drop the 0 and/or the +)
when the script runs this comes up in powershell:
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
No other message etc no failure no sms sent.
any help appreciated.
Thanks,
Chris
can any one suggest me….
Do i need a SMS Server set up in my enviornment before using thsi script…?
You just need an exchange/office365 server.
sry for the late reply….in our environment we do have exchange server but how would i enable sms thing?
i mean how how would i sending a user their password on their mobile through sms…
The script will email the user back. The email is sent to their phone number’s email address – the carrier converts it into a text message.
Thanks for the great script!
Nearly got it working apart from the following:
Vodafone UK uses an individual unique message “Reply-To” address for return messages and rejects any replies to the displayed FROM address (syntax “phonenumber@mms.vodafone.co.uk”)
Any ideas on how to use the Reply-To address instead?
Ok so I found a work around by using an external SMS Gateway.
Works great now!
Only slight issue is that mobile numbers need to be stored in AD without the + prefix.
Eg: 44234567891 rather than +44234567891
What did you need to do to set it with external SMS gateway?
Does that work with any UN mobile network?
Can you please share the sms gateway mode
Thank you
Regards
Thanks for very valuable script.
Our boss doesn’t like fully self serve service for audit reason, so can you please guide me to tweak script so that still user send me lockout email but I as administrator reset that particular user password and once I recive, I can forward to my users.
You can use a script like this: http://blogs.technet.com/b/heyscriptingguy/archive/2011/08/31/use-powershell-to-find-locked-out-user-accounts.aspx
I have this setup and it is awesome! I modified it to use the ‘code word’ in the body of the text/email so the ‘From’ address couldn’t be spoofed. My only issue is that when I receive emails from an iPhone, the body does not contain the code word. Instead, the body of the email is empty and the iPhone sends the body of the text as an attachment. Anyone find a work around? Possibly checking to see if the body is empty, and if so, read the content of the attachment?
What if I want to use the email field in their AD profile(instead of exchange). So basically they could message reset@yourdomain.com with their cell, it would be authenticated through their ad profile but instead of pulling through exchange to email them the reset is there a way the script could just pull from their email in their profile. This would help with google users. I don’t need the script to read their email only authenticate their phone number and then email them a new password.
Any tips or suggestions?
Hey Morgan – this is possible but you will have to tweak the script a bit.
Check out Gerald’s reply to Wardag which is a few below your comment. He asked a very similar question. Let me know if you have issues.
I want to use this script but want to be able to send from an email address and reply with a new password to another e-mail address … can this be achieved modifying this script ?
Just to clarify: are you wanting the password to be sent to another email address instead of from a cell phone?
yes I want the password sent to another e-mail address
Hi Wardag,
At line 51 add:
$userMail = get-aduser $user.samaccountname -properties mail
and replace $item.From.address in line 60 with to $userMail.mail, assuming that you have the person’s email address in AD.
Hello Geraldo.
At first, thanks for the script.
In my AD structure, we already have a secondary e-mail address added in the wWWHomePage attribute field.
Can you help me. please?
🙂
The Reset Mailbox is getting the mms messege in this format: phonenumber@myserviceprovider.domain ,But
My exchange server can not send sms to the sender back.
what do i need ? i have an sms getway (sns++) but this system can send sms to phone number without the suffix “@myserviceprovider.domain ” …
please help!
Thanks,
Aviv
I am having an issue with this script.
The password sent to the user via SMS does not match the password that the script sets in AD. Every time a user inputs the password sent to them, they are denied with “invalid credentials”. Any help would be greatly appreciated. I made a few modifications to the script however, none of my changes are related to the random password generation variable.
It would be worth noting in your documentation that Quest Active Directory Module is required for this script to run.
Go into the script and add a debugging statement above the Set-ADAccountPassword -identity $user.samaccountname … statement – something like: Write-Host $PW, and see if it is the same one being sent to the user via sms; run the line Set-ADAccountPassword -identity $user.samaccountname -NewPassword … by itself and see if the user can login. You could also sms/email the password to yourself to verify it.
Hi, thanks for this post! I’m very interested in trying this but I receive this error message when I try to execute the script:
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\M…
Exception calling “Bind” with “2” argument(s): “The request failed. The underly
ing connection was closed: Could not establish trust relationship for the SSL/T
LS secure channel.”
At C:\Temp\SelfPWReset\Script.ps1:34 char:60
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind( <<<< $email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
I'm not that experienced with Exchange so could anyone point me in the right direction?
Hi Carl,
What version of exchange are you running?
We’re running Exchange 2007 08.03.0137.000
Have you updated this line:
$email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1) to reflect your Exchange 2007 Service Pack version?
Yes, I’ve changed it to SP3. I’ve gotten past the first problem now but now I receive this:
Exception calling “Bind” with “2” argument(s): “The request failed. The remote
server returned an error: (401) Unauthorized.”
At C:\Temp\SelfPWReset\Script.ps1:34 char:60
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind( <<<< $email,[Mic
rosoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
I've tried all sorts of administrator accounts in the script so I don't understand the Unauthorized code. Is there any special permission in exchange that I need to add?
It appears that you might be using an incorrect username and/or password in the $email.Credentials = statement. At least that is what the error indicates.
Hi,
Thanks for the great post.
I would like to bring into your notice that I am also getting the same error.
False v2.0.50727 C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The request failed. The underlying connection was closed: Could not est
ablish trust relationship for the SSL/TLS secure channel.”
At C:\PasswordReset\Script.ps1:34 char:60
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind <<<< ($email,[Microsoft.Exchange.WebServices.Data.WellKno
wnFolderName]::Inbox)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
I have verified the user credentials are correct.
Your kind assistance required.
Thank You.
MAK
Now I am getting the same error as Carl is getting:
GAC Version Location
— ——- ——–
False v2.0.50727 C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll
Exception calling “Bind” with “2” argument(s): “The request failed. The remote server returned an error: (401)
Unauthorized.”
At C:\PasswordReset\Script.ps1:34 char:1
+ $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Ex …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ServiceRequestException
Although, I am using the exchange admin account to run this script.
Please, your help required.
regards,
MAK
Carl,
Were you able to resolve this problem?
Any help is highly appreciated.
Thanks
MAK
You must use the account that you are going to read the emails from. It is possible that you could give the permissions to another account to read someone else’s emails, but why?
Thanks Gerald for your reply.
Apologies for late reply, I was badly suffering from fever and was bit away from my work.
Actually, I am using only one account. Let me show you my configuration block:
————————————
#Configuration Block
$SmtpServer = “server01.abcxyz.com”
$ResetEmail = “reset@abcxyz.com” (users will send sms to this address)
$Username = “reset”
$Password = “*****”
$Domain = “abcxyz.com”
$MailServer = “https://email.abcxyz.com/ews/exchange.asmx”
then i make the changes in ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
———————————————————————
Then I define the scheduled task to run with the exchange admin account that i usually use to reset users’ password.
Thats all what i am doing. Have I missed anything?
Please correct me if I had made a mistake.
Regards,
MAK
All of your variables look right with the exception of the $domain; it should be the NetBIOS name of the domain. In your example, I would assume abcxyz.
Gerald,
This idea is brilliant!!! Any thoughts on, how to pull this off using Lotus Domino Mail Server??
Please confirm , if my understading is correct!
1. Users sends a message from their phones , to $ResetEmail (reset@mydomain.com)
I tried sending a text message from my phone to my email. It is reaching my inbox as an MMS (The message format is “phonenumber@myserviceprovider.domain” .Is this an expected outcome ?
2. Powershell script , searches for unread message in inbox of email : reset@mydomain.com ; identify AD id’s of the phone number(s) that sent an email / message.
3. Generate a random password , respond to the message / mail that was sent with a new password. (I am assuming , a response is send to the phone number from where the message was received)
From my mail , i responded to the message that I received from my phone number. I dint not receive a response to my phone. I did not get any failure messages either !!
Please shed some light on , how to get this done.
And thank you so much for , even sharing this thought in first place 🙂
Cheers
Karthik
You are correct; the code views all unread emails looking for “Reset my password” in the body. If the text is found, it looks in AD, mobilePhone attribute, for a matching phone number. If it finds it, it generates a random password, resets the password and unlocks the account, then it emails the password to the sender, and emails itself only who it reset the password for – audit purposes.
If it does not find it, it emails the sender that the phone number sent from is not in the database, and it also sends itself the information of the invalid number – audit purposes again.
Finally, it marks the email as read.
If Lotus Domino mail uses POP and SMTP, there are numerous sites showing how to use Powershell to view and send email. Simply replace the Exchange lines with POP3 and SMTP functions and you will be in business.
Let me know how it goes,
Gerald
seems as if 2003 cannot get use of it due to the missing EWS.
cool script anyways!
Hi,
Love the idea, but I am wondering can this be adapted to work with a cloud mail solution like Gmail? Also do you need any other 3rd part tool to send the SMS message?
Julian
I am not sure about Gmail but I would bet you could do it with Office365!
Will Steele has a function at http://poshcode.org/3195 that reads gmail via PowerShell. Though it needs work, it is a good starting place.
I hope this helps,
Gerald
Did you ever get this to work with gmail?
Thank you both! Let me know if you have any issues setting it up!
Just wanted to let you know I had no issue getting this setup at all. Since this was your project and we do work at the same place. But it is awesome thank you for lowering my ticket load.
I do enjoy this concept. At first I was skeptical, but the use of a corporate phone to facilitate the delivery of the password might make it viable. I am pitching the idea to my director to give it a test run. Who knows, maybe it will help alleviate some ticket load from my Helpdesk. I know they would appreciate it.
This is awesome when is it going to be setup