Public/AD/New-AdUserFromPopuliPerson.ps1

function New-AdUserFromPopuliPerson
{

    [CmdletBinding(PositionalBinding = $true)]
    param
    (
        [Parameter(Mandatory = $true)][string]$PersonId,
        [Parameter(Mandatory = $true)][string]$DomainName,
        [Parameter(Mandatory = $true)]$RoleOuMap,

        [Parameter(Mandatory = $false)][ValidateLength(200, 999)][string]$PopuliToken = $env:PopuliToken,
        [Parameter(Mandatory = $false)][ValidatePattern('^(?i)https:\/\/\S+\.populiweb\.com\/?$')][string]$BaseUrl = $env:PopuliBaseUrl
    )


    try
    {

        Write-Log "Processing person with Popuili PersonId ""$($PersonId)"""


        $returnObjProps = [ordered]@{
            Action     = 'NewUser'
            Result     = ''
            EmployeeId = $PersonId
            UserType   = $null
            FirstName  = $null
            LastName   = $null
            LoginName  = $null
            Email      = $null
            Password   = $null
            Tags       = $null
            AdGroups   = $null
        }
        
        $returnObj = New-Object psobject -Property $returnObjProps
        
        $personObj = Get-PopuliPerson -PersonId $PersonId -PopuliToken $PopuliToken -BaseUrl $BaseUrl
        
        if ($personObj.first.Length -lt 3 -or $personObj.last.Length -lt 3)
        {
            Write-Log "Error creating new aduser from Populi person ""$PersonId"". No valid Person was returned from Populi using command: Get-PopuliPerson -PersonId ""$PersonId""" -LogType: warning
            $returnObj.Result = 'ERROR: ErrorFetchingPersonFromPopuli'
            return $returnObj
        }
        
        $firstName = $personObj.first
        $lastName = $personObj.last
        
        if ($personObj.preferred_name.Length -gt 0)
        {
            $firstName = $personObj.preferred_name
        }
        
        if ($personObj.prefix.Length -gt 0)
        {
            $displayName = "$lastName, $($personObj.prefix) $firstName"
        }
        else
        {
            $displayName = "$lastName, $firstName"
        }
        
        
        
        
        $email = "$samAccountName@$DomainName"
        
        $firstInitial = $firstName[0].ToString().ToUpper()
        $lastInitial = $lastName[0].ToString().ToLower()
        $password = $firstInitial + $lastInitial + $PersonId
        $passwordSecureString = $password | ConvertTo-SecureString -AsPlainText -Force


        $samAccountName = $firstInitial.ToLower() + $lastName.ToLower()
        
        $returnObj.FirstName = $firstName
        $returnObj.LastName = $lastName
        $returnObj.LoginName = $samAccountName
        $returnObj.Password = $password
        $returnObj.Email = $email
        
        $adUserAlreadyExists = $null
        
        try
        {
            $adUserAlreadyExists = Get-ADUser $samAccountName
        }
        catch
        {
        }
        
        
        if ($adUserAlreadyExists)
        {
            Write-Log "Error creating new aduser from Populi person ""$PersonId"" ($displayName). User with SamAccountName ""$samAccountName"" already exists in AD: ""$($adUserAlreadyExists.DistinguishedName)""" -LogType: warning
            $returnObj.Result = 'ERROR: AlreadyExistsInAD'
            return $returnObj
        }
        
        
        $personRoles = @(Get-PopuliPersonRoles -PersonId $PersonId -PopuliToken $PopuliToken -BaseUrl $BaseUrl)
        
        $ou = $null
        
        foreach ($role in $personRoles)
        {
            if ($RoleOuMap.Keys -contains $role.name)
            {
                $returnObj.UserType = $role.name
                $ou = $RoleOuMap[$role.name]
                break
            }
        }
        
        if (!$ou)
        {
            if ($RoleOuMap.Keys -notcontains 'default')
            {   
                Write-Log "Cannot create new user ""$PersonId"". Invalid default OU in RoleOuMap param."
                $returnObj.Result = "ERROR: InvalidDefaultOU"
                return $returnObj
            }

            Write-Log "Could not find a role that matched value in RoleOuMap param. Using default OU: ""$($RoleOuMap.default)"""
            $ou = $RoleOuMap.default
        }
        
        
        $newUserProps = [ordered]@{
            Enabled               = $true
            EmployeeId            = $PersonId
            GivenName             = $firstName
            Surname               = $lastname
            SamAccountName        = $samAccountName
            Name                  = $displayName
            DisplayName           = $displayName
            UserPrincipalName     = $email
            EmailAddress          = $email
            AccountPassword       = $passwordSecureString
            PasswordNeverExpires  = $true
            ChangePasswordAtLogon = $false
            Description           = "Automatically created $(Get-Date -Format "yyyy-MM-dd") by Populi-AD-Sync script"
            Path                  = $ou
            ErrorAction           = "Stop"
        
        }
        
        Write-Log "Creating new AD User: $($newUserProps | ConvertTo-Json -Compress)"
        
        try
        {
            $newUserResp = New-ADUser @newUserProps
        
            $returnObj.Result = 'OK'
        }
        catch
        {
            Write-Log "Error using New-ADUser. PersonId: $PersonId" -LogType error -ErrorObject $_
            $returnObj.Result = "ERROR: Exception calling New-ADUser"
            return $returnObj
        }
        
        $personTags = @($personObj.tags.tag)
        
        if ($personTags.Count -gt 0)
        {
            $tagListString = """$($personTags.name -join '", "')"""
            $returnObj.Tags = $tagListString
        
            $adGroupsToAdd = @(Get-ADGroup -Filter { Name -like "@*" } -Properties Description | ? { $_.Description.Length -gt 3 -and $personTags.name -contains $_.Description })
        
            if ($adGroupsToAdd.Count -gt 0)
            {
                $adGroupListString = """$($adGroupsToAdd.Name -join '", "')"""
                $returnObj.AdGroups = $adGroupListString
        
                Write-Log "Adding ""$samAccountName"" ($PersonId) to $($adGroupsToAdd.Count) AD Group(s). Tags >> $tagListString || Matching AD Groups >> $adGroupListString"
        
                foreach ($group in $adGroupsToAdd)
                {
                    try
                    {
                        Add-ADGroupMember -Identity $group.ObjectGUID.Guid -Members $samAccountName -ErrorAction Stop
                        Write-Log "Added ""$samAccountName"" ($PersonId) to AD Group ""$($group.Name)"". Command: Add-ADGroupMember -Identity ""$($group.DistinguishedName)"" -Members ""$samAccountName"""
                    }
                    catch
                    {
                        Write-Log "Error adding ""$samAccountName"" ($PersonId) to AD Group ""$($group.Name)"". Command: Add-ADGroupMember -Identity ""$($group.DistinguishedName)"" -Members ""$samAccountName""" -LogType error -ErrorObject $_
                        continue
                    }
                    
                }
            }
            else
            {
                Write-Log "Could not find any AD Groups that match new user's tags. User: ""$samAccountName"" ($PersonId). Tags: $tagListString " -LogType warning
            }
        
        }
        else
        {
            Write-Log "Skipping AD Group membership for user ""$samAccountName"" ($PersonId). No tags found." -LogType warning
        }


    }
    catch
    {
        Write-Log "Unhandled exception" -LogType: error -ErrorObject $_
        Write-Error $_

        return $null
    }

    return $returnObj


}