Reset Passwords for users in a specific OU

Hi There

we have a new HR system that is using Powershell to Create users. Unfortunately, this does not output the passwords so we cannot send them to the managers.

Is there a way to reset the passwords for any users that get created in this OU using a generic password?

I have got a script that generates a password, I cant seem to get it to Reset the users password.

$Users = get-qaduser -SizeLimit 10000 -SearchRoot 'ou=new users,dc=test,dc=Local' -IncludedProperties DisplayName, SamAccountName

function Get-RandomPassword {
$length = 10
$characters = 'abcdefghkmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ'
$nonchar = '123456789!$%&?#'
$random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
$random2 = 1..2 | ForEach-Object { Get-Random -Maximum $nonchar.length }
$private:ofs= ""
$ThePassword = [string]$characters[$random] + [string]$nonchar[$random2]
return $ThePassword
}

function Reset-ADPassword {
foreach ($User in $Users) {
$Username = $User.SamAccountName
$DisplayName = $User.DisplayName
$Password = Get-RandomPassword

Write-Host $DisplayName / $Username / $Password
Set-ADAccountPassword -id $username -NewPassword (ConvertTo-SecureString -AsPlainText $Password -Force)
}

  • Do you have Active Roles in your environment or is this purely a scripting question?  No problem if you don't - just want to make sure that I address the issue in a manner that makes sense for your environment.

  • Thank for the quick Reply, 

    We have Active Roles at the moment, but due to the New HR system, I have a separate server in Dev to test a few changes we have to do as part of this.

  • Is your new HR system provisioning directly into AD (and bypassing Active Roles)?

    If yes, then what you could do is implement code something like you have above in the form of a onPostCreate handler.

    This would be included in a policy script which you would include in a provisioning policy.

    The concept is covered here in the documentation.

    The code for the policy script would look something like this:

    function Get-RandomPassword {
    $length = 10
    $characters = 'abcdefghkmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ'
    $nonchar = '123456789!$%&?#'
    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
    $random2 = 1..2 | ForEach-Object { Get-Random -Maximum $nonchar.length }
    $private:ofs= ""
    $ThePassword = [string]$characters[$random] + [string]$nonchar[$random2]
    return $ThePassword
    }

    function OnPostCreate ($Request) {

    # Is the detected create event for a user object?
    # If not, then don't run the rest of the script

    If ($Request.class -ne "user"){return}

    # Get the distinguishedname (DN) of the just created user

    $InProcessUser = $Request.DN

    # Generate a password for the new user

    $Password = Get-RandomPassword

    # Bind to the user via Active Roles - EDMS means the call is going through Active Roles

    $NewUserObj = [ADSI]"EDMS://$InProcessUser"

    # Set the Active Roles user password property

    $NewUserObj.Properties["edsaPassword"].Value = $Password
    $NewUserObj.CommitChanges()

    # Add some code here to send the new password (stored in $Password) to the Manager

    } # End of onPostCreateHandler

    This article explains the concept of detecting changes made outside of Active Roles.

  • Thank you. I will try this & get back to you.

  • HI Johnny

    Sorry for the long delay.

    So I can see this script above works, for creating the password but for some reason doesn't reset the user's password.

    I don't get an error, so I assumed it had worked but it hasn't. So I have made a slight change to it, Here it is, let me know if you can see any issues.

    $Users = get-qaduser -SizeLimit 10000 -SearchRoot 'ou=New User Staging (ES),ou=New Starters & People Changes,dc=test,dc=Local' -IncludedProperties DisplayName, SamAccountName

    function Get-RandomPassword {
    $length = 10
    $characters = 'abcdefghkmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ'
    $nonchar = '123456789!$%&?#'
    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
    $random2 = 1..2 | ForEach-Object { Get-Random -Maximum $nonchar.length }
    $private:ofs= ""
    $ThePassword = [string]$characters[$random] + [string]$nonchar[$random2]
    return $ThePassword
    }

    function onPostCreate($Request)
    {

    # Is the detected create event for a user object?
    # If not, then don't run the rest of the script

    if ($Request.class -ne "user"){return}

    # Get the distinguishedname (DN) of the just created user

    $InProcessUser = $Request.DN

    # Generate a password for the new user

    $Password = Get-RandomPassword

    # Bind to the user via Active Roles - EDMS means the call is going through Active Roles

    $Users = $NewUserObj

    # Set the Active Roles user password property

    $NewUserObj.Properties["edsaPassword"].Value = $Password
    $NewUserObj.CommitChanges()

    # Add some code here to send the new password (stored in $Password) to the Manager


    Sub onPreCreate(Request)
    rez = Request.Get("edsaPassword")
    Request.Put "edsvaTempPassword", rez
    end Sub
    }

    also as I am not getting notified what the password is.

    this is the notification template I am using.

    <%@ Page Language="C#" Inherits="ActiveRoles.Common.Services.MailMessageTemplate"%>
    <%@ Import Namespace="System"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">www.w3.org/.../xhtml1-transitional.dtd">
    <html xmlns="">www.w3.org/.../xhtml">
    <!-- <p><img src="">file.test.co.uk/.../header.gif" alt="Header" />&nbsp;</p> -->
    <head>
    <title>IMPORTANT: New Employee: <% =Operation.TargetObjectDisplayName %> Login Details &amp; Regulatory Learning</title>
    <style type="text/css">body { font-family: Arialt, sans-serif; }a:link {color:#40474f;}a:visited {color:#40474f;}
    .pageHeader {
    width:auto;
    padding:0px;
    }

    img {
    width: 100%;
    height: 100%;
    max-width: 1441px;
    max-height:73px;
    object-fit: contain;
    }
    </style>
    </head>
    <body>
    <div class = "pageHeader">
    <p id="Header Image"><img src="">file.test.co.uk/.../p>
    </div>
    <p>To enable your new starter to thrive in their career at Test, we have listed below important details that both of you need to action to support their onboarding. They are as follows:</p>

    <p><strong><u>New Starter Login Details</u></strong></p>

    <strong>Login Details </strong><br />
    <table border="1">
    <tbody>
    <tr>
    <td width="132">
    <p>Start Date</p>
    </td>
    <td width="170">
    <p><% =Operation.Target["extensionAttribute6"] %></p>
    </td>
    </tr>
    <tr>
    <td width="132">
    <p>User Login</p>
    </td>
    <td width="170">
    <p><% =Operation.Target["samAccountName"] %></p>
    </td>
    </tr>
    <tr>
    <td width="132">
    <p>User Password</p>
    </td>
    <td width="170">
    <p><% =Operation.Target["edsvaTempPassword"] %></p>
    </td>
    </tr>
    </tbody>
    </table>

  • This:

    Sub onPreCreate(Request)
    rez = Request.Get("edsaPassword")
    Request.Put "edsvaTempPassword", rez
    end Sub

    ...is not valid Powershell code (Looks like VBscript to me)

    If you want to save the password to a virtual attribute, I would just update the section where you are setting the password:

    # You already have the password in the variable $Password

    # Set the Active Roles user password property

    $NewUserObj.Properties["edsaPassword"].Value = $Password
    $NewUserObj.Properties["edsvaTempPassword"].Value = $Password

    $NewUserObj.CommitChanges()

  • thanks, how do I get that in a notification?

    the above template I have has "Operation.TargetObjectDisplayName", but I don't think I can use that for a search object, it that right

  • Hi Johnny

    do you have any idea how I can get the password sent in an email please?

  • Ok I think I have managed to sort this out now. Here is what I have managed to do so Far.

    $Users = get-qaduser -SizeLimit 10000 -SearchRoot 'ou=End Users & Computers,dc=Domain,dc=Local' -Properties DisplayName, SamAccountName, ExtensionAttribute6, manager

    function Get-RandomPassword {
    $length = 10
    $characters = 'abcdefghkmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ'
    $nonchar = '123456789!$%&?#'
    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
    $random2 = 1..2 | ForEach-Object { Get-Random -Maximum $nonchar.length }
    $private:ofs= ""
    $ThePassword = [string]$characters[$random] + [string]$nonchar[$random2]
    return $ThePassword
    }
    foreach ($User in $Users) {
    $Username = $User.SamAccountName
    $DisplayName = $User.DisplayName
    $Password = Get-RandomPassword
    $Startdate = $User.ExtensionAttribute6

    # This will be the distinguishedName of the manager of the user.
    $ManagerDN = (Get-ADUser -Identity $User.sAMAccountName -Properties manager).manager

    # Retrieve the email address of the manager.
    $MgrEmail = (Get-ADUser -Identity $ManagerDN -Properties EMailAddress).EMailAddress

    # Write-Host $DisplayName / $Username / $Password / $MgrEmail
    # $DisplayName, $Password | Out-File c:\temp\Password.txt -append
    Set-ADAccountPassword -Identity $username -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $Password -Force)
    # Set-ADUser -Identity $username -ChangePasswordAtLogon $true

    $report = "<html>
    <body>
    <p>To enable your new starter to thrive in their career at Test, we have listed below important details that both of you need to action to support their onboarding. They are as follows:</p>

    <p><strong><u>New Starter Login Details</u></strong></p>
    <br><br />
    <strong>Login Details </strong><br />
    <tbody>
    <tr>
    <p>Start Date</p>
    </td>
    <p>$Startdate</p>
    </td>
    </tr>
    <tr>
    <p>User Login</p>
    </td>
    <p>$Username</p>
    </td>
    </tr>
    <tr>
    <p>User Password</p>
    </td>
    <p>$Password</p>
    </td>
    </tr>
    </tbody>
    </table>
    </html>
    "

    Send-MailMessage -To $MgrEmail,Users@test.co.uk -From activerolesnp@test.co.uk -Body $report -subject "IMPORTANT: New Employee: $Username Login Details & Regulatory Learning" -SmtpServer smtp -BodyAsHtml
    }

    This all works fine when I run it as is. The problem I have when I add this to the script module, I run the work flow I get 2 emails for each user instead of 1 when running it from the powershell. 

    Is there something in the WorkFlow I need to change?