# User-input Variables
$csvFile='C:\Users-finalized.csv'
$newOu='CN=Users,DC=kimconnect,DC=com'
$newCompany='Kim Connect'
$logFile="c:\temp\createActiveDirectoryAccounts-$(get-date -f yyyy-mm-dd-hh-mm-ss).txt"

function createActiveDirectoryAccounts{
  param(
    $csvFile,
    $newOu,
    $newCompany,
    $logFile="c:\temp\createActiveDirectoryAccounts-$(get-date -f yyyy-mm-dd-hh-mm-ss).txt"
  )

  # Declare variables Log Files
  $failures = @()
  $usersAlreadyExist =@()
  $successes = @()
  $erroractionpreference = "Continue"

  write-host "Gathering Active Directory Users Information..."
  $existingUsers=Get-ADUser -Filter * -property SamAccountName,EmailAddress
  $users = Import-Csv -Path $csvFile
  $voidChars='#N/A','',$null
  $ou=if($newOu){$newOu}else{
    $domainLdapExpression='DC='+((($env:USERDNSDOMAIN).tolower() -split '\.') -join ',DC=');
    'CN=Users,'+$domainLdapExpression
  }
  $sortedRecords=$users|sort -property newSamAccountName

  write-host "Commencing users creation..."
  foreach ($user in $sortedRecords) {
    $userExists=$user.newSamAccountName -in $existingUsers.SamAccountName -or $user.newEmailAddress -in $existingUsers.EmailAddress
    if(!$userExists){
      $password = $user.newPassword | ConvertTo-SecureString -AsPlainText -Force
      $proxyAddresses = $user.newEmailAddress
      $streetAddress=if($user.'Street 2' -notin $voidChars){$user.'Street 1'+', '+$user.'Street 2'}elseif($user.'Street 1' -notin $voidChars){$user.'Street 1'}else{$null}
      $city =if($user.City -notin $voidChars){$user.City}else{$null}
      $state =if($user.State -notin $voidChars){$user.State}else{$null}
      $postalCode=if($user.PostalCode -notin $voidChars){$user.PostalCode}else{$null}
      $country=if($user.Country -notin $voidChars){$user.Country}else{$null}
      $jobTitle=if($user.Title -notin $voidChars){$user.Title}else{$null}
      $telephone=if($user.telephoneNumber -notin $voidChars){$user.telephoneNumber}else{$null}
      $extension=if($user.Extension -notin $voidChars){$user.Extension}else{$null}
      $displayName=$user.Surname+', '+$user.GivenName
      $newSamAccountName=$user.newSamAccountName
      $newUserPrincipleName=$newSamAccountName+'@'+$env:USERDNSDOMAIN
      # Generating a hash table as a splatting technique
      $params = @{        
        SamAccountName = $newSamAccountName;
        Path = $ou;
        Enabled = $true;        
        AccountPassword = $password;
        ChangePasswordAtLogon = $False;
        EmployeeID = $user.EmployeeID;
        Name = $displayName;
        GivenName = $user.GivenName;
        Surname = $user.Surname;
        DisplayName = $displayName;
        UserPrincipalName = $newUserPrincipleName;
        Initials = $user.Initials;
        Description = $user.Description;    
        Office = $user.Office;
        Title = $jobTitle
        # Manager = $user.newManagerDN
        Company = $newCompany;
        Department = $user.Department;
        Division = $user.Division;
        StreetAddress = $streetAddress;
        EmailAddress = $user.newEmailAddress;
        City = $city
        State = $state
        PostalCode = $postalCode
        Country = $country
        OfficePhone = $telephone
        OtherAttributes = @{ 
            IPPhone = $extension;
            #extensionAttribute2 = $($User.extensionAttribute2);
            #extensionAttribute3 = $($User.extensionAttribute3);
            #extensionAttribute4 = $($User.extensionAttribute4);
          }
        }
    
      # Removing empty values
      @($params.OtherAttributes.Keys)|%{if(-not $params.OtherAttributes[$_]){$params.OtherAttributes.Remove($_)}}
      $voidCount=(@($params.OtherAttributes.Keys) | % {if ($params.OtherAttributes[$_] -in $voidChars) {$_}}).Count
      if($params.OtherAttributes.Keys.count -eq $voidCount){$params.Remove('OtherAttributes')}
      @($params.Keys) | % {if ($null -eq $params[$_]) {$params.Remove($_)}}
      
      try{       
        # Creating the user account
        New-ADUser @params -PassThru #-Verbose      
        
        # Setting the Proxy Address as required for Office 365 and Microsoft Exchange integration
        If (-not [string]::IsNullOrWhiteSpace($proxyAddresses)){
            foreach( $proxyAddress in ( $proxyAddresses -split ';' ) ){
            write-host "adding $proxyAddress to user $newSamAccountName" -ForegroundColor Yellow
            Set-ADUser -Identity $($user.newSamAccountName) -Add @{proxyAddresses=$proxyAddresses}}
            }
        $successes+="$newSamAccountName with display name '$displayName' has been succesfully created"
      }catch{
        $failures+="$newSamAccountName creation has failed with error: $_"
      }
    }else{
      write-warning "$($user.newSamAccountName) already exists in $env:USERDNSDOMAIN"
      $usersAlreadyExist+="$($user.newSamAccountName) already exists"
    }
  }

  write-host "Updating Managers DNs..."
  foreach ($user in $sortedRecords) {
    try{      
      if($user.newManagerDN -notin $voidChars){
        Set-ADUser $user.newSamAccountName -Manager $user.newManagerDN
      }         
    }catch{
      $failures+="$($user.newSamAccountName) Manager DN update has failed with this error: $_"
    }
  }

  $divider='`r`n`r`n==============================================================`r`n`r`n'
  $logMessages=$failures+$divider+$usersAlreadyExist+$divider+$successes
  $logMessages | Out-File -FilePath $logFile
  write-host "Results have been logged at $logFile"
}

createActiveDirectoryAccounts $csvFile