Hi all!
I wanted to revisit an older post I made a while ago an improve upon it! You can find that post here
Let me lay out the background to this post in case you didn’t read the original. So I had recently had an opportunity to use PowerShell to update update Azure AD attributes. This involved using the Get-AzureADUser and the Set-AzureADUser commands.
This is very much different from the local AD administration I had done in the past. However, I could still leverage this experience for Azure AD. Thankfully!
I’d never used the Get-AzureADUser command before!
I’d never used the Get-AzureADUser command before but I’m comfortable with PowerShell. And anyone comfortable with PowerShell knows that there are built in helper commands for every module.
So… my mission was this:
My first method was a little dirty, I put together a foreach loop and hardcoded the values with no error checking:
$marketingUsers = Get-AzureADUser –Filter "Department eq 'Marketing'"
foreach($user in $marketingUsers){
Set-AzureADUser –ObjectID $user `
–StreetAddress '51 River St.' `
–City 'Ridgefield' `
–State 'CT' `
–PostalCode '06877' `
–Country 'United States'
}
I know! It’s a rough method but I was just testing out the command to see if everything worked as I predicted!
There’s also no host output for each successful change so that’s fun.
What I did next was add a couple of checks to my code:
#Get all marketing users
$marketingUsers = $null
try {
$marketingUsers = Get-AzureADUser –Filter "Department eq 'Marketing'" –ErrorAction Stop
}catch{
#Output the error message if any
Write-Host "Failed to collect Marketing users!" –ForegroundColor Red
Write-Host $_.ScriptStackTrace –ForegroundColor Red
}
#Checking if there are no marketing users found
if (!$marketingUsers){
Write-Host "No Marketing users found"
return;
}
#Run through each user and update
foreach($user in $marketingUsers){
try{
Set-AzureADUser –ObjectID $user `
–StreetAddress '51 River St.' `
–City 'Ridgefield' `
–State 'CT' `
–PostalCode '06877' `
–Country 'United States' `
–ErrorAction Stop
}catch{
Write-Host "Failed to update $user" –ForegroundColor Red
Write-Host $_.ScriptStackTrace
}
}
After that, it was looking much better and I felt more comfortable actually running the code. We all know what it’s like to run code that’s meant to be a ‘test’ that accidently overwrites everyone’s profile.
Just me? Okay.
What I wanted to do next was to implement a technique called Splatting.
Splatting it a way of putting all the variables or inputs for the script or command into it’s own hash-table so that changes are easier to make further on down the line.
Nothing worse than having a command that takes in a bunch of parameters and you have to scroll across the screen to find the one you’re looking for!
Before I move onto splatting though, now is a good time to test the performance of different loop methods.
I wanted to test if using the -filter parameter was faster than piping items into a Where-Object commandlet. So I used the built in measuring tools within PowerShell:
Command | Get-AzureADUser -ErrorAction Stop | Where-Object {$_.Department -eq ‘Development’} | Get-AzureADUser -Filter “Department eq ‘Development’” -ErrorAction Stop |
#1 | 1311.6669 | 6630.8861 |
#2 | 1769.6253 | 7973.5126 |
#3 | 2122.8749 | 6060.9699 |
#4 | 1963.6512 | 5315.6691 |
#5 | 3437.268 | 5783.7616 |
Now that is just crazy to me. Using the built-in -filter parameter is more than twice as slow when compared to piping the results to a completely different command.
Now, lets move back to splatting!
I created the required hash-table to hold the values for the Set-AzureADUser command parameters.
Thankfully, this is very simple and you can see my hash-table below:
#51 River St., Ridgefield, CT 06877
#Randomly generated fake address
#New props in a hashtable for splatting
$newProps = @{
StreetAddress = '51 River St.'
City = 'Ridgefield'
State = 'CT'
PostalCode = '06877'
Country = 'United States'
}
This means I can now simplify the Set-AzureADUser command massively by just passing in the hash-table as a single parameter versus specifying them all manually.
Using Set-AzureADUser To Update Attributes
This is what my final code looked like:
#51 River St., Ridgefield, CT 06877
#New props in a hashtable for splatting
$newProps = @{
StreetAddress = '51 River St.'
City = 'Ridgefield'
State = 'CT'
PostalCode = '06877'
Country = 'United States'
}
#Get all marketing users
$marketingUsers = $null
try {
$marketingUsers = Get-AzureADUser –ErrorAction Stop | `
Where-Object {$_.Department -eq 'Marketing'}
}catch{
#Output the error message if any
Write-Host "Failed to collect Marketing users!" –ForegroundColor Red
Write-Host $_.ScriptStackTrace –ForegroundColor Red
}
#Checking if there are no marketing users found
if (!$marketingUsers){
Write-Host "No Marketing users found"
return;
}
#Running through each user
foreach ($user in $marketingUsers){
try{
Set-AzureADUser –ObjectId $user $newProps –ErrorAction Stop
}catch{
Write-Host "Failed to update $user" –ForegroundColor Red
Write-Host $_.ScriptStackTrace
}
}
I hope you enjoyed this little journey I’ve created today. And found the importance of measure commands to find the fastest route to success.
Enjoy! 🎉