[CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Path, [Parameter()] [guid] $TenantId, [Parameter()] [switch] $UpdateName ) #region Private helper functions <# .SYNOPSIS Formats a phone number .DESCRIPTION Formats a phone number into the format (123) 456-7890 Ext. 1234 Takes a 15-digit E.164 phone number .PARAMETER PhoneNumber The phone number to format #> function Format-PhoneNumber { [CmdletBinding()] param ( # The phone number to format [Parameter(Mandatory=$true,ValueFromPipeline)] [string] $PhoneNumber ) $Parts = [regex]::Matches($PhoneNumber, '^(\+\d{1,2})?[\s-]?\(?(\d{3})\)?[\s.-]?(\d{3})[\s.-]?(\d{4})(?:\s[E|e]?xt?\.?\s(\d+))?').Groups if ($Parts[5].Success) { return "($($Parts[2])) $($Parts[3])-$($Parts[4]) Ext. $($Parts[5])" } else { return "($($Parts[2])) $($Parts[3])-$($Parts[4])" } } #endregion # Connnect to Microsoft Graph for the given tenant if ($null -eq (Get-MgContext)) { if ($null -eq $TenantId) { Write-Warning "No tenant ID provided. Connecting to Microsoft Graph without tenant context." Connect-MgGraph -NoWelcome -Scopes User.ReadWrite.All, Organization.Read.All } else { Connect-MgGraph -NoWelcome -Scopes User.ReadWrite.All, Organization.Read.All -TenantId $TenantId } } else { Write-Verbose "Already connected to Microsoft Graph. Authenticated as $((Get-MgContext).Account) to tenant $((Get-MgContext).TenantId)." } # Import the list of users $Users = Import-Csv -Path $Path $Results = @() foreach ($User in $Users) { Write-Progress -Activity "Updating user $($User.Email)" -Status "Processing $($Results.Count) of $($Users.Count)" -PercentComplete (($Results.Count / $Users.Count) * 100) # Try to match up the email address of the user with a Graph user. # If it matches, return the UserId for use in later update step. try { $UserId = (Get-MgUser -Filter "Mail eq '$($User.Email)'").Id } catch { Write-Warning "User with email $($User.Email) not found in Microsoft Graph. Skipping update for this user. Error: $_" Continue } # Default properties $NewProperties = @{} if ($UpdateName) { if ($null -ne $User.GivenName -and $User.GivenName -ne '') { $NewProperties.GivenName = $User.GivenName } else { Write-Verbose "No given name provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.Surname -and $User.Surname -ne '') { $NewProperties.Surname = $User.Surname } else { Write-Verbose "No surname provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.DisplayName -and $User.DisplayName -ne '') { $NewProperties.DisplayName = $User.DisplayName } else { Write-Verbose "No display name provided for $($User.Email). Skipping update for this property." } } if ($null -ne $User.JobTitle -and $User.JobTitle -ne '') { $NewProperties.JobTitle = $User.JobTitle } else { Write-Verbose "No job title provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.Department -and $User.Department -ne '') { $NewProperties.Department = $User.Department } else { Write-Verbose "No department provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.OfficeLocation -and $User.OfficeLocation -ne '') { $NewProperties.OfficeLocation = $User.OfficeLocation } else { Write-Verbose "No office location provided for $($User.Email). Skipping update for this property." } # Format phone numbers if ($null -ne $User.BusinessPhone -and $User.BusinessPhone -ne '') { $NewProperties.BusinessPhones = @(Format-PhoneNumber -PhoneNumber $User.BusinessPhone) } else { Write-Verbose "No business phone provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.MobilePhone -and $User.MobilePhone -ne '') { $NewProperties.MobilePhone = Format-PhoneNumber -PhoneNumber $User.MobilePhone } else { Write-Verbose "No mobile phone provided for $($User.Email). Skipping update for this property." } if ($null -ne $User.FaxNumber -and $User.FaxNumber -ne '') { $NewProperties.FaxNumber = Format-PhoneNumber -PhoneNumber $User.FaxNumber } else { Write-Verbose "No fax number provided for $($User.Email). Skipping update for this property." } # Update Graph user Entra properties Update-MgUser -UserId $UserId @NewProperties $NewProperties.Id = $UserId $Results += [PsCustomObject]$NewProperties } # $Results | sort OfficeLocation,DisplayName | select Id,DisplayName,License,JobTitle,@{Label='BusinessPhone';Expression={$_.BusinessPhones[0]}},MobilePhone,FaxNumber,CompanyName,OfficeLocation | Out-GridView $Results | Sort-Object OfficeLocation,DisplayName | Select-Object Id,DisplayName,License,JobTitle,@{Label='BusinessPhone';Expression={$_.BusinessPhones[0]}},MobilePhone,FaxNumber,CompanyName,OfficeLocation | Export-Csv -Path results.csv -NoTypeInformation