B2B

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

}

Azure Active Directory – Assigning Groups to Applications in PowerShell

Azure Active Directory Applications have been around for a while, but it’s I’ve found it hard to find good information on them beyond the biggest benefit of Marketplace Apps.

Along with my Azure AD B2B journey (still in preview at time of writing), the option of pushing out something like a SharePoint Online site as an app is one of the jigsaw pieces required to make the whole B2B process work – as a version of the apps page is displayed as the default link to anyone who accepts an Azure AD B2B invite and logs in for the first time.

MyApps – an externally invited user will only see the apps they have access to (by default, none)

I’m trying to gloss over details here, as there’s a lot of steps with different parts of the Microsoft world to get a process automated end to end for inviting external users to a SharePoint Online site – but the last step of assigning a user or group to an application has no documentation I could find, that showed how to achieve this via PowerShell.

All I want to do here, is create an Application in Azure AD, then assign a group to it. Members of the group will then see the application on MyApps.

Two different modules are required – Azure Active Directory V2 PowerShell module and Azure Resource Manager.

What we can do with these two modules is first create the application with the New-AzureRMADApplication command:

New-AzureRmADApplication -DisplayName "SharePoint Online Site A" -HomePage "https://contoso.sharepointonline.com/sitea" -IdentifierUris "https://contoso.sharepointonline.com/sitea"

Easy, now you have an application that will point to the URL entered in Azure Active Directory. Assigning a group to it is a bit trickier…

First, a few values need to be obtained:

$app = Get-AzureRmADApplication | where displayname -eq "SharePoint Online Site A"
$appid = $app.ApplicationId
$fullgroup = get-msolgroup -all | where displayname -eq "SharePoint Online Site A"

This is getting the two objects as variables – the Application itself, and the group that you want to add onto it.

Then a new Service Principal needs to be created based on the Application, as this is required when adding the group onto the application:

New-AzureADServicePrincipal -AppId $appid

Another variable is needed, which is the new Service Principal we just created:

$servicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$appId'"

Finally, we can assign the group to the application:

New-AzureADGroupAppRoleAssignment -objectid $fullgroup.objectid -principalid $fullgroup.objectid -resourceid $serviceprincipal.objectid -id ([Guid]::Empty)

You can check that this has applied by the Azure Active Directory portal too, by going to your Active Directory section, choosing ‘Applications’ and finding your app, then go into ‘users and groups’ and find the group. You should see a ‘yes’ in the assigned field.

If there’s any interest in documenting the entire SharePoint Online and Azure AD B2B invite process and script, let me know. It’s a great way of sharing data with clients via a portal.

Update 15th June 2017

Microsoft made a change with the IdentifierURI field, which is also called AppID if you view it in the Azure portal. Previously, it could be any unique URL, it just has to be unique amongst your apps (as to why it has to be a URL at all, I couldn’t get an answer on). Now, it can be anything as long as it’s not sharepoint.com or dynamics.com as they’ve reserved those for other reasons. My example above, and what I’d been using in production was variants of sharepoint.com – as the unique URI might as well be the actual URL of the site. If you use a URL that’s not allowed anymore, you’ll get the error:

New-AzureRMADApplication : Operation returned an invalid status code ‘BadRequest’

AzureAD – Assign Application to User via PowerShell

Scenario:

You’ve created an application in Azure AD, and want to script allocating access to the app rather than using the web interface. App show up at https://myapps.microsoft.com

Azure AD Premium is required for group access which would be ideal, but if you don’t have that you’ll need to add access on a user by user basis.

Answer:

PowerShell of course. First, you’ll need Azure AD for PowerShell (Preview version 2.0.0.17 at time of writing).

The below script which I modified from Philippe’s comment here should cover both internal, cloud and B2B invited users. The original script was using -objectid rather than -searchstring which works better and is more accurate for the internal and cloud accounts, but doesn’t work at all for B2B accounts.

The AppID can be obtained from this command:

Get-AzureADApplication -SearchString “Display Name for App”

Put the corresponding AppID into the below script, and you’re good to go. You’ll get prompted for Azure AD credentials as per usual. You can also get this

This is designed for a single user addition, but you could easily import the email addresses from a CSV file, and do a ‘for each’ on each entry like I did here.

# The UserPrincipalName or ObjectId of the user
  $userId = "[email protected]"

# The AppId (a.k.a. "client ID") of the app to assign the user to
  $appId = "AppIDGoesHere"

# Connect to Azure AD
  Connect-AzureAD -Confirm

# Get the user to be added
  $user = Get-AzureADUser -searchstring $userId

# Get the service principal for the app you would like to assign the user to
  $servicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$appId'"

# Create the app role assignment
 new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id ([Guid]::Empty)

 

Note: If you try this and get the error below, it’s because the app is already assigned.

new-AzureADUserAppRoleAssignment : Error occurred while executing NewUserAppRoleAssignment
StatusCode: BadRequest
ErrorCode: Request_BadRequest
Message: One or more properties are invalid.
At Z:\script.ps1:17 char:1
+ new-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId `
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-AzureADUserAppRoleAssignment], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.AzureAD16.Client.ApiException,Microsoft.Open.AzureAD16.PowerShell.NewUser
AppRoleAssignment

Azure AD B2B

Azure AD B2B has been a lifesaver for me, in giving external clients access to SharePoint Online portals.

There’s a great TechNet article on how it works and how to do it, as well as a great Channel 9 video demoing how it works if you want to dive deeper, but here’s an overview:

Azure AD B2B lets you invite external people via their email address, to use your Azure resources. For me, that’s SharePoint Online, but you can grant access to other Azure resources too.

The process is really simple – you need to fill out a very basic CSV file with each person’s email address and full name, along with a few basic details such as the site you want them to be redirected to, and an ID of the resource you’re granting access to.

The people you’re inviting don’t need their own Azure AD instance which is the best part – if they do, then they just get invited to your instance with the set permissions… but if they don’t, on the fly a pseudo-Azure AD gets set up by Microsoft for the domain their email address is on, and again they’ll get invited to your instance.

This method eliminates the need to do extensive account management, all you have to worry about is inviting them and giving them the permissions they need (which I do via group membership). Password resets they can do themselves, and get a code sent to their email address to use as part of the reset process.

On top of this, there’s no licensing required, which means if you are already covered for SharePoint Online through your Office 365 sub, this is a very cheap way to make customer facing portals to share information with, that’s locked down and hosted in the HA environment of Office 365.

I was surprised at how simple it was to invite, and even from the end user’s perspective of receiving the invitation – the process is very easy.

At the time of writing, Azure AD B2B is in public preview and may have a few bugs.