Private/Google/Get-GoogleUsersToSetEmployeeID.ps1
|
<# .SYNOPSIS Match unlinked source users to existing Google accounts by primary email and name. .DESCRIPTION For each source user without a GoogleCurrentUserID, looks for a Google user whose primaryEmail equals the source UPN and whose given/family name match. A match is returned so the source record can be linked to (and its externalId set on) that existing account — letting unlinked or deprovisioned accounts be reconciled and, if inactive, deactivated. A primaryEmail that matches a different name is logged as an error and skipped — unless that exact mismatch was approved via Approve-IDBridgeNameMismatch (persisted in <DataRoot>\ApprovedNameMismatches.csv), in which case it links; an approval whose recorded account/name no longer matches the current Google account is logged as a warning and skipped. .PARAMETER UserList The source records (the in-progress user list). .PARAMETER GoogleUsers All current Google users (from Get-TargetDataGoogle .Users). .OUTPUTS [hashtable] personID -> @{ ID; Groups; SuspendedStatus; User }. .EXAMPLE $matches = Get-GoogleUsersToSetEmployeeID -UserList $sourceData -GoogleUsers $googleData.Users .NOTES Created by: Sam Cattanach Modified: 2026-08-19 #> function Get-GoogleUsersToSetEmployeeID { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $UserList, [Parameter(Mandatory = $true)] $GoogleUsers ) #Set Users that need EmployeeID set in Google #If no user exists with the employee ID, try username #Username has to pair with the first name and last name - unless the mismatch was #explicitly approved via Approve-IDBridgeNameMismatch $itemUpdateList = @{} $approvedMismatches = Get-IDBridgeApprovedNameMismatches foreach ($item in $UserList | Where-Object {-not $_.GoogleCurrentUserID}) { $googleUser = $null #One outcome line per user, logged where the decision is made, so the discovery #and its result read together instead of in separate phases if ($item.UPN -in $GoogleUsers.primaryEmail) { $googleUser = ($GoogleUsers | Where-Object {$_.primaryEmail -eq $item.UPN}) $link = $false if ($googleUser.Name.familyName -eq $item.NameLast -and $googleUser.Name.givenName -eq $item.NameFirst) { Write-Log -Message ("Google: No user with EmployeeID: $($item.personID) - matched existing $($googleUser.primaryEmail) by username+name; will link EmployeeID.") $link = $true } else { #Name differs - honor a recorded approval only while both sides still match #what was approved; a drifted account name means re-approval is required $approval = $approvedMismatches["Google|$($item.personID)"] if ($approval -and $approval.Account -eq $item.UPN -and $approval.DirectoryName -eq ($googleUser.Name.givenName + " " + $googleUser.Name.familyName)) { Write-Log -Message ("Google: No user with EmployeeID: $($item.personID) - matched existing $($googleUser.primaryEmail) by username with name mismatch approved on $($approval.ApprovedDate); will link EmployeeID.") $link = $true } elseif ($approval) { Write-Log -Message ("Google: Username: " + $item.UPN + " for " + $item.personID + " has an approval from " + $approval.ApprovedDate + " but the account no longer matches it (approved: " + $approval.Account + " / " + $approval.DirectoryName + ", current: " + $item.UPN + " / " + $googleUser.Name.givenName + " " + $googleUser.Name.familyName + ") - not linked; re-approve with Approve-IDBridgeNameMismatch.") -Level Warn } else { Write-Log -Message ("Google: Username: " + $item.UPN + " for " + $item.personID + " is already taken by " + $googleUser.Name.givenName + " " + $googleUser.Name.familyName + " in Google but source name is " + $item.NameFirst + " " + $item.NameLast + " - not linked.") -Level Error } } if ($link) { $itemUpdateList[$item.personID] = [PSCustomObject]@{ ID = $googleUser.ID Groups = $googleUser.CurrentGroups SuspendedStatus = ($googleUser.Suspended -or $googleUser.Archived) User = $googleUser } } } elseif ($item.IDBActive -eq $false) { Write-Log -Message ("Google: No user found with EmployeeID: $($item.personID). Source user is inactive and has no Google account - nothing to reconcile.") -Level Trace } else { Write-Log -Message ("Google: No user found with EmployeeID: $($item.personID) - no username match; treated as new.") -Level Trace } } return $itemUpdateList } |