This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Custom Password Generation Policy

Hi all,

We are looking for some help with a policy script that we plan to use for generating passwords with configurable length and complexity.  We basically took the built-in password generation policy script, converted it to PowerShell, set it to return a static password value, and applied it to a single OU.  So far the custom password generation policy only works when we either disable the built-in password generation policy or if we enable script debugging.

I assume that our attempt to override the built-in policy is failing which explains why the custom policy does work when we disable the built-in policy.  I'd appreciate any feedback that would help override the built-in policy so our implemenation is a little more straight forward. 

I cant explain why this policy magically starts working when we enable script debugging.  What changes in the scripting environment which would allow the new policy to work as expected?

Below is a copy of a watered down version of the script.  We've removed our password generation code and anything that was specific to our environment.  To test the script, we basically applied it as a provisioning policy to a single OU.  We then test password resets (using the generate password button) to see what password value is displayed.  We also test using the new account wizard (also leveraging the generate password button).

Any feedback would be helpful.  We didnt have any luck finding examples of others doing the same thing so I hope the eventual solution will benefit others.  Thanks!

function onGetEffectivePolicy($Request)
{
    $errcount = $Error.count

# Include script library
    $context.UseLibraryScript("PowerShell Best Practices")

    if (($Request.Class -ne "inetOrgPerson") -AND ($Request.Class -ne "user") ) {$Request.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE, "CustomPasswordPolicy-Wrong object type-exit"); return }

# Mark password as server-side generated.
    $Request.SetEffectivePolicyInfo("edsaPassword",$Constants.EDS_EPI_UI_SERVER_SIDE_GENERATED, $true)
   
# Determine whether server-side generation is requested (button pressed).
    $controlFullPolicyInfo = $Request.GetInControl($constants.EDS_CONTROL_FULL_EFFECTIVE_POLICY_INFO)
    if ($Error.count –ne $errcount)
    {
       $controlFullPolicyInfo = ""
    }

    if ($controlFullPolicyInfo -ne "edsaPassword") { return }

# Return static password value
    $Request.SetEffectivePolicyInfo("edsaPassword",$Constants.EDS_EPI_UI_GENERATED_VALUE, "123456789")
}

function onGetPolicyMarker()
{

# Override built-in Generate User Password Policy
    return "Generate User Password"
}

  • Bumping this one to see if anyone has any ideas. Thanks!
  • Matt,

    Can you put the final code you used to get this working. Please include all and if you have to use dummy info to hide your company info.

    Is there a section missing in the code above?

    I'm trying to do something similar in my environment.

  • Did you disable the built-in password generation policy before you turned on your's?

    There's quite a number of built-in provisioning policies that are linked at the domain level that you need to carefully examine and determine which ones to turn off (or specific rules within them to turn off) so that your own policies can take over.

    I don't recommend deleting any of the policy objects themselves but there's no reason you can't unlink them from the domain and replace them with your own.

  • I got the above script working for a static password but what i need is a powershell script that can formulate a password from a couple attribute values that the user has that is unique for each user and if they don't have those values then create a random generated password.

  • OK, within an ARS policy script you have two choices for obtaining attribute values:

    1) If the attributes are part of the transaction - for example a user creation:

    $MyFirstAttribute = $Request.get("<attribute name>")

    2) If the attributes are NOT part of the transaction but are already populated on the object:

    $MyFirstAttribute = $Dirobj.get("<attribute name>")

    So then you would do something like this:

    If ($MyFirstAttribute -eq $null) -or ($MySecondAttribute -eq $null)

    {

    <call to password generation function or insert password generation code here>

    }

    Else

    {

    $UserPwd = $MyFirstAttribute + $MySecondAttribute

    }

    Set-qadobject -proxy -identity $Request.GUID -objectattributes @{edsapassword=$UserPwd}

  • where would you put that in the script above? Also will it show the password in the WI when the admin selects "generate" password?

    Not sure why we are defining Set-qadobject when i thought WI would do that when select "Save"


    Thanks for the your help Johnnyquest

  • Got it working. I removed my domain and attribute information but here is the working script to replace the vbscript generate password.

     function onGetEffectivePolicy($Request)
    {
        $errcount = $Error.count


     # Include script library
        $context.UseLibraryScript("PowerShell Best Practices")

        if (($Request.Class -ne "inetOrgPerson") -AND ($Request.Class -ne "user") ) {$Request.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE, "CustomPasswordPolicy-Wrong object type-exit"); return }


     # Mark password as server-side generated.
        $Request.SetEffectivePolicyInfo("edsaPassword",$Constants.EDS_EPI_UI_SERVER_SIDE_GENERATED, $false)
        
     # Determine whether server-side generation is requested (button pressed).
        $controlFullPolicyInfo = $Request.GetInControl($constants.EDS_CONTROL_FULL_EFFECTIVE_POLICY_INFO)
        if ($Error.count –ne $errcount)
        {
           $controlFullPolicyInfo = ""
        }
        if ($controlFullPolicyInfo -ne "edsaPassword") { return }

     # Get Attributes for password
          $dirobj.getinfoex(@("sAMAccountName","attributename", "attributename", "attributename"), 0)
          $user = $dirobj.get("samAccountName")
        $sam = get-qaduser $user -searchroot 'DC=domainName,DC=com' -IncludedProperties attributename, attributename, attributename
        if
         (($sam.attributename -ne $Null) -AND ($sam.attributename -ne $Null)){$Pwd = ($sam.attributename)+($sam.attributename)+($sam.attributename)}
        else
         {$Pwd = ([char[]](Get-Random -Input $(48..57 + 65..90 + 97..122) -Count 8)) -join ""}
        
     # Return static password value

          $Password = $Pwd
        $Request.SetEffectivePolicyInfo("edsaPassword",$Constants.EDS_EPI_UI_GENERATED_VALUE, $Password)

    }

    function onGetPolicyMarker()
    {

     # Override built-in Generate User Password Policy
        onGetPolicyMarker = "Generate User Password"
    }