Script Repository


Import user information from fixed formatted text file

February 08, 2017
1661

The script updates user accounts in Active Directory based on information in a fixed formatted text file. Operation performed on a user account depends on the value of the 1st column in the file:

  1. User account is created
  2. User account is updated
  3. User account is disabled and moved to an Organizational Unit for disabled accounts.

Users are identified in Active Directory by their Employee ID.

To schedule import of user information, create a Scheduled Task configured for the Domain-DNS object type that runs the script.

Parameters:

  • $filePath - specifies the full path to a fixed formatted text file to import;
  • $disabledAccountsOUDN - specifies the Distinguished Name (DN) of an Organizational Unit that disabled user accounts are moved to;
  • $ouDN - specifies the Distinguished Name (DN) of an Organizational Unit where new user accounts are created;
  • $userPassword - specifies a password for all new users;
  • $nameTemplate - specifies a template for the name (cn attribute) of new users;
  • $sAMAccountNameTemplate - specifies a template for the name (sAMAccountName attribute) of new users;
  • $columnWidths - specifies the widths (in characters) of all the columns in the file starting from the left one;
  • $columnInfos - specifies a map of column numbers to names of Active Directory attributes that the columns contain. The 1st column is reserved to specify an action that will be performed on user accounts, so you can specify any name you like for that column.
Note: The script uses cmdlets from Adaxes PowerShell module for Active Directory. To run the script, you need to install the PowerShell Module for Active Directory component of Adaxes.
Edit Remove
PowerShell
Import-Module Adaxes

$filePath = "\\server\share\HR-Export.txt" # TODO: modify me
$disabledAccountsOUDN = "OU=DisabledAccounts,DC=domain,DC=com" # TODO: modify me

# New employee settings
$ouDN = "OU=NewAccounts,DC=domain,DC=com" # TODO: modify me
$userPassword = "secret" # TODO: modify me
$nameTemplate = @("givenName", "sn") # TODO: modify me
$sAMAccountNameTemplate = @("givenName", 1), @("sn", 0) # TODO: modify me
# Example $sAMAccountNameTemplate = @(<propertyLdapName>, <value length>), @(<propertyLdapName>, <value length>)
# if <value length> = 0, use all characters

# Column settings
$columnWidths = 1,2,20,4,4,4,10,10,15,20,15,20,6,2,20,15,16,9,6,60,60,16,2,5,5,3,3,75,75,28,2,10,10,75,75,28,2,10,60,60,60,30,30,120 # TODO: modify me
$columnInfos = @{
    1="Operation Type";
    3="terminationDate";
    4="positionDepartmentCode";
    5="positionUnitCode";
    6="positionDivisionCode";
    7="EmployeeID";
    8="positionSupervisorUID";
    9="GivenName";
    10="sn";
    11="middlename";
    12="hireDate";
    13="titleCode";
    14="SubTitleCode";
    15="positionPositionNumber";
    16="preferredFirstName";
    17="positionAppointmentID";
    20="wctitle";
    21="personalTitle";
    22="personalBirthDate";
    23="fTEClassification";
    33="homePhone";
    39="department";
    40="division";
    41="positionOrgUnit";
    42="companyOfficePhone";
    43="mobile";
    44="facsimileTelephoneNumber";
} # TODO: modify me

function CreateEmployee ($userProperties, $sAMAccountNameTemplate, $nameTemplate, $userPassword, $ouDN, $domainName)
{
    # Build 'User logon name (pre-Windows 2000)'
    $samAccountName = ""
    foreach ($propertyInfo in $sAMAccountNameTemplate)
    {
        $value = $userProperties[$propertyInfo[0]]
        $valueLength = $propertyInfo[1]
        
        # Check value length
        if (($valueLength -ne 0) -and ($valueLength -lt $value.Length))
        {
            $value = $value.SubString(0, $valueLength)
        }
        
        $sAMAccountName += $value
    }
    
    if ([System.String]::IsNullOrEmpty($sAMAccountName))
    {
        $Context.LogMessage("Cannot generate s logon name for user wtih Employee ID: " + $userProperties.EmployeeID, "Error")
        return
    }

    # Check whether the user exists
    $employeeID = $userProperties["EmployeeID"]
    $user = Get-AdmUser -Filter {employeeID -eq $employeeID} -AdaxesService localhost -Server $domainName
    
    if ($user -ne $NULL)
    {
        $Context.LogMessage("Cannot create user with Employee ID $($userProperties.EmployeeID). A user with the same Employee ID already exists.", "Error")
        return
    }
    
    # Build name
    $name = ($nameTemplate | %%{$userProperties[$_]}) -join " "
    if ([System.String]::IsNullOrEmpty($name))
    {
        $name = $sAMAccountName # Set 'User logon name (pre-Windows 2000)' as name
    }
    
    # Convert password to Secure String
    $userPassword = ConvertTo-SecureString -AsPlainText $userPassword -Force
    
    # Create user
    try
    {
        New-AdmUser -Name $name -SamAccountName $sAMAccountName -OtherAttributes $userProperties -AdaxesService localhost `
            -Server $domainName -Path $ouDN -Enabled $True -ErrorAction Stop -AccountPassword $userPassword
    }
    catch
    {
        $Context.LogMessage("An error occurred when creating a user with Employee ID $($userProperties.EmployeeID). Error: " + $_.Exception.Message, "Error")
    }
}

function UpdateEmployee ($userProperties, $domainName)
{
    # Get Employee ID
    $employeeID = $userProperties.EmployeeID
    [void]$userProperties.Remove("EmployeeID")
    
    # Check whether the user exists
    $user = Get-AdmUser -Filter {employeeID -eq $employeeID} -AdaxesService localhost -Server $domainName
    
    if ($user -eq $NULL)
    {
        $Context.LogMessage("Cannot update user with Employee ID $($userProperties.EmployeeID). A user with the specified Employee ID does not exist.", "Warning")
        return
    }
    
    # Update the user
    Set-AdmUser $user.DistinguishedName -Replace $userProperties -AdaxesService localhost -Server $domainName
}

function TerminateEmployee ($userProperties, $disabledAccountsOUDN, $domainName)
{
    # Get Employee ID
    $employeeID = $userProperties.EmployeeID
    [void]$userProperties.Remove("EmployeeID")
    
    # Check whether the user exists
    $user = Get-AdmUser -Filter {employeeID -eq $employeeID} -AdaxesService localhost -Server $domainName
    
    if ($user -eq $NULL)
    {
        $Context.LogMessage("Cannot terminate user with Employee ID $($userProperties.EmployeeID). A user with the specified Employee ID does not exist.", "Warning")
        return
    }
    
    # Disable the user
    Disable-AdmAccount $user.DistinguishedName -Confirm:$False -AdaxesService localhost -Server $domainName
    
    # Move the user
    Move-AdmObject -Identity $user.DistinguishedName -TargetPath $disabledAccountsOUDN -AdaxesService localhost -Server $domainName
}

if (-not(Test-Path -Path $filePath))
{
    $Context.LogMessage("Incorrect file path: $filePath", "Error")
    return
}

# Ensure that no columns are of width 0 or lower.
$valuesLowerThanOrEqualToZero = $columnWidths | Where { $_ -le 0 }
if ($valuesLowerThanOrEqualToZero.Length -gt 0)
{
    $Context.LogMessage("The column width must be a value higher than 0. The value(s) '$($valuesLowerThanOrEqualToZero -join "', '")' is not valid for column width", "Error")
    return
}

# Build the a regular expression for parsing the columns
$regex = '^'
foreach($width in $columnWidths)
{
    $regex += "(.{$width})"
}
$regex += '$'

# Get domain name
$domainName = $Context.GetObjectDomain($ouDN)

# Import the file
[System.Object[]]$objects = Get-Content $filePath | Select-String -Pattern $regex

# Process the strings based on the regular expression 
for ($i = 0; $i -lt $objects.Length; $i++)
{
    $groups = $objects[$i].Matches | %%{$_.Groups}
    $operationType = [System.String]::Empty
    $userProperties = @{}
    foreach ($columnNumber in $columnInfos.Keys)
    {
        if ($columnNumber -eq 1)
        {
            # Get operation type
            $operationType = $groups[$columnNumber].Value.Trim()
            continue
        }

        # Get value and ldapPropertyName
        $value = $groups[$columnNumber].Value.Trim()
        if ([System.String]::IsNullOrEmpty($value))
        {
            continue
        }
        $property = $columnInfos[$columnNumber]
        
        # Add property info to the hash table
        [void]$userProperties.Add($property, $value)
    }
    switch ($operationType)
    {
        "1"
        {
            CreateEmployee $userProperties $sAMAccountNameTemplate $nameTemplate $userPassword $ouDN $domainName
        }
        "2"
        {
            UpdateEmployee $userProperties $domainName
        }
        "3"
        {
            TerminateEmployee $userProperties $disabledAccountsOUDN $domainName
        }
        default
        {
            $Context.LogMessage("Cannot get operation type for line '$i'", "Warning")
            continue
        }
    }
}

Comments ( 0 )
No results found.
Leave a comment