[CmdletBinding()] param (     [string]$CSVfile = "justice.csv" ) <# ******************************************************************************************* Script for processing user accounts for Justice Inc. Version 2021v2.3 ******************************************************************************************* The main part of this script will loop through all lines of the given CSV file and check each line against ADDS. There are three possible scenario's that need to be addressed:    1. The user exists in the CSV, but not in ADDS --> Create new user in ADDS    2. The user exists in both the CSV and ADDS --> Check differences and update ADDS if applicable    3. The user does not exist in the CSV, but does in ADDS --> Remov the user from ADDS ******************************************************************************************* #> # Fuction for collecting all user values from either the CSV file and by combining values to new ones # This function takes one input parameter: the SamAccountName of the target object # This function returns a PowerShell hashtable object that contains all neccesariy key/value pairs, ready for use function GetJusticeUser {     param (         [string]$AccountName     )     # Loop through all lines in the CSV file and for each line, check if that line is the target object     # If so, start collecting and concatinating values     # If not, skip to the next line in the CSV file     foreach ($csv in $myCSVfile) {         if ($AccountName -eq $csv.Account) {             $myFirstName = (Get-Culture).TextInfo.ToTitleCase($csv.'first-name')             $csvLastName = $csv.'last-name'             if ($csvLastName.Contains(" ")) {                 $csvLastNameArray = $csvLastName.Split(" ")                 $newLastPart = (Get-Culture).TextInfo.ToTitleCase($csvLastNameArray[-1])                 $csvLastNameArray[-1] = $newLastPart                 $myLastName = "$csvLastNameArray"             } else {                 $myLastName = (Get-Culture).TextInfo.ToTitleCase($csvLastName)             }             $myDepartment = (Get-Culture).TextInfo.ToTitleCase($csv.department)             $myJobDescription = (Get-Culture).TextInfo.ToTitleCase($csv.'job-description')             $csvGroup = (Get-Culture).TextInfo.ToTitleCase($csv.group)             $myGroup = (Get-Culture).TextInfo.ToTitleCase($csvGroup)             $myGroup = ("GS_" + $myGroup.Replace(" ", "_"))             $myManager = $csv.manager             $myPhonenumber = $csv.phone             $myCellphone = $csv.cell             $myOu = ("OU=" + $myDepartment + "," + $mySearchBase)             $myUpn = ($AccountName + "@" + $myDomainComponent1 + "." + $myDomainComponent2)             $myManagerDN = if ($myManager.Length -gt 0) { (Get-ADUser -Filter "samaccountname -eq '$myManager'").DistinguishedName } else { $null }             $myHomedirectory = ("\\" + $myDomainComponent1 + "." + $myDomainComponent2 + "\home$\" + $AccountName)             $myServerprofile = ("\\" + $myDomainComponent1 + "." + $myDomainComponent2 + "\profile$\" + $AccountName)             $myHomeDrive = "U:"             $myPassword = ConvertTo-SecureString -String "Welkom01" -AsPlainText -Force             # Structure all collected values is a single hashtable object...             $justiceUserProperties = @{                 FirstName = $myFirstName                 LastName = $myLastName                 FullName = ($myFirstName + " " + $myLastName)                 DisplayName = ($myLastName + ", " + $myFirstName)                 Department = $myDepartment                 JobDescription = $myJobDescription                 GroupName = $myGroup                 Description = $csvGroup                 Manager = $myManager                 Phone = $myPhonenumber                 CellPhone = $myCellphone                 TargetOU = $myOu                 UPN = $myUpn                 ManagerDN = $myManagerDN                 HomePath = $myHomedirectory                 HomeLetter = $myHomeDrive                 ProfilePath = $myServerprofile                 Secret = $myPassword             }         }     }     # ...and return that to the caller of the function     return $justiceUserProperties } function DisplayMessage {     param (         [array]$messageArray     )     Write-Host ("    " + $messageArray[0] + " ") -NoNewline     Write-Host $messageArray[1] -ForegroundColor $messageArray[2] -NoNewline     if ($messageArray.Count -gt 3) {         Write-Host (" " + $messageArray[3] + " ") -NoNewline         Write-Host $messageArray[4] -ForegroundColor $messageArray[5]     } else {         Write-Host     } } # Function for creating a new ADDS useraccount as found in the CSV file, but that does not yet exist in ADDS function AddJusticeUser {     param (         [string]$AccountName      )     Write-Host     Write-Host "Processing CSV entry " -NoNewline     Write-Host $AccountName -ForegroundColor Yellow -NoNewline     Write-Host " --> User account not found in ADDS"     $justiceUser = GetJusticeUser -AccountName $AccountName     $myTargetOU = $justiceUser.TargetOU          $isOu = [adsi]::Exists("LDAP://$myTargetOU")     if (-not $isOu) {         DisplayMessage @("Target ADDS Organizational Unit missing --> Creating ADDS OU", $myTargetOU, "Magenta")         New-ADOrganizationalUnit -Name $justiceUser.Department -Path $mySearchBase -ProtectedFromAccidentalDeletion:$false | Out-Null     }          try {         Get-ADGroup -Identity $justiceUser.GroupName -ErrorAction SilentlyContinue | Out-Null     }     catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {         $groupNotFound = $True     }     if ($groupNotFound) {         DisplayMessage @("Target ADDS group missing. Creating ADDS group", $justiceUser.GroupName, "Green")         New-ADGroup -Name $justiceUser.GroupName -Description $justiceUser.Description -GroupCategory Security -GroupScope Global -Path ("OU=SecurityGroups," + $mySearchBase) | Out-Null     }     DisplayMessage @("Adding ADDS account", $AccountName, "Yellow", "as new", $justiceUser.JobDescription, "Gray")     New-ADUser `         -SamAccountName $AccountName `         -UserPrincipalName $justiceUser.UPN `         -Name $justiceUser.FullName `         -GivenName $justiceUser.FirstName `         -Surname $justiceUser.LastName `         -Enabled $True `         -ChangePasswordAtLogon $True `         -Description $justiceUser.Description `         -DisplayName $justiceUser.DisplayName `         -Department $justiceUser.Department `         -Path $justiceUser.TargetOU `         -OfficePhone $justiceUser.Phone `         -Manager $justiceUser.ManagerDN `         -Title $justiceUser.JobDescription `         -Company "Justice Inc." `         -MobilePhone $justiceUser.CellPhone `         -ProfilePath $justiceUser.ProfilePath `         -HomeDirectory $justiceUser.HomePath `         -HomeDrive $justiceUser.HomeLetter `         -AccountPassword $justiceUser.Secret     $adUserNotCreated = $true       while ($adUserNotCreated) {         $isUser = Get-ADUser -Filter "SamAccountName -eq '$Accountname'"         if ($isUser) {             $adUserNotCreated = $false         }         Start-Sleep -Milliseconds 333     }     DisplayMessage @("Adding ADDS account", $AccountName, "Yellow", "to security group", $justiceUser.GroupName, "Green")     Add-ADGroupMember -Identity $justiceUser.GroupName -Members $AccountName | Out-Null     $isHomePath = Test-Path -Path $justiceUser.HomePath -ErrorAction SilentlyContinue     if (-not $isHomePath) {         DisplayMessage @("Target home folder missing. Creating user home folder", $justiceUser.HomePath, "Cyan")         New-Item -Path $justiceUser.HomePath -ItemType Directory | Out-Null         DisplayMessage @("Granting", $AccountName, "Yellow", "full access rights to", $justiceUser.HomePath, "Cyan")         $folderACL = Get-Acl -Path $justiceUser.HomePath         $myAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($AccountName, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")         $folderACL.SetAccessRule($myAccessRule)         Set-Acl -Path $justiceUser.HomePath -AclObject $folderACL | Out-Null     } } # Function for updating a useraccount in ADDS with updated values from the CSV file function UpdateJusticeUser {     param (         [string]$AccountName     )     $isChangeDetected = $false     $isFirstNameChange = $false     $isLastNameChange = $false     $isDepartmentChange = $false     $isDescriptionChange = $true     $isJobDescriptionChange = $false     $isManagerChange = $false     $isPhoneChange = $false     $isCellphoneChange = $false     $isGroupChange = $false     # Collect all fields for both the CSV file as well as the ADDS useraccount object     $justiceUserCSV = GetJusticeUser -AccountName $AccountName     $justiceUserADD = Get-ADUser -Identity $AccountName -Properties *     # Compare all collected values one by one and set variables if differences are discovered     if ($justiceUserCSV.FirstName -ne $justiceUserADD.GivenName) {         $isFirstNameChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.LastName -ne $justiceUserADD.sn) {         $isLastNameChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.Department -ne $justiceUserADD.Department) {         $isDepartmentChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.Description -ne $justiceUserADD.Description) {         $isDescriptionChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.JobDescription -ne $justiceUserADD.Title) {         $isJobDescriptionChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.ManagerDN -ne $justiceUserADD.Manager) {         $isManagerChange = $true         $isChangeDetected = $true     }     if ($justiceUserCSV.Phone -ne $justiceUserADD.OfficePhone) {         if ($justiceUserCSV.Phone.Length -gt 0) {             $isPhoneChange = $true             $isChangeDetected = $true         }     }     if ($justiceUserCSV.CellPhone -ne $justiceUserADD.MobilePhone) {         if ($justiceUserCSV.CellPhone.Length -gt 0) {             $isCellphoneChange = $true             $isChangeDetected = $true         }     }     $AddGroupName = (Get-ADGroup -Identity $justiceUserADD.MemberOf[0]).Name     if ($justiceUserCSV.GroupName -ne $AddGroupName) {         $isGroupChange = $true         $isChangeDetected = $true     }     # Take action for each discovered change and display feedback on screen     if ($isChangeDetected) {         Write-Host         Write-Host "Processing CSV entry " -NoNewline         Write-Host $AccountName -ForegroundColor Yellow -NoNewline         Write-Host " --> User account found in ADDS"         if ($isFirstNameChange) {             DisplayMessage @("Updating first name from", $justiceUserADD.GivenName, "Cyan", "to", $justiceUserCSV.FirstName, "Cyan")             DisplayMessage @("Updating full name from", $justiceUserADD.Name, "Cyan", "to", $justiceUserCSV.FullName, "Cyan")             Set-ADUser -Identity $AccountName -GivenName $justiceUserCSV.FirstName -DisplayName $justiceUserCSV.DisplayName | Out-Null             DisplayMessage @("Updating diaplay name from", $justiceUserADD.DisplayName, "Cyan", "to", $justiceUserCSV.DisplayName, "Cyan")             $AddUserID = (Get-ADUser -Identity $AccountName).DistinguishedName             Rename-ADObject -Identity $AddUserID -NewName $justiceUserCSV.FullName | Out-Null         }         if ($isLastNameChange) {             DisplayMessage @("Updating last name from", $justiceUserADD.sn, "Cyan", "to", $justiceUserCSV.LastName, "Cyan")             DisplayMessage @("Updating full name from", $justiceUserADD.Name, "Cyan", "to", $justiceUserCSV.FullName, "Cyan")             Set-ADUser -Identity $AccountName -Surname $justiceUserCSV.LastName -DisplayName $justiceUserCSV.DisplayName | Out-Null             DisplayMessage @("Updating diaplay name from", $justiceUserADD.DisplayName, "Cyan", "to", $justiceUserCSV.DisplayName, "Cyan")             $AddUserID = (Get-ADUser -Identity $AccountName).DistinguishedName             Rename-ADObject -Identity $AddUserID -NewName $justiceUserCSV.FullName | Out-Null         }         if ($isDepartmentChange) {             DisplayMessage @("Updating department from", $justiceUserADD.Department, "Cyan",  "to", $justiceUserCSV.Department, "Cyan")             Set-ADUser -Identity $AccountName -Department $justiceUserCSV.Department | Out-Null         }         if ($isDescriptionChange) {             DisplayMessage @("Updating description from", $justiceUserADD.Description, "Cyan", "to", $justiceUserCSV.Description, "Cyan")             Set-ADUser -Identity $AccountName -Description $justiceUserCSV.Description | Out-Null         }         if ($isJobDescriptionChange) {             DisplayMessage @("Updating title from", $justiceUserADD.Title, "Cyan", "to", $justiceUserCSV.JobDescription, "Cyan")             DisplayMessage @("Updating description from", $justiceUserADD.Description, "Cyan", "to", $justiceUserCSV.Description, "Cyan")             Set-ADUser -Identity $AccountName -Description $justiceUserCSV.Description -Title $justiceUserCSV.JobDescription | Out-Null             DisplayMessage @("Moving ADDS account", $AccountName, "Yellow", "to", $justiceUserCSV.TargetOU, "Blue")             $AddUserID = (Get-ADUser -Identity $AccountName).DistinguishedName             Move-ADObject -Identity $AddUserID -TargetPath $justiceUserCSV.TargetOU -Confirm:$false | Out-Null         }         if ($isManagerChange) {             $myManagerName = (get-aduser -identity $justiceUserADD.Manager -Properties SamAccountName).SamAccountName             DisplayMessage @("Updating manager from", $myManagerName, "DarkGreen", "to", $justiceUserCSV.Manager, "DarkGreen")             Set-ADUser -Identity $AccountName -Manager $justiceUserCSV.ManagerDN | Out-Null         }         if ($isPhoneChange) {             DisplayMessage @("Updating office phone from", $justiceUserADD.OfficePhone, "Cyan", "to", $justiceUserCSV.Phone, "Cyan")             Set-ADUser -Identity $AccountName -OfficePhone $justiceUserCSV.Phone         }         if ($isCellphoneChange) {             DisplayMessage @("Updating cell phone from", $justiceUserADD.MobilePhone, "Cyan", "to", $justiceUserCSV.CellPhone, "Cyan")             Set-ADUser -Identity $AccountName -MobilePhone $justiceUserCSV.CellPhone | Out-Null         }         if ($isGroupChange) {             DisplayMessage @("Clearing ADDS account", $AccountName, "Yellow", "from security group", $AddGroupName, "Green")             Remove-ADGroupMember -Identity $AddGroupName -Members $AccountName -Confirm:$false | Out-Null             DisplayMessage @("Adding ADDS account", $AccountName, "Yellow", "to security group", $justiceUserCSV.GroupName, "Green")             Add-ADGroupMember -Identity $justiceUserCSV.GroupName -Members $AccountName | Out-Null         }     } } #function for removing a useraccount from ADDS if it does not exist in the CSV file function RemoveJusticeUser {     param (         [string]$AccountName     )     Write-Host     Write-Host "Processing CSV entry " -NoNewline     Write-Host $AccountName -ForegroundColor Yellow -NoNewline     Write-Host " --> User not found in CSV"     $AddsUserObject = Get-ADUser -Properties * -Identity $AccountName     foreach ($adGroup in $AddsUserObject.MemberOf) {         $adGroupShort = $adGroup.Split(",")[0]                 $adGroupShort = $adGroupShort.Substring(3,$adGroupShort.Length-3)         DisplayMessage @("Removing ADDS account", $AccountName, "Yellow", "from security group", $adGroupShort, "Green")         Remove-ADGroupMember -Identity $adGroup -Members $AccountName -Confirm:$false | Out-Null     }     if (Test-Path -Path $AddsUserObject.HomeDirectory) {         DisplayMessage @("Removing Home folder", $AddsUserObject.HomeDirectory, "Cyan")         Remove-Item -Path $AddsUserObject.HomeDirectory -Recurse -Confirm:$false | Out-Null     }     if (Test-Path -Path ($AddsUserObject.ProfilePath + ".V6")) {         DisplayMessage @("Removing Profile folder", ($AddsUserObject.ProfilePath + ".V6"), "Cyan") #        Remove-Item -Path ($AddsUserObject.ProfilePath + ".V6") -Recurse -Confirm:$false | Out-Null     }     $myRedirectPath = ("\\" + $myDomainComponent1 + "." + $myDomainComponent2 + "\redirect$\" + $AccountName)     if (Test-Path -Path $myRedirectPath) {         DisplayMessage @("Removing Redirected folders", $myRedirectPath, "Cyan") #        Remove-Item -Path $myRedirectPath -Recurse -Confirm:$false | Out-Null     }     DisplayMessage @("Removing ADDS account", $AccountName, "Yellow")     Remove-ADUser -Identity $AccountName -Confirm:$false | Out-Null } # MAIN SCRIPT # Provide a blank canvas for status messages Clear-Host # As this script is inteded to manipulate ADDS objects, import the ADDS module import-module ActiveDirectory # Start user friendly output to the screen Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host "AD Processing Script for Justice INC." Write-Host "=====================================" Write-Host ("Looking for CSV-file <" + $CSVfile + ">".PadRight(8)) -NoNewline # Test if the CSv file can be found and throw an error if that is nog the case and exit the script # Otherwise, continue if (-not(Test-Path -Path $CSVfile -PathType Leaf)) {     Write-Host ("--> ERROR. The file <" + $CSVfile + "> can not be found. Please provide the correct path and retry.")     Write-Host     exit } Write-Host "--> OK." Write-Host "Processing. Please wait..." # Import CSV file and create some variables for later use $myCSVfile = Import-Csv -Path $CSVfile -Delimiter ";" $myDomainComponent1 = ((Get-WMIObject Win32_ComputerSystem).Domain.Split("."))[0] $myDomainComponent2 = ((Get-WMIObject Win32_ComputerSystem).Domain.Split("."))[1] $mySearchBase = ("OU=Justice,DC=" + $myDomainComponent1 + ",DC=" + $myDomainComponent2) # Check if root OU exist, if not: create it $isOuRoot = [adsi]::Exists("LDAP://$mySearchBase") if (-not $isOuRoot) {     New-ADOrganizationalUnit -Name "Justice" -Path ("DC=" + $myDomainComponent1 + ",DC=" + $myDomainComponent2)     # Give ADDS some time to process     Start-Sleep -Seconds 2 } # Pull list of all current useraccounts from ADDS $myAdUserList = Get-ADUser -SearchBase $mySearchBase -Filter * # Show overall progress bar on screen Write-Progress -Activity "Overall Progress" -PercentComplete 0 -Id 123 # Set up variables for all procress bars (set curren to zero and target to number of reccords) $csvCurrentRecord = 0 $addsCurrentRecord = 0 $overallCurrentRecord = 0 $csvRecordCount = (Get-Content $CSVfile | Measure-Object -Line).Lines $addsUserCount = $myAdUserList.Count $overallCount = $csvRecordCount + $addsUserCount # Main script loop for either creating new users that dont exist in ADDS, or updating user info in ADDS based on CSV info foreach ($csv in $myCSVfile) {     $isAdUser = $false     foreach ($user in $myAdUserList) {         if ($csv.account -eq $user.SamAccountName) {             $isAdUser = $true         }     }     if ($isAdUser) {         UpdateJusticeUser $csv.account     } else {         AddJusticeUser $csv.account     }     # Update progress bars after processing     $csvCurrentRecord++     $overallCurrentRecord++     Write-Progress -Activity "Processing CSV file" -Status ("Enty " + $csv.account) -PercentComplete (($csvCurrentRecord / $csvRecordCount) * 100) -ParentId 123     Write-Progress -Activity "Overall Progress" -PercentComplete (($overallCurrentRecord / $overallCount) * 100) -Id 123     Start-Sleep -Milliseconds 100 } # Update overall progress bar between the two actions $overallCurrentRecord++ Write-Progress -Activity "Overall Progress" -PercentComplete (($overallCurrentRecord / $overallCount) * 100) -Id 123 # Main script loop for deleting ADDS users that don't exist in the CSV file foreach ($adds in $myAdUserList) {     $isCSVuser = $false     foreach ($csv in $myCSVfile) {         if ($adds.SamAccountName -eq $csv.account) {             $isCSVuser = $true         }     }     if (-not $isCSVuser) {         RemoveJusticeUser $adds.SamAccountName     }     # Update progress bars after processing     $addsCurrentRecord++     $overallCurrentRecord++     Write-Progress -Activity "Processing ADDS users" -Status ("Account " + $adds.SamAccountName) -PercentComplete (($addsCurrentRecord / $addsUserCount) * 100)     Write-Progress -Activity "Overall Progress" -PercentComplete (($overallCurrentRecord / $overallCount) * 100) -Id 123     Start-Sleep -Milliseconds 100 } # Display feedback on screen once processing is done Write-Host Write-Host "Done!" Write-Host