Active Directory management & automation

Validate/Modify User Input Using a Script

With Adaxes, you can enforce various constraints on the data entered in Active Directory. For example, using Property Patterns, you can specify the format for any AD object property via a regular expression, make a property required, specify a list of possible values for a property, etc.

However, sometimes that's not enough and a more flexible approach is needed. For example, you may want to ensure that the Employee ID specified for a new user is unique in the directory, verify that a user with the specified ID exists in an HR database, automatically add a digit to the username if another user with the same username exists in AD, etc.

All this and more can be done with the help of scripts. In this tutorial, you will learn how to configure Adaxes to automatically execute a script before creating new users and how to validate and modify the user entered data with the help of this script.

To automatically execute a script that will validate the user's input, you need to create a Business Rule that will be executed before creating users in Active Directory.

1Launch Adaxes Administration Console, right-click your Adaxes service, point to New and click Business Rule. The Create Business Rule wizard will open.

Launching the Create Business Rule wizard

2Enter a name for the new Business Rule and click Next.

3Here you need to specify, when the new Business Rule must be executed. As we want to execute a script before user creation, do the following:

  • Select User in the Object Type list.
  • Select Before in the Operation section.
  • Select Creating a User in the Operation section and click Next.

Selecting the triggering operation for the Business Rule


4 At the next step, you need to specify, what the Business Rule will do before a new user is created. To run a PowerShell script, the Business Rule must execute the Run a program or PowerShell script action.

  • Click the Add Action link.
  • In the dialog that opens, select the Run a program or PowerShell script action.
  • Select PowerShell script in the Type field.
  • In the Short description field, describe what does your script do, its purpose or intention.

    Optionally, assign a custom description for the action

    You can assign a custom description for the Run a program or PowerShell script action that will replace the default description generated by Adaxes. To do this:
    • Click the Assign Custom Action Description button.
    • Type the description in the Custom action description field.

      Add custom action description.

Run PowerShell Script action.

To execute PowerShell scripts, PowerShell must be installed on the computer, where the Adaxes service is running. To install PowerShell, visit Script Center Downloads and follow the instructions provided there.

5 Type the text of the script in the Script field and click OK.


To pass parameters to the script, you can use value references (e.g. %username%). Before the script is executed, these value references will be replaced with the property values specified for the new user. For example, you can enter the following:

  $htable = @{FirstName="%firstname%";LastName="%lastname%";Department="%department%";}

After the replacement of the value references, this part of the script will look as follows:
  $htable = @{FirstName="John";LastName="Doe";Department="Marketing";}

Also, to get the data entered by the user and access other parameters of the operation, you can use a variable called Context. Context is a pre-defined PowerShell variable of the ExecuteScriptContext class. Using this variable, your script can determine whether a property was modified during the operation, get the value entered by the user for this property, modify this value, cancel the operation, update the operation Execution Log, and much more.

To cancel the operation, your script should call the Cancel() method of the Context variable:

  if ($isValueInvalid)
  {
      $Context.Cancel("The value is invalid.")
      return
  }

To check if a property was modified during the operation, call the IsPropertyModified() method.

To get the new value entered for a property, call the GetModifiedPropertyValue() method.

To change the value entered by the user, use the SetModifiedPropertyValue() method.

  if ($Context.IsPropertyModified("samAccountName"))
  {
      # Get the value specified by the user
      $newValue = $Context.GetModifiedPropertyValue("samAccountName")
      # Modify value
      $newValue = $newValue + "1"
      # Set the modified value
      $Context.SetModifiedPropertyValue("samAccountName", $newValue)
  }

To check if the user's password was modified during the operation, you can use the IsPasswordChanged() method.

To get the new password, call the GetNewPassword() method.

  if ($Context.IsPasswordChanged())
  {
      $newPassword = $Context.GetNewPassword()
      ...
  }

To update the Execution Log of the current operation, call the LogMessage() method of the Context variable. The second parameter of this method can take the following values: "Information", "Warning" and "Error".

  $Context.LogMessage("Username has been changed, as it was not unique.", "Information")

To get the domain name of the target object, call the GetObjectDomain() method of the Context variable. This method takes the Distinguished Name (DN) of an object as the input parameter.

  $domainName = $Context.GetObjectDomain("%distinguishedName%")

To send an e-mail or SMS message, you can use SendMail() and SendSms() methods of the Context variable.

  $Context.SendMail($toAddress, $subject, $bodyText, $bodyHtml)
  $Context.SendSms($mobileNumber, $text)

Example 1: Validate that Employee ID is unique and formatted correctly

Import-Module Adaxes
if ($Context.IsPropertyModified("employeeID"))
{
    # Get the value specified by the user
    $value = $Context.GetModifiedPropertyValue("employeeID")

    # Validate employeeID
    if (([System.String]::IsNullOrEmpty($value)) -or (-not($value.Contains("-"))))
    {
        $Context.Cancel("employeeID is invalid.")
        return
    }

    # Ensure that the employeeID is unique
    if ((Get-AdmUser -Filter 'employeeID -eq $value') -ne $NULL)
    {
        $Context.Cancel("A user with the specified Employee ID already exists!")
        return
    }
}
To use the script, you need to install Adaxes PowerShell Module on the computer, where your Adaxes service is running.

Example 2: Automatically add a digit to the username if it is not unique

Import-Module Adaxes
function IsUserNameUnique($username)
{
   $user = Get-AdmUser $username -erroraction silentlycontinue
   return $user -eq $Null
}
# Get the username
$username = $Context.GetModifiedPropertyValue("samAccountName")
# Check if the username is unique
if (IsUserNameUnique($username))
{
    return
}
# If the username is not unique, generate a unique one
$uniqueUsername = $Null
for ($i = 1; $True; $i++)
{
    $uniqueUsername = $username + $i
    if (IsUserNameUnique($uniqueUsername))
    {
        break
    }
}

# Update User Logon Name (pre-Windows 2000)
$Context.SetModifiedPropertyValue("samAccountName", $uniqueUsername)

# Update User Logon Name
$upnSuffix = $Context.GetObjectDomain("%distinguishedName%")
$userLogonName = $uniqueUsername + "@" + $upnSuffix
$Context.SetModifiedPropertyValue("userPrincipalName", $userLogonName)
$Context.LogMessage("The username has been changed to " + $userLogonName `
  + ".", "Information")
To use the script, you need to install Adaxes PowerShell Module on the computer, where your Adaxes service is running.

Example 3: Rename the user if the Full Name is not unique within the OU

Import-Module Adaxes
function DoesObjectExist($objectDN)
{
    $obj = Get-AdmObject $objectDN.ToString() -erroraction silentlycontinue
    return $obj -ne $Null
}
# Get the object DN
$objectDN = $Context.TargetObject.ObjectInfo.DN
# Check whether an object with the same DN already exists
if (-not (DoesObjectExist($objectDN)))
{
    return
}
$objectLeaf = $objectDN.Leaf
for ($i = 1;; $i++)
{
    # Build new distinguished name (DN)
    $objectName = $objectLeaf.Value + $i
    $objectRdn = New-Object "Softerra.Adaxes.Ldap.Rdn" $objectLeaf.Type,$objectName
    $objectDN = $objectDN.Parent
    $objectDN.AddLeaf($objectRdn)
    if (-not (DoesObjectExist($objectDN)))
    {
        # Rename the object
        $Context.SetModifiedPropertyValue("name", $objectName)
        $Context.LogMessage("Full Name has been changed to " + $objectName `
         + ".", "Information")
        break
    }
}
To use the script, you need to install Adaxes PowerShell Module on the computer, where your Adaxes service is running.

Example 4: Check the password length

$PasswordMinLength = 5
if ($Context.IsPasswordChanged())
{
    # Get the password that is going to be set
    $newPassword = $Context.GetNewPassword()
    # Check the password length
    if ($newPassword.Length -lt $PasswordMinLength)
    {
        $Context.Cancel("The password is too short.")
        return
    }
}

Example 5: Automatically remove spaces from the username

$spacesRemoved = $False
# User Logon Name (pre-Windows 2000)
if ($Context.IsPropertyModified("samAccountName"))
{
    $samAccountName = $Context.GetModifiedPropertyValue("samAccountName")
    if ($samAccountName.Contains(" "))
    {
        # Remove spaces
        $samAccountName = $samAccountName.Replace(" ", "")
        # Update sAMAccountName
        $Context.SetModifiedPropertyValue("samAccountName", $samAccountName)
        $spacesRemoved = $True
    }
}
# User Logon Name
if ($Context.IsPropertyModified("userPrincipalName"))
{
    $userPrincipalName = $Context.GetModifiedPropertyValue("userPrincipalName")
    if ($userPrincipalName.Contains(" "))
    {
        # Remove spaces
        $userPrincipalName = $userPrincipalName.Replace(" ", "")
        # Update the username
        $Context.SetModifiedPropertyValue("userPrincipalName", $userPrincipalName)
        $spacesRemoved = $True
    }
}
# Log a message
if ($spacesRemoved)
{
    $Context.LogMessage("Spaces have been removed from the username.", "Information")
}

Example 6: Replace characters in the username

$props = @("sAMAccountName", "userPrincipalName")
$map =@{ "å"="a"; "ö"="o"; "ä"="a";"ü"="u"; "ñ"="n"; "é"="e"; " "="-"; }

foreach ($prop in $props)
{
    if ($Context.IsPropertyModified($prop))
    {
        $value = $Context.GetModifiedPropertyValue($prop)

        foreach ($key in $map.Keys)
        {
            $value = $value.Replace($key, $map[$key])
        }

        $Context.SetModifiedPropertyValue($prop, $value)
        $Context.LogMessage($prop + ": " + $value, "Information")
    }
}
For more information on how to create scripts for Business Rules, Custom Commands, and Scheduled Tasks, see Server-Side Scripting.

For a list of all cmdlets contained in the Adaxes PowerShell module, see Adaxes PowerShell Module.

6 Optionally, you may want the new Business Rule to run the PowerShell script only if certain conditions are met. For example, to run the script only if the Department property of the user is set to Sales, perform the following steps:

  • Select the action/condition set (click the created action to highlight the set) and click the Add Condition icon.
  • In the dialog that opens, select the If <property> <relation> <value> condition type.
  • In the Condition Parameters section, specify Department equals Sales.
  • Click OK.

Adding Business Rule condition

You can also use a PowerShell script to check whether a condition is met. To test a condition with the help of a script:

  • Select the If PowerShell script returns true condition type.
  • In the Short description field, describe what does your script do, its purpose or intention.
  • Type the text of the script in the Script field.
  • Click OK.

Adding Business Rule condition

If a condition is met, your script must set the ConditionIsMet property of the $Context variable to $True:

$Context.ConditionIsMet = $True

Example 1: The condition is met if the user name contains a digit

$username = "%username%"
foreach ($char in $username.ToCharArray())
{
    if ([System.Char]::IsDigit($char))
    {
        $Context.ConditionIsMet = $True
        return
    }
}

Example 2: The condition is met if the Department property has changed and the Manager property hasn't changed

$departmentModified = $Context.IsPropertyModified("department")
$managerModified = $Context.IsPropertyModified("manager")
$Context.ConditionIsMet = $departmentModified -and -not $managerModified

Example 3: The condition is met if a user with the specified Employee ID is not found in an MS SQL database

$DatabaseHost = "localhost"
$DatabaseName = "HRDatabase"
$DatabaseTableName = "Users"
$DatabaseIDField = "UserId"

# Connect using the credentials of the default Adaxes service administrator
$DatabaseUsername = $NULL
$DatabasePassword = $NULL

$Context.ConditionIsMet = $True

$employeeId = "%employeeID%"
if ([System.String]::IsNullOrEmpty($employeeId))
{
    $Context.LogMessage("Employee ID is not specified!", "Warning")
    return
}

$connectionString =`
    "Data Source=$DatabaseHost; Initial Catalog=$DatabaseName;"
if ($DatabaseUsername -eq $NULL)
{
    $connectionString = $connectionString + "Integrated Security=SSPI;"
}
else
{
    $connectionString =`
        $connectionString + "User ID=$DatabaseUsername;Password=$DatabasePassword;"
}
$connection = New-Object "System.Data.SqlClient.SqlConnection"  $connectionString
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = "SELECT COUNT(*) FROM " + $DatabaseTableName + " WHERE " +`
    $DatabaseIDField + "=@UserID"
$command.Parameters.Add("@UserID", $employeeId) | Out-Null
$count = $command.ExecuteScalar()
$Context.ConditionIsMet = $count -eq 0

$command.Dispose()
$connection.Close()
For more information on how to create scripts for Business Rules, Custom Commands, and Scheduled Tasks, see Server-Side Scripting.

If necessary, specify other actions and conditions for this Business Rule. When finished, click Next.

7 Here, at the Activity Scope page, you need to specify where in Active Directory a user must be created to trigger the new Business Rule. Click Add.

Specifying rule activity scope

8 In the Business Rule Activity Scope dialog that opens, you need to specify the Active Directory locations where the Business Rule will be effective. Select one of the following items:

  • All Objects - select if you want this Business Rule to be executed when a user is created in any AD domain managed by the Adaxes service.

  • Specific Domain - select if you want this Business Rule to be executed when a user is created in the AD domain you specify.

  • OU or Container - select if you want this Business Rule to be executed only when a new user is created under the selected OU or container.

Select the item you need and click Add. When finished, click OK.

9 The specified activity scope items will be displayed in the Assignments list. Click Finish.

Now, when the Business Rule is complete, every time a new user is created (no matter in which way - using Administration Console, Web Interface, during data import, via an ADSI or PowerShell script, etc.), Adaxes will automatically execute your script prior to creating the user in AD.

? Waiting

Progress status: Checking...