Session Recap, PowerShell Scripts and Resources from session on Azure AD Management Skills at NICConf 2017

Last week at NICConf I presented two sessions on Management of Microsoft Azure AD, Application Publishing with Azure AD – the New Management Experience! and Take your Azure AD Management Skills to the Next Level with Azure AD Graph API and Powershell!

In the last session i presented demos and scripts with some technical details, so in this blog post I will link to those PowerShell scripts together with some explanations. See also my slides for the sessions published here:, and the session recording might be available later which I will link to.

First i talked about the new Azure AD PowerShell v2 module and install info:

# Azure AD v2 PowerShell Quickstart module install
# Azure AD has a GA version: AzureAD and Preview version: AzureADPreview
# Check available versions installed
Get-Module AzureAD ListAvailable
Get-Module AzureADPreview ListAvailable
# Install from PowerShell Gallery
Install-Module AzureAD
Install-Module AzureADPreview
# Update new versions from PS Gallery
Update-Module AzureAD
Update-Module AzureADPreview
# Check and uninstall old versions
$Latest = Get-InstalledModule ("AzureADPreview")
Get-InstalledModule ("AzureADPreview") AllVersions | ? {$_.Version -ne $Latest.Version} | Uninstall-Module WhatIf
# Check Commands, see also list of commands at: ref.
Get-Command Module AzureADPreview

Then connecting and exploring some objects and license info:

# Azure AD v2 PowerShell Quickstart Connect
# Connect with Credential Object
$AzureAdCred = Get-Credential
Connect-AzureAD Credential $AzureAdCred
# Connect with Modern Authentication
# Explore some objects
# Getting users by objectid, upn and searching
Get-AzureADUser ObjectId <objectid>
Get-AzureADUser ObjectId
Get-AzureADUser SearchString "Jan Vidar"
# Explore deeper via object variable
$AADUser = Get-AzureADUser ObjectId
$AADUser | Get-Member
$AADUser | FL
# Look at licenses and history for enable and disable
# Or
Get-AzureADUser ObjectId | Select-Object ExpandProperty AssignedPlans
# More detail for individual licenses for plans
Get-AzureADUserLicenseDetail ObjectId $AADUser.ObjectId | Select-Object ExpandProperty ServicePlans
# Get your tenants subscriptions, and explore details
Get-AzureADSubscribedSku | FL
Get-AzureADSubscribedSku | Select-Object SkuPartNumber ExpandProperty PrepaidUnits
Get-AzureADSubscribedSku | Select-Object SkuPartNumber ExpandProperty ServicePlans
# Invalidate Users Refresh tokens
Revoke-AzureADUserAllRefreshToken ObjectId $AADUser.ObjectId

Then performing some Administration tasks including creating Dynamic Groups, setting user thumbnail photo, adding licenses and changing passwords:

# Create a Dynamic Group for my test users of Seinfeld characters
New-AzureADMSGroup DisplayName "Seinfeld Users" Description "Dynamic groups with all Seinfeld users" MailEnabled $false SecurityEnabled $true MailNickname "seinfeld" GroupTypes "DynamicMembership" MembershipRule "(user.department -eq ""Seinfeld"")" MembershipRuleProcessingState "Paused"
# Get Group and members
$AADGroup = Get-AzureADMSGroup SearchString "Seinfeld Users"
Get-AzureADGroupMember ObjectId $AADGroup.Id
# Set Membership Processing
$AADGroup | Set-AzureADMSGroup MembershipRuleProcessingState On
# Save members to object variable
$members = Get-AzureADGroupMember ObjectId $AADGroup.Id
# Set User Thumbnail Photo
# Note that setting Thumbnailphoto can only be set against cloud mastered objects, or else error message:
# Unable to update the specified properties for on-premises mastered Directory Sync objects or objects currently undergoing migration.
Set-AzureADUserThumbnailPhoto ObjectId <myuserupn or objectid> FilePath C:\_source\temp\
# Get and View User Thumbnail Photo
Get-AzureADUserThumbnailPhoto ObjectId <myuserupn or objectid> view $true
#region License management for a collection of users
# For example assigning EMS E5 license plan
# Get SkuId for EMS E5 (EMS PREMIUM)
$EmsSkuId = (Get-AzureADSubscribedSku | Where { $_.SkuPartNumber -eq 'EMSPREMIUM'}).SkuId
ForEach ($member in $members) {
# Get the user
$User = Get-AzureADUser ObjectId $member.ObjectId
# Create a License Object for assigning the wanted SkuId
$License = New-Object TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$License.SkuId = $EmsSkuId
# Create a Licenses Object for Adding the License
$Licenses = New-Object TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$Licenses.AddLicenses = $License
# If I wanted to remove licenses I would use .RemoveLicenses instead
# And lastly, update User license with added (or removed) licenses
Set-AzureADUserLicense ObjectId $User.ObjectId AssignedLicenses $Licenses
# Reset a Users password
# Note that synchronized users need Azure AD Premium, and Azure AD Connect with Password Write-Back Configured
$password = Read-Host AsSecureString
Set-AzureADUserPassword ObjectId <myuserupn or objectid> Password $password
# Change (not Reset) the current logged on users password
Update-AzureADSignedInUserPassword CurrentPassword $CurrentPassword NewPassword $NewPassword

In the next part of my session I went on to talk about the Azure AD Graph API and the Microsoft Graph API. The Microsoft Graph API will eventually be the “one API to rule them all”, as Azure AD also can be accessed by that API, but there are still use cases for the Azure AD Graph API.

In either case, to be able to use the APIs you must create and register an Azure AD Application of type Web App/Api, and give that Application the needed permissions to access the APIs. I showed in my session how to do this in the portal, and here you have a PowerShell Script for creating that same type of Application, this example for accessing the Azure AD Graph API:

# This Application is for accessing the Azure AD Graph Api
# Log in to Azure AD with Global Admin
# Create the Azure AD API Application
$azureAdApp = New-AzureADApplication DisplayName "Elven Azure AD Reporting Api App" Homepage "https://localhost" IdentifierUris "https://localhost/azureadreportingapi" ReplyUrls "https://localhost"
$keyStartDate = "{0:s}" -f (get-date).AddHours(-1) + "Z"
$keyEndDate = "{0:s}" -f (get-date).AddYears(1) + "Z"
# Create Password Key Secret
$azureAdAppKeySecret = New-AzureADApplicationPasswordCredential ObjectId $azureAdApp.ObjectId CustomKeyIdentifier "Azure AD Api Reporting Key" StartDate $keyStartDate EndDate $keyEndDate
# Get the Azure AD SPN
$azureAdSpn = Get-AzureADServicePrincipal Filter "DisplayName eq 'Microsoft.Azure.ActiveDirectory'"
# Get the Oauth2 permissions for Read and Sign-in plus Directory Read
$azureAdOauth2UserSignInProfileRead = $azureAdSpn | select expand Oauth2Permissions | ? {$_.value -eq "User.Read"}
$azureAdOauth2DirectoryRead = $azureAdSpn | select expand Oauth2Permissions | ? {$_.value -eq "Directory.Read.All"}
# Build a Required Resource Access Object with permissions for User.Read + Sign in and Directory Read
$requiredResourceAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
  ResourceAppId=$azureAdSpn.AppId ;
    Id = $azureAdOauth2UserSignInProfileRead.Id ;
    Type = "Scope"
Id = $azureAdOauth2DirectoryRead.Id ;
Type = "Role"
# Set the required resources for the Azure AD Application
Set-AzureADApplication ObjectId $azureadapp.ObjectId RequiredResourceAccess $requiredResourceAccess
# Associate a new Service Principal to my Azure AD Application
$appspn = New-AzureADServicePrincipal AppId $azureadapp.AppId Tags @("WindowsAzureActiveDirectoryIntegratedApp")
# Add Permission Grant for that App Service Principal to the Microsoft.Azure.ActiveDirectory API
## This is the only thing that cannot be automated by now!
### Go to the Azure Portal and your Azure AD, under App Registrations, find this Reporting Api App, and under Permissions select to Grant Permission

Note that for the above script, you will need to note some output and manual operations:

  • Take a note of the Application ID, you will need that later:
  • Take note of the Key Secret, you will need that later also:
  • Application must be manually granted permission here, as this per now cannot be automated with PowerShell:

By the way, you should newer share this App Id and key secret publically (as I have just done here 😉 Other people could use that same information to access your APIs and Azure AD info, so take care to protect that info! (Of course I have deleted that info after showing this here 😉

Now, with this App registered in Azure AD, we can now start managing Azure AD via REST API calls, for example from PowerShell. The following script shows how we can get Self Service Password Registration Activity via the Azure AD Graph API, specifically we will use the Reporting API ( Note that the script will need the App Id and Key value noted from above:

# PowerShell for calling the Azure AD Graph Reporting REST API,
# Getting Self Service Password Reset Registrations
# This script will require registration of a Web Application in Azure Active Directory
# Method 1: Use steps here for manually creating required Web App:
# Method 2: Use Azure AD PowerShell as documented here:
$loginURL = ""
$tenantdomain = "<yourtenant>"
# Fill in your App Id and Key Secret
$azureAdAppId = "<app id for azure ad application>"
$azureAdAppKey = "<valid key secret for azure ad application>"
# Create a credential based on already registered Azure AD App Id and Key Secret
$keysecurestring = ConvertTo-SecureString $azureAdAppKey AsPlainText Force
$reportingapicred = New-Object System.Management.Automation.PSCredential ($azureAdAppId, $keysecurestring)
# Get an Oauth 2 access token based on client id, secret and tenant domain
$body = @{grant_type="client_credentials";resource=$resource;client_id=$reportingapicred.UserName;client_secret=$reportingapicred.GetNetworkCredential().Password}
$oauth = Invoke-RestMethod Method Post Uri $loginURL/$TenantDomain/oauth2/token?apiversion=1.0 Body $body
# Define a header with the authorization token
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
# Build the request, here we are looking for SSPR activity
$topResults = 100 # Tweak this value if you want different page size and present it in a report
$reportContent = @()
$reportUrl = "$TenantDomain/reports/ssprRegistrationActivityEvents?api-version=beta&`$top=$topResults"
$reportCount = 0
# Returns a JSON document for the "ssprRegistrations" report
$ssprRegistrations = (Invoke-WebRequest Headers $headerParams Uri $reportUrl UseBasicParsing).Content | ConvertFrom-Json
# Adding data to the Report
$reportContent += $ssprRegistrations.value | Select Unique eventTime, role, registrationActivity, displayName, userName
# Showing the Report
# Exporting the Report to a Comma Separated Value file
$reportContent | Export-Csv "ElvenAzureAD_SSPRregistrations.csv" NoTypeInformation Delimiter ","

With that last export to a Csv file I can import it to Power BI as a table, and create a report and a dashboard on it, for example showing which password reset registration method the users configured, what user and role type did the registration and the count and date for the registrations:


In the session we also looked at the new Content Pack for Azure AD, showing sign-in and audit events, and also how you can get data from the Microsoft Graph API using a OData Feed:

I hope this scripts will be as useful for you as it is for me! Good luck with taking your management of Azure AD to the next level with Azure AD PowerShell and Graph APIs!

1 thought on “Session Recap, PowerShell Scripts and Resources from session on Azure AD Management Skills at NICConf 2017

  1. Pingback: Creating Azure AD Application using Powershell | adatum

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s