In Part 4, we created our basic Get-MITUser function, which accepts a single $Identity
parameter, and will obtain both the MsolUser and Mailbox (assuming they exist). Now it’s time to test with some real fake data – in particular we need to test with edge cases, and refine the function to work with them.
Maybe it’s just me, but it turns out that making up edge cases is hard! I consider uniformity a very core best practice of an Office 365 / Exchange Online environment. There are plenty of businesses out there with non-uniformity (some for good reasons, some not); but it is difficult to create a non-uniform environment yourself just for the sake of it.
I made a CSV file with user data – a mixture of consistent and inconsistent data, some users sharing values with other users, either in the same field (DisplayName) or different fields (DisplayName vs Alias).
FirstName,LastName,DisplayName,UserPrincipalName,NeedsMailbox,Alias,EmailAddress,Notes Vicki,Marsh,Vicki Marsh,Vicki@milneitlab01.onmicrosoft.com,TRUE,Vicki,Vicki@milneitlab01.onmicrosoft.com,Normal user with mailbox Roy,Hitchcock,Roy Hitchcock,Roy@milneitlab01.onmicrosoft.com,FALSE,,,Normal user without mailbox Brady,Tyree,Brady Tyree,Brady@milneitlab01.onmicrosoft.com,TRUE,Brady,Brady@milneitlab01.onmicrosoft.com,Normal user with mailbox Brady,,Brady,Brady2@milneitlab01.onmicrosoft.com,TRUE,Brady2,Brady2@milneitlab01.onmicrosoft.com,User with no last name; display name identical to another's Alias Sandra,Martinez,Sandra Martinez,Sandra@milneitlab01.onmicrosoft.com,TRUE,Sandra,Sandra@milneitlab01.onmicrosoft.com,Normal user with mailbox Sandra,Martinez,Sandra Martinez,Sandra2@milneitlab01.onmicrosoft.com,TRUE,Sandra2,Sandra2@milneitlab01.onmicrosoft.com,User with same first and last name as another Sandra,Phillips,Sandra Phillips,Sandra3@milneitlab01.onmicrosoft.com,TRUE,SandraP,SandraP@milneitlab01.onmicrosoft.com,User with non-matching UPN and Email Address Mary,Johnson,Mary Johnson,Mary@milneitlab01.onmicrosoft.com,TRUE,Mary,MaryJohnson@milneitlab01.onmicrosoft.com,Alias does not match email prefix Will,Richard,Will Richard,Will@milneitlab01.onmicrosoft.com,FALSE,,,Normal user without mailbox Will,Cook,Will Cook,Will2@milneitlab01.onmicrosoft.com,TRUE,Will,Will@milneitlab01.onmicrosoft.com,EmailAddress is identical to another user's UserPrincipalName
(Side note: There was one edge case I thought of that it turns out isn’t possible on Office 365. I wanted the UserPrincipalName of one user to be the PrimarySmtpAddress of another. This is possible if the first user does not have a mailbox / Exchange Online licence, but it is not possible if both users have mailboxes.
It turns out that Office 365 forces a user’s UserPrincipalName to also be one of its email addresses. It doesn’t have to be primary, but it has to be present as an email address. If you try to delete it (whether in the Office 365 Portal, Exchange Admin Center, or Exchange Online PowerShell) it will “delete” without error, but check again and it’s still there.
Obviously email addresses are required to be globally unique, so I couldn’t add this email address to a second user. I am fairly certain that there is no such constraint between AD users and Exchange on-premises mailboxes; this is between Msol users and Exchange Online mailboxes.)
I imported the users using the following quick-and-dirty script.
# Connect to Office 365 and Exchange Online PowerShell if not already. if (-not $global:MilneITLabConnected365) { $Credential = Get-Credential Connect-MsolService -Credential $Credential $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection Import-PSSession $Session $global:MilneITLabConnected365 = $true } # The licence we will be assigning. $AccountSkuId = "milneitlab01:ENTERPRISEPACK" # A licence options object with Exchange disabled, for certain users. $ExchangeDisabled = New-MsolLicenseOptions -AccountSkuId $AccountSkuId -DisabledPlans "EXCHANGE_S_ENTERPRISE" # Import the users. $Users = Import-Csv "Users.csv" # Create MsolUsers $Users | ForEach-Object { Write-Host ('Creating MsolUser for {0}' -F $_.DisplayName) $MsolUser = New-MsolUser -FirstName $_.FirstName -LastName $_.LastName -DisplayName $_.DisplayName -UserPrincipalName $_.UserPrincipalName -UsageLocation 'GB' $_ | Add-Member -Force -MemberType NoteProperty -Name Guid -Value $MsolUser.ObjectId.Guid } # Export to CSV with GUIDs, in case we need them. $Users | Export-Csv "Users-WithGuid.csv" -NoTypeInformation # License the users $Users | ForEach-Object { if ($_.NeedsMailbox -eq $true) { Write-Host ('Adding licence for {0}' -F $_.DisplayName) Set-MsolUserLicense -ObjectId $_.Guid -AddLicenses $AccountSkuId } else { Write-Host ('Adding licence for {0} (no Exchange)' -F $_.DisplayName) Set-MsolUserLicense -ObjectId $_.Guid -AddLicenses $AccountSkuId -LicenseOptions $ExchangeDisabled } } Write-Host "Waiting 5 minutes for the mailboxes to be created..." Start-Sleep -Seconds 300 # Set their Exchange properties $Users | Where-Object NeedsMailbox -eq $true | ForEach-Object { Write-Host ('Setting Mailbox for {0}' -F $_.DisplayName) $EmailAddresses = 'SMTP:{0}' -F $_.EmailAddress Set-Mailbox -Identity $_.Guid -Alias $_.Alias -EmailAddresses $EmailAddresses }
Let’s now test our existing Get-MITUser command. First, an Msoluser with a mailbox:
PS> Get-MITUser -Identity Vicki@milneitlab01.onmicrosoft.com DisplayName : Vicki Marsh UserPrincipalName : Vicki@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Vicki@milneitlab01.onmicrosoft.com ObjectId : fe491646-d83c-4043-a6a5-d40b0a3075eb MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Vicki Marsh MailboxFound : True MailboxError : PS> Get-MITUser -Identity "Vicki Marsh" DisplayName : Vicki Marsh UserPrincipalName : Vicki@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Vicki@milneitlab01.onmicrosoft.com ObjectId : fe491646-d83c-4043-a6a5-d40b0a3075eb MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Vicki Marsh MailboxFound : True MailboxError : PS> Get-MITUser -Identity "Vicki" DisplayName : Vicki Marsh UserPrincipalName : Vicki@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Vicki@milneitlab01.onmicrosoft.com ObjectId : fe491646-d83c-4043-a6a5-d40b0a3075eb MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Vicki Marsh MailboxFound : True MailboxError : PS>
That’s all good. Now, an Msoluser without a mailbox.
PS> Get-MITUser -Identity "Roy@milneitlab01.onmicrosoft.com" DisplayName : Roy Hitchcock UserPrincipalName : Roy@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Roy@milneitlab01.onmicrosoft.com ObjectId : 3795c0c9-0436-433c-8bbe-0255ab7fb4b0 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : MailboxFound : False MailboxError : The operation couldn't be performed because object '3795c0c9-0436-433c-8bbe-0255ab7fb4b0' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. PS> Get-MITUser -Identity "Roy Hitchcock" Unable to find user Roy Hitchcock. MsolUserError: User Not Found. User: Roy Hitchcock. MailboxError: The operation couldn't be performed because object 'Roy Hitchcock' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. At C:\Users\Ryan\OneDrive\Scripts\Milne.IT\PowerShell\Modules\MilneIT\MilneIT.psm1:156 char:9 + throw $ErrorText + ~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Unable to find ...D.OUTLOOK.COM'.:String) [], RuntimeException + FullyQualifiedErrorId : Unable to find user Roy Hitchcock. MsolUserError: User Not Found. User: Roy Hitchcock. MailboxError: The operation couldn't be performed because object 'Roy Hitchcock' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. PS> Get-MITUser -Identity "Roy" Unable to find user Roy. MsolUserError: User Not Found. User: Roy. MailboxError: The operation couldn't be performed because object 'Roy' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. At C:\Users\Ryan\OneDrive\Scripts\Milne.IT\PowerShell\Modules\MilneIT\MilneIT.psm1:156 char:9 + throw $ErrorText + ~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Unable to find ...D.OUTLOOK.COM'.:String) [], RuntimeException + FullyQualifiedErrorId : Unable to find user Roy. MsolUserError: User Not Found. User: Roy. MailboxError: The operation couldn't be performed because object 'Roy' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. PS>
This is also working as expected. As there is no Mailbox, and Get-MsolUser only accepts UserPrincipalNames and ObjectIds. It’s not going to find the user by Alias or DisplayName. (Perhaps in the future we will use Get-MsolUser’s -SearchString
parameter to allow Get-MITUser to accept DisplayNames, but not now.)
Let’s have a look at Brady. Both Brady’s have unique UPNs and email addresses. However Brady Tyree’s Alias matches the other Brady’s DisplayName.
PS> Get-MITUser -Identity "Brady@milneitlab01.onmicrosoft.com"
DisplayName : Brady Tyree
UserPrincipalName : Brady@milneitlab01.onmicrosoft.com
PrimarySmtpAddress : Brady@milneitlab01.onmicrosoft.com
ObjectId : 41c11d5c-0161-4aef-bef3-7c20cd80bec2
MsolUser : Microsoft.Online.Administration.User
MsolUserFound : True
MsolUserError :
Mailbox : Brady Tyree
MailboxFound : True
MailboxError :
PS> Get-MITUser -Identity "Brady2@milneitlab01.onmicrosoft.com"
DisplayName : Brady
UserPrincipalName : Brady2@milneitlab01.onmicrosoft.com
PrimarySmtpAddress : Brady2@milneitlab01.onmicrosoft.com
ObjectId : 379ef9e5-918d-44a6-b8a9-5ac7cd727975
MsolUser : Microsoft.Online.Administration.User
MsolUserFound : True
MsolUserError :
Mailbox : Brady
MailboxFound : True
MailboxError :
PS> Get-MITUser -Identity "Brady Tyree"
DisplayName : Brady Tyree
UserPrincipalName : Brady@milneitlab01.onmicrosoft.com
PrimarySmtpAddress : Brady@milneitlab01.onmicrosoft.com
ObjectId : 41c11d5c-0161-4aef-bef3-7c20cd80bec2
MsolUser : Microsoft.Online.Administration.User
MsolUserFound : True
MsolUserError :
Mailbox : Brady Tyree
MailboxFound : True
MailboxError :
PS> Get-MITUser -Identity "Brady"
GetMsolUser2 : Cannot process argument transformation on parameter 'Identity'. Cannot convert value to type System.String.
At C:\Users\Ryan\OneDrive\Scripts\Milne.IT\PowerShell\Modules\MilneIT\MilneIT.psm1:136 char:47
+ ... GetMsolUser2 -Identity $MailboxObj.Mailbox.ExternalDirectoryObjectId
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [GetMsolUser2], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,GetMsolUser2
DisplayName : {Brady Tyree, Brady}
UserPrincipalName : {Brady@milneitlab01.onmicrosoft.com, Brady2@milneitlab01.onmicrosoft.com}
PrimarySmtpAddress : {Brady@milneitlab01.onmicrosoft.com, Brady2@milneitlab01.onmicrosoft.com}
ObjectId : {41c11d5c-0161-4aef-bef3-7c20cd80bec2, 379ef9e5-918d-44a6-b8a9-5ac7cd727975}
MsolUser : Microsoft.Online.Administration.UserExtended
MsolUserFound : False
MsolUserError : User Not Found. User: Brady.
Mailbox : {Brady Tyree, Brady}
MailboxFound : True
MailboxError :
PS>
Uh-oh, this didn’t go as planned. It’s sort of combined the two users together, and not in a way we can use. We will need to fix this.
To start with, let’s see what happens if we run Get-Mailbox with the same identity:
PS> Get-Mailbox -Identity Brady Name Alias ServerName ProhibitSendQuota ---- ----- ---------- ----------------- Brady Brady loxp123mb1062 99 GB (106,300,440,576 bytes) Brady2 Brady2 mmxp123mb0062 99 GB (106,300,440,576 bytes)
Get-Mailbox is working absolutely fine. How about our internal GetMailbox2 function?
PS> GetMailbox2 -Identity Brady Mailbox MailboxFound MailboxError ------- ------------ ------------ {Brady Tyree, Brady} True PS> GetMailbox2 -Identity Brady | Select -ExpandProperty Mailbox Name Alias ServerName ProhibitSendQuota ---- ----- ---------- ----------------- Brady Brady loxp123mb1062 99 GB (106,300,440,576 bytes) Brady2 Brady2 mmxp123mb0062 99 GB (106,300,440,576 bytes) PS> (GetMailbox2 -Identity Brady).Mailbox.Count 2 PS>
This also works fine. Sure it puts both Mailboxes in the Mailbox property, but this isn’t a problem; we can extract them individually.
The issue is that our Get-MITUser function was not written with consideration to GetMailbox2 returning multiple users. (Or Get-MsolUser for that matter, but Get-MsolUser will only return a single user when using -UserPrincipalName
or -ObjectId
, as these values are unique within the tenant).
In Part 4, I posed the question “How do we want to handle these? Should we error? Output multiple results?”. After some thought, it makes sense that we output multiple results, just like Get-Mailbox does. If the end-user doesn’t want multiple results from Get-MITUser, it’s simple for them to check the output (e.g. the Count property) and handle as desired.
This will require a redesign of our function. Remember our flow chart in Part 1? This redesign changes that a fair bit, to say the least.
First, we are going to split off the code at the end of the Get-MITUser cmdlet into an internal function NewMITUserObj, as we are going to call it multiple times.
Function NewMITUserObj { [cmdletbinding()] Param( $MsolObj, $MailboxObj ) # Obtain key properties where we prefer the MsolUser if ($MsolObj.MsolUserFound) { $DisplayName = $MsolObj.MsolUser.DisplayName $UserPrincipalName = $MsolObj.MsolUser.UserPrincipalName $ObjectId = $MsolObj.MsolUser.ObjectId } elseif ($MailboxObj.MailboxFound) { $DisplayName = $MailboxObj.Mailbox.DisplayName $UserPrincipalName = $MailboxObj.Mailbox.UserPrincipalName $ObjectId = $MailboxObj.Mailbox.ExternalDirectoryObjectId } #end elseif # Obtain key properties where we prefer the Mailbox if ($MailboxObj.MailboxFound) { $PrimarySmtpAddress = $MailboxObj.Mailbox.PrimarySmtpAddress } elseif ($MsolObj.MsolUserFound) { # Return the email address that begins with SMTP (case sensitive) $PrimarySmtpAddress = $MsolObj.MsolUser.ProxyAddresses | ForEach-Object { if ($_ -cmatch '^SMTP:(.*)$') { $Matches[1] } #end if } #end Foreach-Object } #end elseif [pscustomobject]@{ DisplayName = $DisplayName UserPrincipalName = $UserPrincipalName PrimarySmtpAddress = $PrimarySmtpAddress ObjectId = $ObjectId MsolUser = $MsolObj.MsolUser MsolUserFound = $MsolObj.MsolUserFound MsolUserError = $MsolObj.MsolUserError Mailbox = $MailboxObj.Mailbox MailboxFound = $MailboxObj.MailboxFound MailboxError = $MailboxObj.MailboxError } #end [pscustomobject] } #end Function NewMITUserObj
In our redesigned Get-MITUser function, the first thing we try to do is obtain both MsolUser and Mailbox from the given $Identity. If we turn up empty, we can error out right away.
Function Get-MITUser { [cmdletbinding()] Param( [string] $Identity ) # An empty array we will use to store and then output all combined objects. $MITUsers = @() # Try to get both the MsolUser and Mailbox from the provided $Identity. $MsolObj = GetMsolUser2 -Identity $Identity $MailboxesObj = GetMailbox2 -Identity $Identity # If neither are found, we can throw right away. if ( (-not $MsolObj.MsolUserFound) -and (-not $MailboxesObj.MailboxFound) ) { Write-Debug '[Get-MITUser] Neither MsolUser nor Mailbox found.' $ErrorText = "Unable to find user $Identity.`nMsolUserError: {0}`nMailboxError: {1}" -F $MsolObj.MsolUserError,$MailboxesObj.MailboxError throw $ErrorText }
After this, we now loop through each mailbox and try to match the MsolUser we obtained (if we DID obtain it, that is). If we match, then we create our combined MITUser object and add it to the array. If we don’t match, we obtain the MsolUser from the Mailbox’s ExternalDirectoryObjectId, and again create a combined MITUser object and add it to the array.
(If we didn’t obtain any mailboxes that’s fine too – the foreach loop just doesn’t execute at all.)
# Now we go through each Mailbox, try matching with the MsolUser we (may) have # and failing that, see if it corresponds to another MsolUser. $MsolMailboxMatchFound = $false foreach ($Mailbox in $MailboxesObj.Mailbox) { Write-Debug ('[Get-MITUser] Mailbox: {0}.' -F $Mailbox.ExternalDirectoryObjectId) $MailboxObj = [pscustomobject]@{ Mailbox=$Mailbox MailboxFound=$true MailboxError=$null } <# If $MsolObj.MsolUser.ObjectId.Guid does not exist, referencing it would cause an error if StrictMode is set in PowerShell. $MsolObj.MsolUser.ObjectId.Guid will definitely be set if $MsolObj.MsolUserFound is true. PowerShell processes boolean operators from left to right. If $MsolObj.MsolUserFound is $false, it does not process past the first -and because it knows the result must be $false. This prevents any StrictMode errors. #> $MsolMailboxMatch = $MsolObj.MsolUserFound -and ($MsolObj.MsolUser.ObjectId.Guid -eq $Mailbox.ExternalDirectoryObjectId) if ($MsolMailboxMatch) { # We have matched, so create the MITUser object and add it to our final output. Write-Debug ('[Get-MITUser] Mailbox {0} matched with MsolUser.' -F $Mailbox.ExternalDirectoryObjectId) $MITUsers += NewMITUserObj -MsolObj $MsolObj -MailboxObj $MailboxObj $MsolMailboxMatchFound = $true } else { Write-Debug ('[Get-MITUser] Mailbox did not match with MsolUser. Obtaining MsolUser using {0}' -F $Mailbox.ExternalDirectoryObjectId) # We have not matched, so see if we can find an MsolUser for this mailbox. $LoopMsolObj = GetMsolUser2 -Identity $MailboxObj.Mailbox.ExternalDirectoryObjectId $MITUsers += NewMITUserObj -MsolObj $LoopMsolObj -MailboxObj $MailboxObj } #end else } #end foreach ($MailboxObj in $MailboxesObj)
Now, if we had obtained an MsolUser originally, and did not match it with a Mailbox, we obtain the Mailbox from the MsolUser’s ObjectId.
if ($MsolObj.MsolUserFound -and ($MsolMailboxMatchFound -eq $false) ) { Write-Debug ('[Get-MITUser] MsolUser found but did not match any Mailbox. Obtaining Mailbox using {0}.' -F $MsolObj.MsolUser.ObjectId) $MailboxObj = GetMailbox2 -Identity $MsolObj.MsolUser.ObjectId $MITUsers += NewMITUserObj -MsolObj $MsolObj -MailboxObj $MailboxObj }
After that, we just output our list of users.
$MITUsers } #end Function Get-MITUser
Now let’s try this with Brady:
PS> Get-MITUser -Identity Brady DisplayName : Brady Tyree UserPrincipalName : Brady@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Brady@milneitlab01.onmicrosoft.com ObjectId : 41c11d5c-0161-4aef-bef3-7c20cd80bec2 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Brady Tyree MailboxFound : True MailboxError : DisplayName : Brady UserPrincipalName : Brady2@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Brady2@milneitlab01.onmicrosoft.com ObjectId : 379ef9e5-918d-44a6-b8a9-5ac7cd727975 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Brady MailboxFound : True MailboxError : PS> Get-MITUser -Identity "Brady@milneitlab01.onmicrosoft.com" DisplayName : Brady Tyree UserPrincipalName : Brady@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Brady@milneitlab01.onmicrosoft.com ObjectId : 41c11d5c-0161-4aef-bef3-7c20cd80bec2 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Brady Tyree MailboxFound : True MailboxError : PS> Get-MITUser -Identity "Brady2@milneitlab01.onmicrosoft.com" DisplayName : Brady UserPrincipalName : Brady2@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Brady2@milneitlab01.onmicrosoft.com ObjectId : 379ef9e5-918d-44a6-b8a9-5ac7cd727975 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Brady MailboxFound : True MailboxError : PS>
Brilliant, it gives us both Bradys (Bradies?), as one matches by DisplayName and the other matches by Alias. But, if we instead try it with something specific to just one Brady, it just gives us the one Brady.
Let’s try with our Wills now. Will Richard does not have a Mailbox, Will Cook does. Will Richard’s UPN is the same as Will Cook’s Email Address.
PS> Get-MITUser -Identity Will DisplayName : Will Cook UserPrincipalName : Will2@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Will@milneitlab01.onmicrosoft.com ObjectId : 709f2ce8-4cbd-4f5d-b0b6-dc56f337c753 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Will Cook MailboxFound : True MailboxError : PS> Get-MITUser -Identity Will@milneitlab01.onmicrosoft.com DisplayName : Will Cook UserPrincipalName : Will2@milneitlab01.onmicrosoft.com PrimarySmtpAddress : Will@milneitlab01.onmicrosoft.com ObjectId : 709f2ce8-4cbd-4f5d-b0b6-dc56f337c753 MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : Will Cook MailboxFound : True MailboxError : DisplayName : Will Richard UserPrincipalName : Will@milneitlab01.onmicrosoft.com PrimarySmtpAddress : ObjectId : d5bffab9-3855-44d2-82ab-4b75ba62e67a MsolUser : Microsoft.Online.Administration.User MsolUserFound : True MsolUserError : Mailbox : MailboxFound : False MailboxError : The operation couldn't be performed because object 'd5bffab9-3855-44d2-82ab-4b75ba62e67a' couldn't be found on 'MMXP123A001DC01.GBRP123A001.PROD.OUTLOOK.COM'. PS>
Again, as expected. If we ask for “Will Cook”, we get Will Cook as that’s his DisplayName. If we ask for “Will@milneitlab01.onmicrosoft.com”, we get Will Richard (it’s his UPN) and Will Cook (it’s his PrimarySmtpAddress). Will Richard has a MailboxError, which is entirely as expected as he doesn’t have a mailbox.
And of course, all of the commands we ran with our old function for Vicki and Roy still work exactly the same.
The full MilneIT.psm1 file as of this blog post can be viewed on Bitbucket here. You can always view the latest version of the full repository here.
In the next part, we will modify the default formatting of the Get-MITUser function to be more visually useful.