Script repository

Import new and updated users from CSV file

Updated on: Jan 18, 2026, Views: 16836

Import data

The scripts update existing and create new user accounts based on the data in the CSV file. To execute either of the scripts, create a scheduled task configured for the Domain object type and add a managed domain to the Activity Scope of the task. The domain will only be used to trigger execution of the scheduled task.

To use the scripts, install the Adaxes PowerShell module on the computer where the service runs.

Script 1: Create new and update existing users

Existing accounts are updated and non-existing ones are created in Active Directory based on the data in the CSV file.

Parameters

  • $csvFilePath - the path to the CSV file to import.
  • $userIdColumn - the name of the column that contains values of the property for identifying existing users.
  • $userIdProperty - the name of the property for identifying existing users (e.g. sAMAccountName, employeeID).
  • $accountPasswordColumn - the name of the column that contains account passwords.
  • $customColumnNames - Maps column headers with names of the corresponding user properties. If mapping is not specified for a column header, the header specified in the file will be used as the property name.
  • $aDObjectProperties - the headers of the columns that contain references to other AD objects, such as, Manager, Secretary or Assistant. Objects can be referenced in the columns by their:
    • Distinguished Name
    • Full Name
    • Display Name
$csvFilePath = "\\SERVER\share\ImportUsers.csv" # TODO: modify me
$userIdColumn = "EmployeeName" # TODO: modify me
$userIdProperty = "sAMAccountName" # TODO: modify me
$accountPasswordColumn = "AccountPassword" # TODO: modify me
$customColumnNames = @{
    "JobTitle" = "title";
    "FirstName" = "givenName";
} # TODO: modify me
$aDObjectProperties = @("Manager", "Secretary") # TODO: modify me

$domainName = $Context.GetObjectDomain("%distinguishedName%")
$importedUsers  = Import-Csv -Path $csvFilePath

foreach ($userFromCSV in $importedUsers)
{
    $userObject = @{}
    $accountPassword = $NULL
    $propertiesToClear = @()
    foreach ($property in $userFromCSV.PSObject.Properties)
    {
        $columnName = $property.Name
        $value = $property.Value
        
        if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value)))
        {
            $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
            continue
        }
        elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value))
        {
            continue
        }
        
        if ($customColumnNames.ContainsKey($columnName))
        {
            $propertyName = $customColumnNames[$columnName]
        }
        else
        {
            $propertyName = $columnName
        }
        
        if ([System.String]::IsNullOrEmpty($value))
        {
            $propertiesToClear += $propertyName
            continue
        }

        # Parse special columns.
        if ($columnName -ieq $userIdColumn)
        {
            $propertyName = $userIdProperty
        }
        elseif ($aDObjectProperties -icontains $columnName)
        {
            $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
            
            if ($aDObject -is [System.Array])
            {
                $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                continue
            }

            if ($aDObject -eq $NULL)
            {
                $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                continue
            }
            
            $value = $aDObject.DistinguishedName
        }

        if ($value -ieq "True" -or $value -ieq "False")
        {
            $value = [System.Boolean]::Parse($value)
        }

        $userObject.Add($propertyName, $value)
    }
    
    # Check whether the user exists.
    $valueForSearch = $userObject.$userIdProperty
    $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" `
        -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
    if ($userExists -eq $NULL)
    {
        # Build user name.
        $displayName = $userObject.GivenName + " " + $userObject.SN
        $parameters = @{
            "Path" = "%distinguishedName%"
            "Name" = $displayName;
            "Server" = $domainName;
            "AdaxesService" = "localhost"
            "Enabled" = $True
            "OtherAttributes" = $userObject
            "ErrorAction" = "Stop"
        }
        
        if (!([System.String]::IsNullOrEmpty($accountPassword)))
        {
            $parameters.Add("AccountPassword", $accountPassword)
        }
        
        # Create a new user account.
        try
        {
            New-AdmUser @parameters
        }
        catch
        {
            $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
        continue
    }

    if ($userExists -is [System.Array])
    {
        $Context.LogMessage("Found more than one user with value '$valueForSearch' in property '$userIdProperty'", "Warning")
        continue
    }

    # If user exists, update account.
    $displayName = $userExists.Name
    try
    {
        Set-AdmUser -Identity $userExists.DistinguishedName -Replace $userObject `
            -AdaxesService localhost -Server $domainName -ErrorAction Stop
    }
    catch
    {
        $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
    }
    
    if ($propertiesToClear.Length -ne 0)
    {
        try
        {
            Set-AdmUser -Identity $userExists.DistinguishedName -Clear $propertiesToClear `
                -AdaxesService localhost -Server $domainName -ErrorAction Stop
        }
        catch
        {
            $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
    }
    
    if ([System.String]::IsNullOrEmpty($accountPassword))
    {
        continue
    }
    
    try
    {
        Set-AdmAccountPassword -Identity $userExists.DistinguishedName -NewPassword $accountPassword `
            -Reset -Server $domainName -AdaxesService localhost -ErrorAction Stop
    }
    catch
    {
        $Context.LogMessage("An error occurred when updating the password for user '$displayName'. Error: " + $_.Exception.Message, "Warning")
    }
}

Script 2: Only update existing users

The script only updates existing accounts updated based on the data in the CSV file. The script also sends an email notification containing users that were not found or if there were more than one user found with a specific identity.

Parameters

  • $csvFilePath - the path to the CSV file to import.
  • $userIdColumn - the header of the column that contains values of the property for identifying existing users.
  • $userIdProperty - the name of the property for identifying existing users (e.g. sAMAccountName, employeeID).
  • $accountPasswordColumn - the name of the column that contains account passwords.
  • $customColumnNames - Maps column headers with names of the corresponding user properties. If mapping is not specified for a column header, the header specified in the file will be used as the property name.
  • $ignoreUnspecifiedColumns - If set to $true, only the columns specified in the $customColumnNames variable will be imported. If set to $false, columns from the mapping will be imported accordingly, while for the rest the column headers will be considered property schema names.
  • $aDObjectProperties - the headers of the columns that contain references to other AD objects, such as, Manager, Secretary or Assistant. Objects can be referenced in the columns by their:
    • Distinguished Name
    • Full name (cn attribute)
    • Display name
  • $skipEmptyColumnNames - The properties corresponding to the specified headers will not be cleared by the script if the columns are empty.
  • $to - the email address of the notification recipient.
  • $subject - the email notification subject.
  • $reportHeader - the report header.
  • $reportFooter - the report header.
Import-Module Adaxes

$csvFilePath = "\\SERVER\share\ImportUsers.csv" # TODO: modify me
$userIdColumn = "EmployeeName" # TODO: modify me
$userIdProperty = "employeeId" # TODO: modify me
$accountPasswordColumn = "AccountPassword" # TODO: modify me
$customColumnNames = @{
    "JobTitle" = "title";
    "FirstName" = "givenName";
} # TODO: modify me
$ignoreUnspecifiedColumns = $True # TODO: modify me
$aDObjectProperties = @("Manager", "Secretary") # TODO: modify me
$skipEmptyColumnNames = @("MyColumn") # TODO: modify me

# Mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Import report" # TODO: modify me
$reportHeader = "<h2>Import report</h2>"
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

$domainName = $Context.GetObjectDomain("%distinguishedName%")
$importedUsers  = Import-Csv -Path $csvFilePath

$moreThanOneUserFound = New-Object "System.Text.StringBuilder"
$userNotFound = New-Object "System.Text.StringBuilder"
foreach ($userFromCSV in $importedUsers)
{
    $userObject = @{}
    $accountPassword = $NULL
    $propertiesToClear = @()
    foreach ($property in $userFromCSV.PSObject.Properties)
    {
        $columnName = $property.Name
        $value = $property.Value
        
        if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value)))
        {
            $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
            continue
        }
        elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value))
        {
            continue
        }
        
        if ($customColumnNames.ContainsKey($columnName))
        {
            $propertyName = $customColumnNames[$columnName]
        }
        elseif ($columnName -ieq $userIdColumn)
        {
            $propertyName = $userIdProperty
        }
        elseif ($ignoreUnspecifiedColumns)
        {
            continue
        }
        else
        {
            $propertyName = $columnName
        }
        
        if ([System.String]::IsNullOrEmpty($value))
        {
            if ($skipEmptyColumnNames -contains $columnName)
            {
                continue
            }
            
            $propertiesToClear += $propertyName
            continue
        }

        # Parse special columns.
        if ($aDObjectProperties -icontains $columnName)
        {
            $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
            
            if ($aDObject -is [System.Array])
            {
                $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                continue
            }

            if ($aDObject -eq $NULL)
            {
                $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                continue
            }
            
            $value = $aDObject.DistinguishedName
        }

        if ($value -ieq "True" -or $value -ieq "False")
        {
            $value = [System.Boolean]::Parse($value)
        }

        $userObject.Add($propertyName, $value)
    }
    
    # Check whether the user exists.
    $valueForSearch = $userObject.$userIdProperty
    $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" `
        -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
    if ($NULL -eq $userExists)
    {
        $userNotFound.Append("<li>$valueForSearch</li>")
        continue
    }

    if ($userExists -is [System.Array])
    {
        $moreThanOneUserFound.Append("<li>$valueForSearch</li>")
        continue
    }

    # If user exists, update account.
    $displayName = $userExists.Name
    try
    {
        Set-AdmUser -Identity $userExists.DistinguishedName -Replace $userObject `
            -AdaxesService localhost -Server $domainName -ErrorAction Stop
    }
    catch
    {
        $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
    }
    
    if ($propertiesToClear.Length -ne 0)
    {
        try
        {
            Set-AdmUser -Identity $userExists.DistinguishedName -Clear $propertiesToClear `
                -AdaxesService localhost -Server $domainName -ErrorAction Stop
        }
        catch
        {
            $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
    }
    
    if ([System.String]::IsNullOrEmpty($accountPassword))
    {
        continue
    }
    
    try
    {
        Set-AdmAccountPassword -Identity $userExists.DistinguishedName -NewPassword $accountPassword `
            -Reset -Server $domainName -AdaxesService localhost -ErrorAction Stop
    }
    catch
    {
        $Context.LogMessage("An error occurred when updating the password for user '$displayName'. Error: " + $_.Exception.Message, "Warning")
    }
}

if ($moreThanOneUserFound.Length -eq 0 -and $userNotFound.Length -eq 0)
{
    return
}

# Build report
$html = New-Object "System.Text.StringBuilder"
$html.Append($reportHeader)
if ($userNotFound.Length -ne 0)
{
    $html.Append("<b>The following users were not found in Active Directory:</b>")
    $html.Append("<ol>")
    $html.Append($userNotFound.ToString())
    $html.Append("</ol>")
}

if ($moreThanOneUserFound.Length -ne 0)
{
    $html.Append("<b>Found more than one user with the following value of the $userIdProperty property:</b>")
    $html.Append("<ol>")
    $html.Append($moreThanOneUserFound.ToString())
    $html.Append("</ol>")
}

# Send report
$Context.SendMail($to, $subject, $NULL, $html.ToString())

Script 3: Only create new users

The script only creates new accounts updated based on the data in the CSV file. Each user gets a randomly generated password. The script also sends an email notification containing users with a specific identity that already exist.

Parameters

  • $csvFilePath - the path to the CSV file to import.
  • $userIdColumn - the name of the column that contains values of the property for identifying existing users.
  • $userIdProperty - the name of the property for identifying existing users (e.g. sAMAccountName, employeeID).
  • $accountPasswordColumn - the name of the column that contains account passwords.
  • $customColumnNames - Maps column headers with names of the corresponding user account properties. If mapping is not specified for a column header, the header specified in the file will be used as the property name.
  • $aDObjectProperties - the headers of the columns that contain references to other AD objects, such as, Manager, Secretary or Assistant. Objects can be referenced in the columns by their:
    • Distinguished Name
    • Full name (cn attribute)
    • Display name
  • $ouDN - the distinguished name (DN) of the OU where new users will be created. For information on how to get the DN, see Get the DN of a directory object.
  • $to - Specifies the email notification recipient.
  • $subject - Specifies the email notification subject.
  • $reportHeader - Specifies the report header.
  • $reportFooter - Specifies the report header.
Import-Module Adaxes

$csvFilePath = "\\SERVER\share\ImportUsers.csv" # TODO: modify me
$userIdColumn = "EmployeeName" # TODO: modify me
$userIdProperty = "sAMAccountName" # TODO: modify me
$accountPasswordColumn = "AccountPassword" # TODO: modify me
$customColumnNames = @{
    "JobTitle" = "title";
    "FirstName" = "givenName";
} # TODO: modify me
$aDObjectProperties = @("Manager", "Secretary") # TODO: modify me
$ouDN = "CN=Users,DC=domain,DC=com" # TODO: modify me

# E-mail settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Import report" # TODO: modify me
$reportHeader = "<h2>Import report</h2>"
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me

$domainName = $Context.GetObjectDomain($ouDN)
$importedUsers  = Import-Csv -Path $csvFilePath

$rootDSE = $Context.BindToObject("Adaxes://RootDSE")
$userFound = New-Object "System.Text.StringBuilder"
foreach ($userFromCSV in $importedUsers)
{
    $userObject = @{}
    $accountPassword = $NULL
    
    foreach ($property in $userFromCSV.PSObject.Properties)
    {
        $columnName = $property.Name
        $value = $property.Value
        
        if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value)))
        {
            $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
            continue
        }
        elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value))
        {
            continue
        }
        
        if ($customColumnNames.ContainsKey($columnName))
        {
            $propertyName = $customColumnNames[$columnName]
        }
        else
        {
            $propertyName = $columnName
        }
        
        if ([System.String]::IsNullOrEmpty($value))
        {
            continue
        }

        # Parse special columns
        if ($columnName -ieq $userIdColumn)
        {
            $propertyName = $userIdProperty
        }
        elseif ($aDObjectProperties -icontains $columnName)
        {
            $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
            
            if ($aDObject -is [System.Array])
            {
                $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                continue
            }

            if ($aDObject -eq $NULL)
            {
                $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                continue
            }
            
            $value = $aDObject.DistinguishedName
        }

        if ($value -ieq "True" -or $value -ieq "False")
        {
            $value = [System.Boolean]::Parse($value)
        }

        $userObject.Add($propertyName, $value)
    }
    
    # Check whether the user exists
    $valueForSearch = $userObject.$userIdProperty
    $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" `
        -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
    if ($NULL -eq $userExists)
    {
        # Build user name
        $displayName = $userObject.GivenName + " " + $userObject.SN
        $parameters = @{
            "Path" = $ouDN
            "Name" = $displayName;
            "Server" = $domainName;
            "AdaxesService" = "localhost"
            "Enabled" = $True
            "OtherAttributes" = $userObject
            "ErrorAction" = "Stop"
        }
        
        if (!([System.String]::IsNullOrEmpty($accountPassword)))
        {
            $parameters.Add("AccountPassword", $accountPassword)
        }

        # Create a new user account
        try
        {
            New-AdmUser @parameters
        }
        catch
        {
            $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
    }
    else
    {
        $userFound.Append("<li>$valueForSearch</li>")
    }
}

if ($userFound.Length -eq 0)
{
    return
}

# Build report
$html = New-Object "System.Text.StringBuilder"
$html.Append($reportHeader)
$html.Append("<b>The following users were found in Active Directory:</b>")
$html.Append("<ol>")
$html.Append($userFound.ToString())
$html.Append("</ol>")
$html.Append($reportFooter)

$Context.SendMail($to, $subject, $NULL, $html.ToString())

Comments 43

You must be signed in to comment.

  • Christian Ehrenberg

    Christian Ehrenberg

    Can you please help me with the script.
    I built the task as described in https://www.adaxes.com/tutorials\_ActiveDirectoryManagement\_ScheduleImportOfUsersFromCSV.htm.
    And as an action the script is deposited.
    Unfortunately no user will import
    CSV file as described (with my data).

    sn,givenName,sAMAccountName,description,physicalDeliveryOfficeName,AccountPassword,manager  
    Robertson,William,wrobertson,Sales Manager at New York Office,New York,secret,Stephen Jones
    
    • Support

      Support

      Hello Christian,

      Could you, please, provide a screenshot of the Scheduled Task you created including the Activity Scope? You can send it to support@adaxes.com.

      Does the Scheduled Task produce any error messages when executing the script? If so, please, provide us with screenshots. You can check it by viewing the Activity History of the task:https://www.adaxes.com/help/?ManageScheduledTasks.ViewActivityHistory.html.

      If you made any modifications to the script, please, provide us with the updated script in TXT format.

  • Dario Inversi

    Dario Inversi

    Hi, I'm trying to get the script work in our environment but I get and error on line 88: "The search filter cannot be recognized. (Server: *****) Stack trace: at , : line 88".
    Could you please support me on this error.

    Thank you.

    Dario

    • Support

      Support

      Hello Dario.

      Could you, please, post here or send us (support[at]adaxes.com) the script you are using in TXT format including all your modifications?

      Also, provide us with a screenshot of the Scheduled Task that executes the script. Please, make sure that the screenshot includes the Activity Scope section.

    • Leo

      Leo

      I have the same problem - what was the solution?

      • Support

        Support

        Hello Leo,

        Unfortunately, we did not receive any information from Dario. For troubleshooting purposes, please, provide the same data as was requested above.

        • Leo

          Leo

          Import-Module Adaxes
          
          $csvFilePath = "\\Server\file\OriginalImport.csv" # TODO: modify me
          
          $Domain="@***.***"
          $EmpID="Employee_ID"
          $FirstName="First_Name"
          $LastName="Last_Name.ToLower()"
          $userIdColumn=$($FirstName + " " + $LastName)
          $sAMAccountName= ($LastName + $EmpID)
          $MgrID="Supervisor"
          $Manager=Get-ADUser -LDAPFilter "(EmployeeID=$MgrID)" -Properties distinguishedName
          $userPrincipalName=$sAMAccountName+$Domain
          
          $customColumnNames = @{
              "Company"= "company"
              "Employee_ID" = "employeeID";
              "Location" = "Office";
              "First_Name" = "GivenName";
              "Middle_Name" = "MI";
              "Last_Name" = "Surname"
              "Job_Title" = "title";
              "Role" = "Department";
              "userPrincipalName" = "userPrincipalName"
          } # TODO: modify me
          
          $aDObjectProperties = @("Manager = $Manager") # TODO: modify me
          $ouDN = "OU=Test Adaxes,DC=***,DC=***" # TODO: modify me
          
          # E-mail settings
          $to = "EMAIL Address" # TODO: modify me
          $subject = "Import report" # TODO: modify me
          $reportHeader = "<h2>Import report</h2>"
          $reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
          
          $domainName = $Context.GetObjectDomain($ouDN)
          $importedUsers = Import-Csv -Path $csvFilePath
          
          $rootDSE = $Context.BindToObject("Adaxes://RootDSE")
          $userFound = New-Object "System.Text.StringBuilder"
          foreach ($userFromCSV in $importedUsers)
          {
              $userObject = @{}
              $accountPassword = $NULL
              $propertiesToClear = @()
              foreach ($property in $userFromCSV.PSObject.Properties)
              {
                  $columnName = $property.Name
                  $value = $property.Value
          
                  if ($customColumnNames.ContainsKey($columnName))
                  {
                      $propertyName = $customColumnNames[$columnName]
                  }
                  else
                  {
                      $propertyName = $columnName
                  }
          
                  if ([System.String]::IsNullOrEmpty($value))
                  {
                      $propertiesToClear += $propertyName
                      continue
                  }
          
                  # Parse special columns
                  if ($columnName -ieq $userIdColumn)
                  {
                      $propertyName = $sAMAccountName
                  }
                  elseif ($aDObjectProperties -icontains $columnName)
                  {
                      $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)}`
                      -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
          
                      if ($aDObject -is [System.Array])
                      {
                          $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                          continue
                      }
          
                      if ($aDObject -eq $NULL)
                      {
                          $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                          continue
                      }
          
                      $value = $aDObject.DistinguishedName
                  }
          
                  if ($value -ieq "True" -or $value -ieq "False")
                  {
                      $value = [System.Boolean]::Parse($value)
                  }
          
                  $userObject.Add($propertyName, $value)
              }
          
              # Check whether the user exists
              $valueForSearch = $userObject.$sAMAccountName
              $userExists = Get-AdmUser -LdapFilter "($sAMAccountName=$valueForSearch)"`
              -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
          
              if ($NULL -eq $userExists)
              {
                  # Build user name
                  $displayName = $userObject.GivenName + " " + $userObject.SN
                  $parameters = @{
                      "Path" = $ouDN
                      "Name" = $displayName;
                      "Server" = $domainName;
                      "AdaxesService" = "localhost"
                      "Enabled" = $True
                      "OtherAttributes" = $userObject
                      "ErrorAction" = "Stop"
                  }
          
                  # Generate password
                  $userAdsPathObj = New-Object Softerra.Adaxes.Adsi.AdsPath "Adaxes://$ouDN"
                  $rdnValue = [Softerra.Adaxes.Ldap.Rdn]::EscapeAttributeValue($displayName)
                  $userAdsPathObj.CreateChildPath("CN=$rdnValue")
                  $passwordString = $rootDSE.GeneratePasswordForNewUser($userAdsPathObj)
                  $passwordSecureString = ConvertTo-SecureString -AsPlainText $passwordString -Force
                  $parameters.Add("AccountPassword", $passwordSecureString)
          
                  # Create a new user account
                  try
                  {
                      New-AdmUser @parameters
                  }
                  catch
                  {
                      $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
                  }
              }
              else
              {
                  $userFound.Append("<li>$valueForSearch</li>")
              }
          }
          
          if ($userFound.Length -eq 0)
          {
              return
          }
          
          # Build report
          $html = New-Object "System.Text.StringBuilder"
          $html.Append($reportHeader)
          $html.Append("<b>The following users were found in Active Directory:</b>")
          $html.Append("<ol>")
          $html.Append($userFound.ToString())
          $html.Append("</ol>")
          $html.Append($reportFooter)
          
          $Context.SendMail($to, $subject, $NULL, $html.ToString())
          
        • Leo

          Leo

          The search filter cannot be recognized. (Server: ***.***) Stack trace: at , : line 101

          • Support

            Support

            Hello Leo,

            Thank you for the provided details. The issue occurs because of the modifications you made in the script. For us to correct it, please, specify what exactly all your modifications are intended for and what the desired behavior is. Live examples will be very helpful.

            • Leo

              Leo

              I'm attempting to import a CSV using the script above to create new users.

              CSV Contains:

              Company, Employee_ID, Location, First_Name, Middle_Name, Last_Name, Job_title, Role,Supervisor
              2000, 12345, 20394, Lexie, M, Smith, Care Associate, RG-20000-Campus-Matrix, 137250

              Based on the csv:
              The sAMAAccountName should be the last name and employee ID

              $sAMAccountName= ($LastName + $EmpID)  
              

              Manager: Lookup based on the Supervisor field which is the Employee ID for the Manager

              $MgrID="Supervisor"  
              $Manager=Get-ADUser -LDAPFilter "(EmployeeID=$MgrID)" -Properties distinguishedName  
              

              Users Full Name should be the concatenated first and last name:

              $userIdColumn=$($FirstName + " " + $LastName)  
              

              All of the other fields are to go in as they are:

               "Company"= "company"  
               "Employee_ID" = "employeeID";  
               "Location" = "Office";  
               "First_Name" = "GivenName";  
               "Middle_Name" = "MI";  
               "Last_Name" = "Surname"  
               "Job_Title" = "title";  
               "Role" = "Department";  
              

              Email Settings:

              $to = Should Lookup the Managers email address for each imported user based on the result of the manager lookup.
              
              • Support

                Support

                Hello Leo,

                Thank you for specifying. For us to update the script according to your needs, please, specify what should be done if a manager with the specified employee ID is not found. Should the user be created with an empty Manager property? Should notifications about existing users be sent to a different email? Any additional details and live examples of the desired behavior will be much appreciated.

                • Leo

                  Leo

                  If manager does not exist - email should go to ServcieDesk@domain.com "user created no manager"

                  • Support

                    Support

                    Hello Leo,

                    What if not only the manager does not exist, but also the sAMAccountName is already taken? Should a corresponding email be sent to ServcieDesk@domain.com?

                    • Leo

                      Leo

                      Yes, If the user "sAMAccountName" already exists it should error out and send email to "ServiceDesk@domain.com.

                      • Support

                        Support

                        Hello Leo,

                        Thank you for the confirmation. Please, find the updated script below.

                        Import-Module Adaxes
                        
                        $csvFilePath = "\\SERVER\share\ImportUsers.csv" # TODO: modify me
                        $customColumnNames = @{
                            "JobTitle" = "title";
                            "FirstName" = "givenName";
                        } # TODO: modify me
                        $aDObjectProperties = @("Manager", "Secretary") # TODO: modify me
                        $ouDN = "CN=Users,DC=domain,DC=com" # TODO: modify me
                        
                        # E-mail settings
                        $to = "recipient@domain.com" # TODO: modify me
                        $subject = "Import report" # TODO: modify me
                        $reportHeader = "<h2>Import report</h2>"
                        $reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
                        
                        $domainName = $Context.GetObjectDomain($ouDN)
                        $importedUsers  = Import-Csv -Path $csvFilePath
                        
                        $rootDSE = $Context.BindToObject("Adaxes://RootDSE")
                        $managerEmailsToUsersFound = @{}
                        foreach ($userFromCSV in $importedUsers)
                        {
                            $userObject = @{}
                            $accountPassword = $NULL
                            $propertiesToClear = @()
                            $managerMail = $NULL
                            foreach ($property in $userFromCSV.PSObject.Properties)
                            {
                                $columnName = $property.Name
                                $value = $property.Value
                                
                                if ($customColumnNames.ContainsKey($columnName))
                                {
                                    $propertyName = $customColumnNames[$columnName]
                                }
                                else
                                {
                                    $propertyName = $columnName
                                }
                                
                                if ([System.String]::IsNullOrEmpty($value))
                                {
                                    $propertiesToClear += $propertyName
                                    continue
                                }
                        
                                # Parse special columns
                                if ($aDObjectProperties -icontains $columnName)
                                {
                                    if ($propertyName -eq "manager")
                                    {
                                        $aDObject = Get-AdmObject -Filter {EmployeeID -eq $value} `
                                            -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName -Properties mail
                                    }
                                    else
                                    {
                                        $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                                            -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
                                    }
                                    
                                    if ($NULL -eq $aDObject)
                                    {
                                        $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                                        continue
                                    }
                                     
                                    if ($aDObject -is [System.Array])
                                    {
                                        $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                                        continue
                                    }
                                    
                                    $value = $aDObject.DistinguishedName
                                    if ($propertyName -eq "manager")
                                    {
                                        $managerMail = $aDObject.Mail
                                    }
                                }
                        
                                if ($value -ieq "True" -or $value -ieq "False")
                                {
                                    $value = [System.Boolean]::Parse($value)
                                }
                        
                                $userObject.Add($propertyName, $value)
                            }
                            
                            if ($NULL -eq $managerMail)
                            {
                                $managerMail = $to
                            }
                            
                            if (!$managerEmailsToUsersFound.ContainsKey($managerMail))
                            {
                                $managerEmailsToUsersFound.Add($managerMail, (New-Object "System.Text.StringBuilder"))
                            }
                            
                            
                            # Build sAMAccountName
                            $sAMAccountName = $userObject.sn + $userObject.employeeID
                            
                            # Check whether the user exists
                            $userExists = Get-AdmUser -LdapFilter "(sAMAccountName=$sAMAccountName)" `
                                -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
                            
                            if ($NULL -eq $userExists)
                            {
                                # Build user name
                                $displayName = $userObject.GivenName + " " + $userObject.SN
                                $parameters = @{
                                    "Path" = $ouDN
                                    "Name" = $displayName;
                                    "SamAccountName" = $sAMAccountName
                                    "Server" = $domainName;
                                    "AdaxesService" = "localhost"
                                    "Enabled" = $True
                                    "OtherAttributes" = $userObject
                                    "ErrorAction" = "Stop"
                                }
                                
                                # Generate password
                                $userAdsPathObj = New-Object Softerra.Adaxes.Adsi.AdsPath "Adaxes://$ouDN"
                                $rdnValue = [Softerra.Adaxes.Ldap.Rdn]::EscapeAttributeValue($displayName)
                                $userAdsPathObj.CreateChildPath("CN=$rdnValue")
                                $passwordString = $rootDSE.GeneratePasswordForNewUser($userAdsPathObj)
                                $passwordSecureString = ConvertTo-SecureString -AsPlainText $passwordString -Force
                                $parameters.Add("AccountPassword", $passwordSecureString)
                        
                                # Create a new user account
                                try
                                {
                                    New-AdmUser @parameters 
                                }
                                catch
                                {
                                    $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
                                }
                            }
                            else
                            {
                                $managerEmailsToUsersFound[$managerMail].Append("<li>$sAMAccountName</li>")
                            }
                        }
                        
                        foreach ($mail in $managerEmailsToUsersFound.Keys)
                        {
                            if ($managerEmailsToUsersFound[$mail].Length -eq 0)
                            {
                                continue
                            }
                            
                            # Build report
                            $html = New-Object "System.Text.StringBuilder"
                            $html.Append($reportHeader)
                            $html.Append("<b>The following users were found in Active Directory:</b>")
                            $html.Append("<ol>")
                            $html.Append($managerEmailsToUsersFound[$mail].ToString())
                            $html.Append("</ol>")
                            $html.Append($reportFooter)
                            
                            $Context.SendMail($mail, $subject, $NULL, $html.ToString())
                        }
                        
                        
                        • Leo

                          Leo

                          Thanks for the updated script!

                          I modified what you sent as follows:
                          Changed the Path to the CSV, Changed the $to and added the following:

                          $customColumnNames = @{  
                           "Company"= "company"  
                           "Employee_ID" = "employeeID";  
                           "Location" = "Office";  
                           "First_Name" = "GivenName";  
                           "Middle_Name" = "middleName";  
                           "Last_Name" = "sn"  
                           "Job_Title" = "title";  
                           "Role" = "Department";  
                           "Supervisor" = "$mgrid";  
                            
                          $aDObjectProperties = @("Manager = Supervisor", "Secretary")  
                          $ouDN = info was changed.   
                          

                          CSV Content
                          Company,Employee_ID,Location,First_Name,Middle_Name,Last_Name,Job_Title,Role,Supervisor
                          20000,128,20127,Lexie,r,Test,Test Associate,rg-20000-Campus-CaretrckrMatrix,135743
                          20000,133,20423,Madeline,C,Test,Resident Test Associate,rg-20000-Campus-RCACaretrackerAL,135743
                          20000,136,20415,Irene,M,Test,Test Services Asst,rg-20000-Campus-SmartlinxOnly,135743

                          When the script is run the log says completed. The users are NOT created and the execution log says:
                          "An error occurred when creating user 'Irene Test'. Error: Parameter must be a non empty string. Parameter name: name"

                          • Support

                            Support

                            Hello Leo,

                            We opened a support ticket to help you with the script. An email was sent to the address of your account.

  • Jay

    Jay

    Will this script only update the fields that are needed? Ideally we want to move to importing the Master Employee Record in to Adaxes and simply update only the attributes that changed. We have over 15k employees and in the past the scripts have run too long and not finished.

    • Support

      Support

      Hello Jay,

      The current version of the script not only updates the users, but also creates new ones. Also, it attempts to update all the properties present in the CSV file. However, the script can be updated to work exactly as you need. Still on 15k users it can take quite long.

      • Jay

        Jay

        Is this the best solution to keep the users updated? If not, what do you suggest?

        • Support

          Support

          Hello Jay,

          It totally depends on your requirements. If you have a CSV file with user data that is frequently updated, using such a script should work just fine to keep your user data up to date in Active Directory.

          • Jay

            Jay

            So this script as is just needs the headings of the columns to be the same as the attribute name or map them in the script. Correct? Also we will need a check added to only update the accounts where information changed.

            • Support

              Support

              Hello Jay,

              >So this script as is just needs the headings of the columns to be the same as the attribute name or map them in the script. Correct?

              Yes, that is correct.

              >Also we will need a check added to only update the accounts where information changed.

              There is no need to add the check. Adaxes does not update properties to the same values. If all the properties are the same (nothing has changed), no updates will be performed.

  • Leo

    Leo

    Hello, I'm working with Script 2: Only update existing users. Here are the changes i have made:

    $csvFilePath = "\\ServerName\Scripts\Output\testVcpiExport.csv" # TODO: modify me  
    $userIdColumn = "Name" # TODO: modify me  
    $userIdProperty = "employeeID" # TODO: modify me  
    $accountPasswordColumn = "AccountPassword" # TODO: modify me  
    $customColumnNames = @{  
     "JobTitle" = "title";  
     "FirstName" = "givenName";  
     "SamAccountName" = "SamAccountName";  
     "Departmentnumber" = "Departmentnumber";  
     "enabled" = "enabled";  
     "department" = "department";  
     "description" = "description";  
     "office" = "office";  
     "emailaddress" = "emailaddress";  
     "extensionAttribute2" = "extensionAttribute2";  
    

    CSV with one record:

    Name,SamAccountName,Departmentnumber,enabled,empid,department,description,title,office,emailaddress,extensionAttribute2,whenChanged  
    "Test, user",tuser1,322507,FALSE,96587,North Michigan,"#322507, Office, test job,Cook,322507,,Jobtestcode,5/31/2021 20:31
    

    I receive the following error:
    Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'employeeId' Key being added: 'employeeid'" Stack trace: at , : line 97

  • Leo

    Leo

    Hello, I am working with Script 2: Only update existing users

    Here are the changes i have made:

    $csvFilePath = "\\\\server\\Scripts\\Output\\testImport.csv" # TODO: modify me  
    $userIdColumn = "Name" # TODO: modify me  
    $userIdProperty = "employeeID" # TODO: modify me  
    $accountPasswordColumn = "AccountPassword" # TODO: modify me  
    $customColumnNames = @{  
     "title" = "title";  
     "SamAccountName" = "SamAccountName";  
     "Departmentnumber" = "Departmentnumber";  
     "enabled" = "enabled";  
     "department" = "department";  
     "description" = "description";  
     "office" = "office";  
     "emailaddress" = "emailaddress";  
     "extensionAttribute2" = "extensionAttribute2";  
    

    Import file content:

    Name,SamAccountName,Departmentnumber,enabled,empid,department,description,title,office,emailaddress,extensionAttribute2,whenChanged  
    "user","test",test1,322507,FALSE,99613,Michigan,TestAccountuser,Cook,322507,,TestRoleOnly,5/31/2021 20:31  
    

    Error:
    Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'employeeid' Key being added: 'employeeID'" Stack trace: at , : line 97

  • Leo

    Leo

    Hello, working with Script 2 - I was able to get the script to run without errors. But, none of my changes are getting there:

    ScriptModifications:

    
    $csvFilePath = "\\server\testImport.csv" # TODO: modify me
    $userIdColumn = "cn" # TODO: modify me
    $userIdProperty = "employeeid" # TODO: modify me
    $accountPasswordColumn = "AccountPassword" # TODO: modify me
    $customColumnNames = @{
      "title"               = "title";
      "Departmentnumber"    = "departmentNumber";
      "department"          = "department";
      "description"         = "description";
      "office"              = "physicalDeliveryOfficeName";
      "emailaddress"        = "mail";
      "extensionAttribute2" = "extensionAttribute2";
     
    

    Test file:

    cn,SamAccountName,Departmentnumber,enabled,empid,department,description,title,office,emailaddress,extensionAttribute2,AccountPassword,whenChanged
    Joe Test,jtest,322507,TRUE,987654321,North Michigan,OfficeLocation,Cook,322507,,TestRole,,5/31/2021 20:31
    
    • Support

      Support

      Hello Leo,

      To get notifications on the import attempts performed via the script, you can specify your email address in the $to variable.

      Most probably, the changes are not performed because the Joe Test user account was not found in your domain. The thing is that the value for user search is obtained from the column whose name is specified in the $userIdColumn variable. In your case, it is the cn column which contains full name but not an employee ID whose attribute name is specified to perform the search by (the value of the $userIdProperty variable). At the same time, the empid column name does not match any attribute LDAP name and is not listed in the $customClumnNames variable. That will cause an error during the script execution. If the empid column contains the employee IDs the user search should be performed by, you can change the $userIdColumn variable value to empid to remedy the issue.

      Also, the whenChanged attribute specified in your CSV file is System Only. It means the attribute can be set/updated only by Active Directory and attempts to update manually (e.g. via the script) will cause errors. Thus, you should remove the attribute column from the file.

      For your information, as the title, Departmentnumber, department, description, and extensionAttribute2 column name match the names of the corresponding attributes, there is no need to list them in the $customColumnNames variable. In case of the file you are importing, the variable can be like the following:

      $customColumnNames = @{
          "office" = "physicalDeliveryOfficeName";
          "emailaddress" = "mail";
      }
      
      • Leo

        Leo

        Got it working. Thank you!

  • Lasan

    Lasan

    Hallo Everyone

    I'm working with Script 2 - I what to update the attribute employeeNumber. I made a list with one line, but I get the Error the User not found.

    $csvFilePath = "\\Server\csv\Update_User.csv" # TODO: modify me  
    $userIdColumn = "sAMAccountName" # TODO: modify me  
    $userIdProperty = "employeeNumber" # TODO: modify me  
    $accountPasswordColumn = "AccountPassword" # TODO: modify me  
    $customColumnNames = @{  
     "sAMAccountName" = "sAMAccountName";  
     "employeeNumber" = "employeeNumber";  
     
    } # TODO: modify me  
    $aDObjectProperties = @("employeeNumber") # TODO: modify me  
    
    sAMAccountName,employeeNumber,  
    Peter.Muster,AB52
    
  • Support

    Support

    Hello,

    The thing is that you specifies the column and the property for identifying user account incorrectly. The sAMAccountName column contains the value of the sAMAccountName property, not that of the employeeNumber property. Also, as the employeeNumber is not of DN syntax and you have no such properties in the CSV file, the $aDObjectProperties should be set to an empty array. Finally, your script should be exactly as below.

    Import-Module Adaxes
    
    $csvFilePath = "\\Server\Update_User.csv" # TODO: modify me
    $userIdColumn = "sAMAccountName" # TODO: modify me
    $userIdProperty = "sAMAccountName" # TODO: modify me
    $accountPasswordColumn = "AccountPassword" # TODO: modify me
    $customColumnNames = @{
        "sAMAccountName" = "sAMAccountName";
        "employeeNumber" = "employeeNumber";
    } # TODO: modify me
    
    $aDObjectProperties = @() # TODO: modify me
    
    # E-mail settings
    $to = "recipient@domain.com" # TODO: modify me
    $subject = "Import report" # TODO: modify me
    $reportHeader = "<h2>Import report</h2>"
    $reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
    
    $domainName = $Context.GetObjectDomain("%distinguishedName%")
    $importedUsers  = Import-Csv -Path $csvFilePath
    
    $moreThanOneUserFound = New-Object "System.Text.StringBuilder"
    $userNotFound = New-Object "System.Text.StringBuilder"
    foreach ($userFromCSV in $importedUsers)
    {
        $userObject = @{}
        $accountPassword = $NULL
        $propertiesToClear = @()
        foreach ($property in $userFromCSV.PSObject.Properties)
        {
            $columnName = $property.Name
            $value = $property.Value
    
            if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value)))
            {
                $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
                continue
            }
            elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value))
            {
                continue
            }
    
            if ($customColumnNames.ContainsKey($columnName))
            {
                $propertyName = $customColumnNames[$columnName]
            }
            else
            {
                $propertyName = $columnName
            }
    
            if ([System.String]::IsNullOrEmpty($value))
            {
                $propertiesToClear += $propertyName
                continue
            }
    
            # Parse special columns
            if ($columnName -ieq $userIdColumn)
            {
                $propertyName = $userIdProperty
            }
            elseif ($aDObjectProperties -icontains $columnName)
            {
                $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                    -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
                if ($aDObject -is [System.Array])
                {
                    $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                    continue
                }
    
                if ($aDObject -eq $NULL)
                {
                    $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
                    continue
                }
    
                $value = $aDObject.DistinguishedName
            }
    
            if ($value -ieq "True" -or $value -ieq "False")
            {
                $value = [System.Boolean]::Parse($value)
            }
    
            $userObject.Add($propertyName, $value)
        }
    
        # Check whether the user exists
        $valueForSearch = $userObject.$userIdProperty
        $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" `
            -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
        if ($NULL -eq $userExists)
        {
            $userNotFound.Append("<li>$valueForSearch</li>")
            continue
        }
    
        if ($userExists -is [System.Array])
        {
            $moreThanOneUserFound.Append("<li>$valueForSearch</li>")
            continue
        }
    
        # If user exists, update account
        $displayName = $userExists.Name
        try
        {
            Set-AdmUser -Identity $userExists.DistinguishedName -Replace $userObject `
                -AdaxesService localhost -Server $domainName -ErrorAction Stop
        }
        catch
        {
            $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
    
        if ($propertiesToClear.Length -ne 0)
        {
            try
            {
                Set-AdmUser -Identity $userExists.DistinguishedName -Clear $propertiesToClear `
                    -AdaxesService localhost -Server $domainName -ErrorAction Stop
            }
            catch
            {
                $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
            }
        }
    
        if ([System.String]::IsNullOrEmpty($accountPassword))
        {
            continue
        }
    
        try
        {
            Set-AdmAccountPassword -Identity $userExists.DistinguishedName -NewPassword $accountPassword `
                -Reset -Server $domainName -AdaxesService localhost -ErrorAction Stop
        }
        catch
        {
            $Context.LogMessage("An error occurred when updating the password for user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
    }
    
    if ($moreThanOneUserFound.Length -eq 0 -and $userNotFound.Length -eq 0)
    {
        return
    }
    
    # Build report
    $html = New-Object "System.Text.StringBuilder"
    $html.Append($reportHeader)
    if ($userNotFound.Length -ne 0)
    {
        $html.Append("<b>The following users were not found in Active Directory:</b>")
        $html.Append("<ol>")
        $html.Append($userNotFound.ToString())
        $html.Append("</ol>")
    }
    
    if ($moreThanOneUserFound.Length -ne 0)
    {
        $html.Append("<b>Found more than one user with the following value of the $userIdProperty property:</b>")
        $html.Append("<ol>")
        $html.Append($moreThanOneUserFound.ToString())
        $html.Append("</ol>")
    }
    
    # Send report
    $Context.SendMail($to, $subject, $NULL, $html.ToString())
    
  • Waqas Ahmed

    Waqas Ahmed

    I want to create bulk users by importing CSV file from web console . The user give file path as a parameter. Is it possible ? Can some one please guide me, how to do it ? may be through custom command with csv path as a parameter ?

    • Support

      Support

      Hello Ahmed,

      Yes, it is possible using a custom command and a parameter. In this case, the corresponding line in the script will look as below, where param-filePath is the name of the parameter used to specify the path to the CSV file.

      $csvFilePath = "%param-filePath%" # TODO: modify me
      

      The parameter can be of Edit box type and users will have to manually enter the path. Unfortunately, there is no parameter that would allow you to browse the file system to select a file. However, thank you for the suggestion. We forwarded it to the corresponding department for consideration.

  • Josh Healey

    Josh Healey

    Hey guys, I had this script running just fine a month ago, but now I cannot seem to figure out why ALL users cannot be found using their employeeName attribute. Attached is my script. It was working without any changes and suddenly I cannot get it to find all the users to update. I could really use the help.

    ####Current CSV headers: Employee_Code,Department_Desc,Position 
    
    Import-Module Adaxes 
    
    $csvFilePath = "\\server\Imports\document.csv" # Specifies a path to the CSV file that will be imported.
    $userIdColumn = "Employee_Code" # Specifies the name of the column that contains the property for identifying existing users. 
    $userIdProperty = "employeeNumber" # Specifies the LDAP name of the property for identifying existing users (e.g. sAMAccountName, employeeID). 
    #$accountPasswordColumn = "AccountPassword" # Specifies the name of the column that contains account passwords. 
    $customColumnNames = @{ "Position" = "title"; "Department_Desc" = "department"; "Employee_Code" = "employeeNumber"; } # Maps column headers with LDAP names of the corresponding user account properties. If mapping is not specified for a column header, the header specified in the file will be used as the property LDAP name; 
    $aDObjectProperties = @() # Specifies the list of headers of the columns that contain references to other AD objects, such as, Manager, Secretary or Assistant. Objects can be referenced in the columns by their: Distinguished Name, Full name (cn attribute), or Display name. 
    
    # E-mail settings
    $to = "adminExample" # Specifies the email notification recipient.
    $subject = "Paycom import report" # Specifies the email notification subject.
    $reportHeader = "<h2>Paycom Import Report</h2>" # Specifies the report header. 
    $reportFooter = "<hr /><p><em>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</em></p>" # Specifies the report header. 
    $domainName = $Context.GetObjectDomain("%distinguishedName%") 
    $importedUsers = Import-Csv -Path $csvFilePath $moreThanOneUserFound = New-Object "System.Text.StringBuilder" 
    $userNotFound = New-Object "System.Text.StringBuilder"
    
    foreach ($userFromCSV in $importedUsers) { 
      $userObject = @{} 
      $accountPassword = $NULL 
      $propertiesToClear = @()
      foreach ($property in $userFromCSV.PSObject.Properties) {
        $columnName = $property.Name 
        $value = $property.Value 
        if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value))) {
          $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force continue 
        } 
        elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value)) {
          continue 
        } 
        if ($customColumnNames.ContainsKey($columnName)) {
          $propertyName = $customColumnNames[$columnName] 
        }
        else {
          $propertyName = $columnName 
        } 
        if ([System.String]::IsNullOrEmpty($value)) {
          $propertiesToClear += $propertyName 
          continue 
        } 
    
        # Parse special columns 
        if ($columnName -ieq $userIdColumn) {
          $propertyName = $userIdProperty 
        } 
        elseif ($aDObjectProperties -icontains $columnName) {
          $aDObject = Get-AdmObject -Filter { (Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value) } ` -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName 
          if ($aDObject -is [System.Array]) { 
            $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
            continue 
          } 
          if ($aDObject -eq $NULL) {
            $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
            continue 
          } 
          $value = $aDObject.DistinguishedName 
        } 
        if ($value -ieq "True" -or $value -ieq "False") {
          $value = [System.Boolean]::Parse($value) 
        } 
        $userObject.Add($propertyName, $value) 
      } 
        
      # Check whether the user exists 
      $valueForSearch = $userObject.$userIdProperty 
      $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" ` 
      -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName 
      if ($NULL -eq $userExists) { 
        $userNotFound.Append("$valueForSearch")
        continue 
      } 
      if ($userExists -is [System.Array]) { 
        $moreThanOneUserFound.Append("$valueForSearch")
        continue 
      } 
      # If user exists, update account 
      $displayName = $userExists.Name
      try {
        Set-AdmUser -Identity $userExists.DistinguishedName -Replace $userObject ` 
        -AdaxesService localhost -Server $domainName -ErrorAction Stop 
      }
      catch {
        $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
      }
      if ($propertiesToClear.Length -ne 0) {
        try {
          Set-AdmUser -Identity $userExists.DistinguishedName -Clear $propertiesToClear `
            -AdaxesService localhost -Server $domainName -ErrorAction Stop 
        }
        catch {
          $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning") 
        } 
      } 
      if ([System.String]::IsNullOrEmpty($accountPassword)) {
        continue 
      } 
      try { 
        Set-AdmAccountPassword -Identity $userExists.DistinguishedName -NewPassword $accountPassword ` 
        -Reset -Server $domainName -AdaxesService localhost -ErrorAction Stop 
      }
      catch {
        $Context.LogMessage("An error occurred when updating the password for user '$displayName'. Error: " + $_.Exception.Message, "Warning") 
      }
    } 
    if ($moreThanOneUserFound.Length -eq 0 -and $userNotFound.Length -eq 0) {
      return 
    } 
    
    # Build report 
    $html = New-Object "System.Text.StringBuilder" 
    $html.Append($reportHeader) 
    if ($userNotFound.Length -ne 0) {
      $html.Append("<strong>The following users were not found in Active Directory:</strong>")
      $html.Append("<ol>") 
      $html.Append($userNotFound.ToString()) 
      $html.Append("</ol>") 
    } 
    if ($moreThanOneUserFound.Length -ne 0) {
      $html.Append("<strong>Found more than one user with the following value of the $userIdProperty property:</strong>")
      $html.Append("<ol>")
      $html.Append($moreThanOneUserFound.ToString()) 
      $html.Append("</ol>") 
    } 
    
    # Send report 
    $Context.SendMail($to, $subject, $NULL, $html.ToString())
    
    • Support

      Support

      Hello Josh,

      What exactly do you mean by cannot get it to find all the users to update? Does the script update some users but not all? Do you face any errors? If so, please, send us (support@adaxes.com) screenshots. Also, please, send us a sample CSV file you are using. Any additional details will be much appreciated.

  • Cory Fiala

    Cory Fiala

    For the "Create new and update existing users" script since the scope is the managed domain, how can I specify what OU to put newly created users in?

    • Support

      Support

      Hello Cory,

      To achieve the desired behavior, you can create scheduled task configured for the Organizational Unit object type and specify only the required OU in the Activity Scope. Make sure to select the The Organizational Unit object checkbox only.

  • George Holden

    George Holden

    Hi
    I updated the Script to Create User only, and when I ran the Script, it generated the following error:
    The term ' Import-Module' 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. Stack trace: at , : line 1
    I did not modify the Import-Module Line, and I have other Scripts running with this same Import Module call that does not error out.

    • Support

      Support

      Hello George,

      Most probably, there is some unprintable character in the line. You can try to just remove it from the script. Starting with PowerShell 3.0 required modules are imported automatically.

  • Thomas

    Thomas

    Hello!
    I was getting the Script 2: Only update existing users to work. Thank you for that.
    Can you help me on how can I use it to only update one user and not a bulk? This is for when I create a new user, and the "sAMAccountName" match a entry from the csv file it will update the attributes.

    /Thomas

    • Support

      Support

      Hello Thomas,

      There is no easy way to just update this script to meet your needs. The thing is that you need a totally reverse logic and thus the script will be totally different.

      • Thomas

        Thomas

        Thank for the reply.
        I was able to find a workaround for the problem, I just added some lines. So instead of running the loop on all users in the csv file I only got it to run on my current user.
        So, what i did was make some new variable:

        $CurrentUser = "%username%"
        $folder = "E:\csvfilefromHR" # Location of file
        $csvfile = "CSVfilename" #Name of file
        
        $csvfiles = Get-ChildItem -Path $folder -File | Where-Object { $_.Extension -like ".csv" -and $_.Name -like "$csvfile*" } | Sort-Object -Property LastWriteTime -Descending | select -First 1 | select fullname # Selecting the newest CSV file
        
        $importedUsersNofilter = Import-Csv -path $csvfiles.FullName -Encoding UTF8 # Import the whole CSV file.
        
        importedUsers = $importedUsersNofilter | Where-Object { $_.user_name -eq $CurrentUser } # Import only the line with current user.
        

        Then I use the rest of the script to update the users.
        Hope this can help other also.
        /Thomas

  • Andrew

    Andrew

    Hello! I'm looking to send out an email with the results of the import for each line in the CSV whether it was successful or if there was an error and what the error was. Here is the script we are working with at the moment:

    Import-Module Adaxes
    
    $csvFilePath = " " # TODO: modify me
    $userIdColumn = "EmployeeID" # TODO: modify me
    $userIdProperty = "EmployeeID" # TODO: modify me
    $accountPasswordColumn = "AccountPassword" # TODO: modify me
    $customColumnNames = @{
      "msds-cloudextensionattribute1" = "msds-cloudextensionattribute1";
      "extensionattribute1"           = "extensionattribute1";
      "extensionattribute5"           = "extensionattribute5";
      "extensionattribute12"          = "extensionattribute12";
      "extensionattribute15"          = "extensionattribute15";
    
    } # TODO: modify me
    $aDObjectProperties = @() # TODO: modify me
    
    # E-mail settings
    #$to = " " # TODO: modify me
    #$subject = "Import report" # TODO: modify me
    #$reportHeader = "<h2>Import report</h2>"
    #$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
    
    $domainName = $Context.GetObjectDomain("%distinguishedName%")
    $importedUsers = Import-Csv -Path $csvFilePath
    
    foreach ($userFromCSV in $importedUsers) {
      $userObject = @{}
      $accountPassword = $NULL
      $propertiesToClear = @()
      foreach ($property in $userFromCSV.PSObject.Properties) {
        $columnName = $property.Name
        $value = $property.Value
        $userFromCSV.Enabled = [System.Boolean]::Parse($userFromCSV.Enabled)
    
        if ($columnName -ieq $accountPasswordColumn -and !([System.String]::IsNullOrEmpty($value))) {
          $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
          continue
        }
        elseif ($columnName -ieq $accountPasswordColumn -and [System.String]::IsNullOrEmpty($value)) {
          continue
        }
    
        #if ($customColumnNames.ContainsKey($columnName))
        #{
        # $propertyName = $customColumnNames[$columnName]
        #}
        else {
          $propertyName = $columnName
        }
    
        if ([System.String]::IsNullOrEmpty($value)) {
          $propertiesToClear += $propertyName
          continue
        }
    
        # Parse special columns
        if ($columnName -ieq $userIdColumn) {
          $propertyName = $userIdProperty
        }
        elseif ($aDObjectProperties -icontains $columnName) {
          $aDObject = Get-AdmObject -Filter { (Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value) } `
            -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
          if ($aDObject -is [System.Array]) {
            $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
            continue
          }
    
          if ($aDObject -eq $NULL) {
            $Context.LogMessage("Could not locate object with identity '$value'.", "Warning")
            continue
          }
    
          $value = $aDObject.DistinguishedName
        }
    
        if ($value -ieq "True" -or $value -ieq "False") {
          $value = [System.Boolean]::Parse($value)
        }
    
        $userObject.Add($propertyName, $value)
      }
    
      # Check whether the user exists
      $valueForSearch = $userObject.$userIdProperty
      $userExists = Get-AdmUser -LdapFilter "($userIdProperty=$valueForSearch)" `
        -AdaxesService localhost -ErrorAction SilentlyContinue -Server $domainName
    
      if ($userExists -eq $NULL) {
        # Build user name
        $displayName = $userObject.GivenName + " " + $userObject.SN
        $parameters = @{
          "Path"            = "%distinguishedName%"
          "Name"            = $displayName;
          "Server"          = $domainName;
          "AdaxesService"   = "localhost"
          "Enabled"         = $True
          "OtherAttributes" = $userObject
          "ErrorAction"     = "Stop"
        }
    
        if (!([System.String]::IsNullOrEmpty($accountPassword))) {
          $parameters.Add("AccountPassword", $accountPassword)
        }
    
        # Create a new user account
        try {
          New-AdmUser @parameters
        }
        catch {
          $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
        continue
      }
    
      if ($userExists -is [System.Array]) {
        $Context.LogMessage("Found more than one user with value '$valueForSearch' in property '$userIdProperty'", "Warning")
        continue
      }
    
      # If user exists, update account
      $displayName = $userExists.Name
      try {
        Set-AdmUser -Identity $userExists.DistinguishedName -Replace $userObject `
          -AdaxesService localhost -Server $domainName -ErrorAction Stop
      }
      catch {
        $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
      }
    
      if ($propertiesToClear.Length -ne 0) {
        try {
          Set-AdmUser -Identity $userExists.DistinguishedName -Clear $propertiesToClear `
            -AdaxesService localhost -Server $domainName -ErrorAction Stop
        }
        catch {
          $Context.LogMessage("An error occurred when updating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
        }
      }
    
      if ([System.String]::IsNullOrEmpty($accountPassword)) {
        continue
      }
    
      try {
        Set-AdmAccountPassword -Identity $userExists.DistinguishedName -NewPassword $accountPassword `
          -Reset -Server $domainName -AdaxesService localhost -ErrorAction Stop
      }
      catch {
        $Context.LogMessage("An error occurred when updating the password for user '$displayName'. Error: " + $_.Exception.Message, "Warning")
      }
    }
    
    • Support

      Support

      Hello Andrew,

      You are using a custom script (not one from this article) and thus it is hard for us to be specific. However, the general approach is to use try-catch blocks forming the corresponding lists in each of the blocks and then emailing them. You can check the approaches used in the above Script 2: Only update existing users and Script 3: Only create new users scripts.

Got questions?

Support Questions & Answers

We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.