Created
August 5, 2022 18:05
-
-
Save sean-m/dc7a0e1bb8e16b1c13898191362324c9 to your computer and use it in GitHub Desktop.
For loading users into an ldap directory from a CSV file. Will create new users and update attributes as needed on existing users.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Module ActiveDirectory | |
[CmdletBinding()] | |
param ($users_file, [switch]$WhatIf) | |
if (-not $users_file) { | |
Write-Warning "Must pass file name as `$users_file" | |
return 1 | |
} | |
Write-Host -ForegroundColor Cyan $users_file | |
cd $(Split-Path -parent "$($MyInvocation.MyCommand.Definition)") | |
function ToPages { | |
param ( | |
[Parameter(ValueFromPipeline=$true, Position=0)] | |
[object]$InputObject, | |
[Parameter(Mandatory=$true, Position=1)] | |
[int]$PageSize) | |
begin { | |
$book = New-Object System.Collections.Generic.List[object] | |
$page = @() | |
} | |
process { | |
$page += $InputObject | |
if ($page.Count -ge $PageSize) { | |
$book.Add($page) | |
$page = @() | |
} | |
} | |
end { | |
$book.Add($page) | |
$book.ToArray() | |
} | |
} | |
$ldap_server = 'localhost:389' | |
$ldap_root = 'DC=McAttributes,DC=or,DC=gov' | |
$ldap_active_root = 'CN=Users,DC=McAttributes,DC=or,DC=gov' | |
$ldap_property_map = @{ | |
'name'="aadId" | |
'displayName'="displayName" | |
'employeeId'="employeeId" | |
'givenName'="givenName" | |
'surname'="surname" | |
'comment'="pronouns" | |
'personalTitle'="suffix" | |
} | |
$name_attribute = $ldap_property_map['name'] | |
$ldap_properties = @($ldap_property_map.Keys) | |
$user_properties = @($ldap_property_map.Values) | |
## Load CSV | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Importing user records' | |
$users = Import-Csv $users_file | |
$users_hashset = New-Object System.Collections.Generic.HashSet[string] | |
$users | % { $users_hashset.Add($_.($ldap_property_map['name'])) } | Out-Null | |
Write-Host "Loaded $($users.Count) user records" | |
## Load active LDS users | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Loading LDS current users' | |
$active_users = @(Get-ADUser -Server $ldap_server -SearchBase $ldap_active_root -LDAPFilter "(objectClass=person)" -Properties $ldap_properties) | |
$active_hashset = New-Object System.Collections.Generic.HashSet[string] | |
$active_users | % { $active_hashset.Add($_.Name) } | Out-Null | |
Write-Host "Loaded $($active_users.Count) active LDS user records" | |
## Compute new users | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Resolving new users' | |
$new_users = @($users | ? { -not $active_hashset.Contains($_.($ldap_property_map['name'])) }) | |
Write-Host "New user records $($new_users.Count)" | |
## Create users | |
Write-Host "Creating new users" | |
filter Percent { param ([int]$count=0, [int]$total=0) if ($total -eq 0) { return 0 } [Math]::Min(100,[Math]::Round((($count/$total) * 100))) } | |
$count = 0 | |
if ($new_users) { | |
foreach ($user in $new_users) { | |
$count++ | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Creating user accounts' -PercentComplete (Percent $count $new_users.Count) | |
$params = @{ | |
'WhatIf'=$WhatIf | |
} | |
if ($user.($ldap_property_map['displayName'])) { | |
$params.Add('DisplayName', $user.($ldap_property_map['displayName'])) | |
} | |
if ($user.($ldap_property_map['givenName'])) { | |
$params.Add('GivenName', $user.($ldap_property_map['givenName'])) | |
} | |
if ($user.($ldap_property_map['surname'])) { | |
$params.Add('Surname', $user.($ldap_property_map['surname'])) | |
} | |
New-ADUser -Server $ldap_server -Path $ldap_active_root ` | |
-Name $user.$name_attribute ` | |
-Verbose ` | |
@params | |
} | |
} | |
else { | |
Write-Host "No new users to add" | |
} | |
## Reload active user objects | |
if ($new_users.Count -gt 0) { | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Refreshing active user list' | |
$active_users = @(Get-ADUser -Server $ldap_server -SearchBase $ldap_active_root -LDAPFilter "(objectClass=user)" -Properties $ldap_properties) | |
Write-Host "Loaded $($active_users.Count) active LDS user records" | |
} | |
$active_user_ht = @{} | |
$active_users | % { $active_user_ht.Add($_.Name, $_) } | Out-Null | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Refreshing active user list' -Completed | |
## Update Attributes | |
function CleanChars { | |
param ([string]$InputString) | |
if ([String]::IsNullOrEmpty($InputString)) { return $InputString } | |
$sb = New-Object System.Text.StringBuilder ($InputString.Length) | |
foreach ($c in $InputString.ToCharArray()) { | |
switch ($c) { | |
'[' { } #do nothing | |
']' { } #do nothing | |
'*' { } #do nothing | |
'?' { } #do nothing | |
default { $sb.Append($c) | Out-Null } | |
} | |
} | |
return $sb.ToString() | |
} | |
$count = 0 | |
foreach ($user in $users) { | |
$count++ | |
Write-Progress -Activity 'Provisioning LDS Users' -CurrentOperation 'Updating user attributes' -PercentComplete (Percent $count $users.Count) | |
$lds_user = $active_user_ht[$user.$name_attribute] | |
if ($lds_user) { | |
$params = @{ | |
'Verbose'=$true | |
'WhatIf'=$WhatIf | |
'Server'=$ldap_server | |
} | |
$replace_vals = @{} | |
$set_vals = @{} | |
$clear_vals = @() | |
foreach ($p in $ldap_properties) { | |
$up = $ldap_property_map[$p] | |
if ($user.$up -notlike (CleanChars $lds_user.$p)) { | |
# destination has value, source doesn't. Clear destination. | |
if (-not $user.$up -and $lds_user.$p) { | |
$clear_vals += $ldap_property_map[$p] | |
} | |
elseif ($user.$up -and ($lds_user.$p)) { | |
$replace_vals.Add($p, $user.$up) | |
} | |
elseif ($user.$up -and (-not $lds_user.$p)) { | |
$set_vals.Add($p, $user.$up) | |
} | |
else { | |
Write-Warning "No match for ldap property: $p to user property: $up" | |
} | |
} | |
} | |
if ($replace_vals.Count -gt 0) { $params.Add("Replace", $replace_vals) } | |
if ($set_vals.Count -gt 0) { $params.Add("Add", $set_vals) } | |
if ($clear_vals) { $params.Add("Clear", $clear_vals) } | |
if ($params.Count -gt 3) { | |
$lds_user | Set-ADObject @params | |
} | |
} | |
else { | |
Write-Warning "User: $($user.$name_attribute) not found, skipping..." | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment