CSV

PowerShell – Getting M365 Tenant ID From Domain List

It’s been a while since I’ve broken out PowerShell to solve a problem, but a scenario came up where I thought I could automate something I needed to do – look up a bunch of Microsoft 365 Tenant IDs based on domain names. Here’s how I tackled it:

First, I actually had a list of email addresses and just wanted the domain of each one. The list was in Excel so that’s easy enough – using the Text to Columns feature I selected the data, used the ‘Delimited’ option under Original data type then pressed Next:

Then on the next step, changed the Delimiters from the default ‘Tab’ to ‘Other’ and put the @ symbol on, and as you can see in the Data preview it takes the alias off the email address for the first column, and leaves the domain in the second:

Clicking ‘Finish’ gave me a column full of domains. From this, I created a header for each row (alias and domain):

And then in Excel went to File > Save As > and called the file ‘addresses’ while picking CSV from the dropdown:

Easy enough. From here, I knew I’d need to feed this data into PowerShell using the Import-CSV command, but first I wanted to work out what the one liner command was to get a M365 Tenant ID…. except I couldn’t find one. All the examples were how to find your own M365 Tenant ID after authenticating. I knew it was public and easily accessible since sites like https://whatismytenantid.com/ work great but only accept one domain at a time.

I ended up finding a Function written by Daniel Bradley which was fairly simple and using an API, with the core of it being this one line:

Invoke-RestMethod -UseBasicParsing -Uri "https://odc.officeapps.live.com/odc/v2.1/federationprovider?domain=$domain"

Swapping the $domain variable with an actual domain and piping to just selecting tenantid

Invoke-RestMethod -UseBasicParsing -Uri "https://odc.officeapps.live.com/odc/v2.1/federationprovider?domain=microsoft.com" | select tenantid

tenantId
--------
72f988bf-86f1-41af-91ab-2d7cd011db47

Alright, we should be able to put this all together. Set the $file variable as the imported CSV file, then for each domain record run the Invoke-RestMethod command using the current $record.

Except that didn’t work because I forgot the $record is the entire object and not just the domain membertype. To specify that, we just use $record.domain so the pure domain is used.

Except that didn’t work either and I don’t know why. Instead, I just made a new variable from the $record.domain and called that $newdomain, then referenced THAT in the Invoke-Restmethod line.

That did work, so I could then echo out the results of both the current $newdomain variable, and the newly looked up $result and again specifying the membertype of tenantid (as a bunch of other info gets looked up with that command).

I also then wanted to export this data back out to a new CSV, in this case one called ‘myfile.csv’. Again, I have to work around membertypes so just make a new variable containing the single tenantid line, and use the >> operator to create/append to a file:

$file = import-csv c:\temp\addresses.csv

foreach ($record in $file){
        $newdomain = $record.domain
    $result = Invoke-RestMethod -UseBasicParsing -Uri "https://odc.officeapps.live.com/odc/v2.1/federationprovider?domain=$newdomain"
$newtenantid= $result.tenantid
echo $newdomain $result.tenantid
"$newdomain,$newtenantid" >> c:\temp\myfile.csv
}

Works perfectly and I end up with a CSV that has a column of domains, and a column of Tenant IDs. If a domain had no Tenant ID then that value will be blank.

I’m sure this could be written better, but for quick occasional tasks for yourself, you just need something that works.

Azure AD B2B PowerShell Invites

I’ve written about Azure AD B2B before, as well as then giving those invited users access to SharePoint Online, but there’s been a lot of changes since I started using it. Have a read of my original article if you’re interested to see how I’m using B2B and why.

Azure AD B2B is still in preview, but in Feb 2017 a bunch of improvements were added. Part of these changes were around using the new Azure portal rather than the Classic Portal, and with that is the removal of inviting users via CSV file and uploading it to Azure AD. This was exactly the way I was using it, so I had to change to one of the newer methods.

Although CSV support is gone, it’s been replaced by PowerShell which can just call the same CSV file being used before, so it’s not a huge change. There’s a PowerShell example on this technet page which shows how to do it. There is a catch though, the ability to add the user to groups as part of the import is gone.

The other big change that impacted me was the invitation emails. This is the email that gets sent to the recipient when being invited – it was originally a plain text email from a generic Microsoft address, but it’s now changed to a much more professional looking email. The catch with this is, rather than coming from a generic Microsoft email account, it now comes from the user that sends the invites out. I found this out the hard way when invited parties started seeing my details and photo with the invite!

There’s four approaches I can come up with around this new invite method –

1. Leave it as showing the admin user who does the invites (not ideal)

2. Create and use a seperate service account for these invites, so it comes from a generic looking internal email address (quite good)

3. Get the users themselves to send the invites out – by default, all users have access to invite others to their tenant (worst option, users won’t do this themselves, need training and support, can’t automate)

4. Use APIs and send the invites out on behalf of the user (‘best’ option but requires the most work, most complex)

While I look at option 4, option 2 is a good middle ground and will probably do for most companies.

I’ve written and tested the below script, which works on a single user by user basis. This uses just the Azure AD Preview module for PowerShell, which is at version 2.0.0.85 at the time of writing. To use the method mentioned on that page to install, I had to first install Windows Management Framework 5.0.

$group = get-azureadgroup -SearchString "Put your exact search string here" | where {$_.dirsyncenabled -eq $null}
$newuser = New-AzureADMSInvitation -InvitedUserEmailAddress [email protected] -InvitedUserDisplayName "Full Name" -sendinvitationmessage $true -InviteRedirectUrl "http://myapps.microsoft.com"
Add-AzureADGroupMember -objectid $group.objectid -RefObjectId $newuser.InvitedUser.Id

This script requires you to first authenticate against Azure AD with the command connect-azuread : the same way you’d use connect-msol for Office 365. More on how to automate that part in an upcoming blog post.

I’ve written this on the basis that you already have a group to add the guest user into, which gives them the permissions required after being invited into your Azure AD tenant. It’s also more a proof of concept script, which shows how to automate these steps enough to then be able to do what you want with it – such as wrap it around a ‘for each’ and feed multiple users into it.

The first thing the script does is get the group name. As objects in Azure AD don’t have to have unique names like on-prem Active Directory, this script will fail if it finds multiple results the same. It’s also making sure the result that comes back is only a cloud based group, because you can only add B2B invited users into Azure AD groups (not ones synced from on-prem).

Next it will send out the invite to the user. This is the important part. If you don’t want an email to go out, you can change the -sendinvitationmessage value to $false.

Finally we’re adding the invited user into the group by ObjectIDs of each object – straight forward.

—-

The end result is a user who will be able to accept their invite, log in and have access to whatever they need to. Note that the way I do this is by having an app and advertising it to the group that also gives permissions to SharePoint Online, so they’ll see the single link on their myapps.microsoft.com page.

If you’re mucking about with Azure AD B2B this should give you somewhere to start. The Microsoft Technet pages for Azure AD are very comprehensive now as well as being easy to read, so check them out.

If you have any questions on Azure AD B2B feel free to ask!

Update 23rd August 2017

I’ve now gotten around to making a mass invite script. I used Eric Schrader’s script, and made some of my own modifications.

It will pick up a file in the same path as the script called azure_ad_b2b.csv which needs to be comma delimited with just “InvitedUserEmailAddress,Name”

It will also prompt for the group name which you want to add invitees to, and bomb out if you get more or less than 1 result (because display names aren’t unique fields in Office 365)

Another prompt is for the project URL, which is where you want invitees to be sent to (which for me, is usually a SharePoint Online site). It’s also set to send the invites out from a generic service account, so change “[email protected]” in the send-mailmessage line to whatever you’re sending as. Feel free to ask any questions!

#1.) Install Azure AD PS module – https://www.powershellgallery.com/packages/AzureADPreview

#2.) provide O365 tenant admin cred

$cred = Get-Credential

Connect-AzureAD -Credential $cred

#2.second cred for O365 email account (merge var with above if for non-demo O365 tenant)

$adminemailcred = get-credential [email protected]

$groupname = Read-Host -Prompt 'Input the Group Name to add users to e.g. SharePoint Online XXX Portal External Full'

$project = Read-Host -Prompt 'Input the project name, 1 word e.g. TestSite'

#2.External User Security Group ID

$group = get-azureadgroup -SearchString $groupname | where {$_.dirsyncenabled -eq $null}

if ($group.count -ne 1) {echo "Not Exactly One Group Found"; break}

$projecturl = Read-host -Prompt 'Input the project URL XXX for https://yourdomain.sharepoint.com/XXX'

#3 import CSV, update url and csv location below.

$invitations = import-csv azure_ad_b2b.csv

foreach ($email in $invitations) {

$result= New-AzureADMSInvitation -InvitedUserEmailAddress $email.InvitedUserEmailAddress -InvitedUserDisplayName $email.Name -InviteRedirectUrl $projecturl -InvitedUserMessageInfo $messageInfo -SendInvitationMessage $false

$inviteurl = $result.InviteRedeemUrl

$userid = $result.InvitedUser.Id

#automatically add the new user to your Security Group

Add-AzureADGroupMember -objectid $group.objectid -RefObjectId $userid

#send the user a custom email from your Office 365 tenant. Supports HTML.

Send-MailMessage -To $result.InvitedUserEmailAddress -from [email protected] -Subject ‘Invitation to the $project ’ -Body “<h1>Congrats!</h1><br><strong>This is your invite</strong><br><br>Here:<br>$inviteurl <br>For <strong>help</strong>, contact [email protected]” -BodyAsHtml -smtpserver smtp.office365.com -usessl -Credential $adminemailcred -Port 587

}