Using Invoke-WebRequest calls within a Granfeldt PowerShell MA for Microsoft Identity Manager

MIM Sync Service Account IE Security Settings

If you use PowerShell extensively you should be familiar with the Invoke-RestMethod cmdlet and the ability for PowerShell to call API’s and receive information. The great thing about Invoke-RestMethod is the inbuilt conversion of the results to PowerShell Objects. However there are times when you need the raw response (probably because you are trying to bend things in directions they aren’t supposed to be; story of many of my integrations).

From within Granfeldt PowerShell Management Agent script(s) that use Invoke-WebRequest calls, these will in turn leverage the Internet Explorer COM API on the local machine. That means the account that is performing those tasks will need to have the necessary permissions / Internet Explorer configuration to do so.

Enabling Invoke-WebRequest for the FIM/MIM Synchronization Server Service Account

Logon to your Microsoft Identity Manager Synchronization Server using the Service Account associated with the Forefront Identity Manager Synchronization Service. If you’ve secured the service account properly you will need to temporarily allow that service account to Log on Locally.

FIM Sync Service Account.PNG

Open Internet Explorer and open Internet Options. Select the Security Tab, the Internet zone and select Custom Level.

Locate the Scripting section and set Active scripting to Enable. Set the Allow websites to prompt for information using scripted windows to Disable. Select Ok and Ok.

MIM Sync Service Account IE Security Settings.PNG

With the configuration completed, go back and change back the Forefront Identity Manager Service Accounts’ local permissions so it can’t logon locally.

Your Import / Export Granfeldt PowerShell Management Agent Scripts can now use Invoke-WebRequest where the requests/responses use the Internet Explorer COM API and respect the Internet Explorer security settings for the user profile that the requests are being made by.

Hopefully this helps someone else that is wondering why the scripts that work standalone fail when operating under the FIM/MIM Sync Service Account by the Granfeldt PowerShell Management Agent.

Adding Delta Sync Support to the Microsoft Identity Manager PowerShell Management Agent for Workday HR

Recently I posted a sample Microsoft Identity Manager Management Agent for Workday HR. Subsequently I also posted about some updates I made to the WorkdayAPI PowerShell Module to enable functionality to specify the time period to return changes for. This post details updating  my sample Workday Management Agent to support Delta Synchronisation.

WorkdayAPI PowerShell Module

First up you will need the updated WorkdayAPI PowerShell Module that provides the Get-WorkdayWorkerAdv cmdlet and can take a time period to return information for. Get the updated WorkdayAPI PowerShell Module from here

Update the PowerShell Module on the MIM Sync Server. The module by default will be in the  C:\Program Files\WindowsPowerShell\Modules\WorkdayApi folder.

You will need to unblock the new files.

Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\WorkdayApi' | Unblock-File
Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\WorkdayApi\scripts' | Unblock-File

Updated Schema

In the updated Management Agent I’m also bringing into MIM additional attributes from the other enhancements I made to the PowerShell Module for HireDate, StartDate, EndDate, Supplier and WorkdayActive. The updates to the Schema.ps1 are shown below.

$obj | Add-Member -Type NoteProperty -Name "HireDate|string" -Value "string"
$obj | Add-Member -Type NoteProperty -Name "StartDate|string" -Value "string"
$obj | Add-Member -Type NoteProperty -Name "EndDate|string" -Value "string"
$obj | Add-Member -Type NoteProperty -Name "Supplier|string" -Value "string"
$obj | Add-Member -Type NoteProperty -Name "WorkdayActive|Boolean" -Value $True

The full updated Schema Script is below;

With the Schema Script updated, refresh the Management Agent Schema.

Update Schema

You can then select the new attributes in the Workday MA under Select Attributes.

Select New Attributes.PNG

Then select Ok.

Attributes Selected.PNG

Updated Import Script

The Import Script has a number of changes to handle creating and updating a WaterMark File that is used to store the date stamp of the last run. Also updated in the Import Script is the change to use the Get-WorkdayWorkerAdv cmdlet over the Get-WorkdayWorker cmdlet so that a time period can be specified, and to retrieve the additional attributes we just added to the schema.

Update:

  • Line 11 for the path and name of the Watermark File you wish to use
  • Line 31 for the URI of your Workday Tenant

Executing the Management Agent using a Delta Import Delta Sync Run Profile

After creating a Delta Import Delta Sync Run Profile we can now run a Delta Sync. The following graphic is after seeding the WaterMark file (with the last run time in a format like this 2018-10-29T22:09:08.3628953+00:00), as by default without the WaterMark file being present a Full Import is performed by the MA as it doesn’t have a watermark to base the import time period on.

The changed records in Workday HR are then identified and those records obtained, imported and synchronised via the Management Agent.

Delta Sync.PNG

Summary

Using Delta Synchronisation functionality from Workday HR allows for much quicker synchronsiation from Workday HR to Microsoft Identity Manager.

Updated: Azure AD B2B Guest Invitations Microsoft Identity Manager Management Agent

In August I posted this that detailed Automating Azure AD B2B Guest Invitations using Microsoft Identity Manager. More recently Microsoft updated the Microsoft Graph to include additional information about Azure AD B2B Guest users and I wrote this that creates HTML Reports based off these new attributes.

That information is also handy when managing the lifecyle of Azure AD B2B Users. As we do that using Microsoft Identity Manager I’ve updated my Azure AD B2B Guest Invitation Management Agent for these attributes so they can be used in the lifecycle logic.

Updated Schema

I’ve updated the Schema script to include three new attributes that are shown in bold below in an extract from the Microsoft Graph.

odata.type : Microsoft.DirectoryServices.User
objectType : User
objectId : 38154c4c-a539-4920-a656-b5f8413768b5
deletionTimestamp : 
accountEnabled : True
creationType : Invitation
displayName : Rick Sanchez
givenName : Rick
mail : Rick.Sanchez@customer.com.au
mailNickname : Rick.Sanchez_customer.com.au#EXT#
otherMails : {Rick.Sanchez@customer.com.au}
proxyAddresses : {SMTP:Rick.Sanchez@customer.com.au}
refreshTokensValidFromDateTime : 2018-08-26T02:05:36Z
showInAddressList : False
surname : Sanchez
userPrincipalName : Rick.Sanchez_customer.com.au#EXT#@corporationone.onmicrosoft.com
userState : PendingAcceptance
userStateChangedOn : 2018-08-26T02:05:36Z
userType : Guest

Each are String attributes and I’ve named these;

  • B2BCreationType
  • B2BUpdatedDateTime
  • B2BExternalUserState

Here is the full updated Schema.ps1 Script.

Updated Import Script

The Import Script requires the following changes to bring in the B2B User State attributes.

 # B2B External User State for B2B Users from other AAD's 
if ($user.creationType) {$obj.Add("B2BCreationType", $user.creationType)} 
[string]$B2BUpdatedDateTime = $null 
if ($user.userStateChangedOn) {$B2BUpdatedDateTime = get-date($user.userStateChangedOn); $obj.Add("B2BUpdatedDateTime", $B2BUpdatedDateTime)} 
if ($user.userState) {$obj.Add("B2BExternalUserState", $user.userState)}

The full script with these additions is below. As per this post, make the following updates;

  • Change line 10 for your file path
  • Change line 24 for the version of an AzureAD or AzureADPreview PowerShell Module that you have installed on the MIM Sync Server so that the AuthN Helper Lib can be used. Note if using a recent version you will also need to change the AuthN calls as well as the modules change. See this post here for details.
  • Change line 27 for your tenant name
  • Change line 47/48 for a sync watermark file
  • The Import script also contains an attribute from the MA Schema named AADGuestUser that is a boolean attribute. I create the corresponding attribute in the MetaVerse and MIM Service Schemas for the Person/User objectClasses. This is used to determine when a Guest has been successfully created so their naming attributes can then be updated (using a second synchronisation rule).

Updating the Management Agent

With the updated Schema.ps1 and Import.ps1 scripts in place on the Synchronisation Server, using the Microsoft Identity Manager Synchronisation Service Manager right-click on the B2B Invitiation PSMA and select Refresh Schema.

Refresh B2B MA Schema.PNG

Select the Properties of the MA and choose Select Attributes.  Select the new Attributes.

Select New Attributes

Select Ok.

Select New Attributes - Selected

With the Schema updated and the Attributes selected a Stage/Full Sync can be performed. We now see the External User State, User Creation Type and External User Updated DateTime.

Updates with B2B External State.PNG

Summary

With a change to the Schema and Import B2B Invitation PSMA scripts we can now leverage the new B2B Attributes from the Microsoft Graph for use in our lifecycle management logic.

Building a Microsoft Identity Manager PowerShell Management Agent for Workday HR

Before I even get started with this post, let me state that the integration I describe here is not a standalone solution. Integrating with Workday for any organisation of significant size will require multiple integration points each providing coverage for the scenarios for your implementation. I list a few in this post, but Alexander Filipin has already done an awesome job here.

You may state, that there is of course the Azure Active Directory Provisioning Service for Workday. But what if you need more granular customisation than that provides, or you have requirements to get that data to a number of other systems and you desire to have connectivity to the authoritative source? Those are requirements I had and why I built a Management Agent for Workday to consume Workday HR data directly.

As the title implies it uses the ever versatile Granfeldt PowerShell Management Agent. The other key component is a PowerShell Module that eases the integration with Workdays’ SOAP API. Specifically the Workday API PowerShell Module available here.

Enabling the Workday (Get_Workers) API

In order to access the Workday API you need to have an API  account created. I pointed the Workday Support guys to this Microsoft Azure Inbound Workday Provisioning Documentation. Specifically the ‘Configure a system integration user in Workday‘ section in that link.

Once enabled they were able to give me a Service and Tenant name along with a Username and Password.

  • when using this information your Username is the username and the tenant. So if the username is ‘API User’ and the Tenant is ‘Identity_Corp’ then loginID for our purpose is API User@Identity_Corp
  • the URL you are provided will combine the Service and Tenant names. It will look something like this for the Human Resources Endpoint https://wd3-impl-services1.workday.com/ccx/service/TENANTNAME/Human_Resources/v30.2
    • where wd3-impl-services1 is the Service Name

Install the WorkdayAPI PowerShell Module

On your FIM/MIM Sync Server you will need to install the Workday API PowerShell Module available here. You will need to install it using an Elevated PowerShell session.

Unblock the PowerShell Module and Scripts

After installing the Workday API PowerShell Module it should be located in ‘C:\Program Files\WindowsPowerShell\Modules\WorkdayApi’. You will need to unblock the module and scripts. Run the following two commands in an elevated PowerShell session.

Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\WorkdayApi' | Unblock-File
Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\WorkdayApi\scripts' | Unblock-File

Verify your Execution Policy

As the PowerShell Module is unsigned you might need to do something similar to the following. The Get-ExecutionPolicy -List command will show you what the Execution Policy settings currently are.

Set-ExecutionPolicy "Unrestricted" -Scope Process -Confirm:$false
Set-ExecutionPolicy "Unrestricted" -Scope LocalMachine -Confirm:$false

Import Analytics

50k records with just the base profile (no -include work or -include personal options) takes ~7 minutes to ‘stage’ into the connector space. 50k records WITH work and personal metadata takes ~32 hours at a pretty consistent rate of ~20 mins/500 user records.

If you are retrieving just the Base record then the networking receive bandwidth consumption is ~240kbps. When retrieving the full records as a batch process the networking receive bandwidth consumption it ~3Mbps as shown below.

Full Object Network Graph

Why is this important?

The first “FULL” Sync depending on how many records you have in Workday will alter the approach you will need to take in order to obtain them all. I found that trying to retrieve full records in one call for anything over ~5000 records got inconsistent. I wouldn’t get the full dataset and the machine running it would start to run out of resources (processing power and memory). If you have only a few thousand records, requesting full records in one call will probably suffice.

Now I have ~100k records to return. What I found worked best is to get just the base record for all users then the full record for each user using pagination (via PSMA Paged Imports; I have my set to 500). The the PSMA Paged Imports feature will process the objects through the MA 500 at a time. That way you’re not stressing the host running the Sync Engine to the maximum and you don’t have to wait an hour+ to see any processing of objects on the MA.

Once you have completed a Full Sync and you are of any significant scale you will want to perform Delta Sync’s for the objects that have changed since your last sync. I’m not going to cover that in this post, but in a separate one in the future.

Here is a screenshot of showing the time taken for a Stage (Import) of 50k objects. Just under 33 hours.

Import - Stage Only.PNG

Other Options for Scale

If you are a large organisation this solution isn’t necessary a valid one (in isolation) as I indicated in the opening paragraph. Consider it ancillary augmentation to a multi-pronged implementation (as described nicely by Alexander Filipin here). Potentially something like;

  • Azure Active Directory Inbound Provisioning for object creation
  • A Management Agent such as the one I describe in this post for certain aspects
    • and a modification or two to identify new accounts from a Base Workday discovery and only import the full object for them on workdays and a full sync on the weekends or
    • delta syncs using the Workday Transaction Log Criteria Data and Transaction_Date_Range_Data
      • I’ll cover this in a future post but essentially on every sync I store a cookie-file with the watermark of the time of the sync. On the next deltasync I retrieve the cookie-file with the timestamp and make a call to get all objects changed since the previous sync up to the current time

PSMA Workday Management Agent Script Files

Wow, what a lot of caveats and clarifications. But with all that said, below are base  Schema and Import Scripts examples for the Grandfeldt PowerShell Management Agent that leverages the Workday API PowerShell module.

Schema.ps1

The schema is the base schema for my tenant. You shouldn’t have to change anything here unless you are retreiving additional attributes you want in MIM.

Import.ps1

The import script leverages AuthN creds from the MA config. Make sure the Username is in the format of UserID@TenantName. Also update;

  • Line 10 for the location you put your extension as well as the 8.3 format path to the MA Debug folder
  • Line 30 for the correct Service and Tenant info
  • Make sure you have Paged Imports selected on the Global Parameters screen of the MA Configuration

Export.ps1

I haven’t provided an example. The Workday API PowerShell Module has examples for updating Email, Phone and Photos. You can implement what you require.

Summary

The sample Workday MA Config in this post will give you a base integration with Workday. It is unlikely that it will give you everything you need and there isn’t a single solution that probably will, unless your organisation is quite small. There are other options as mentioned in this post and also the Workday Reports REST API. But those are topics for future posts.

 

Using Azure Cognitive Services to Empower the IT Service Desk

Tonight (29 August 2018) I presented the following presentation on using Azure Cognitive Services to Empower the IT Service/build Business Applications to the Sydney Azure User Group.

I walked through how to leverage the following Azure Cognitive API Services;

  • Speech to Text
  • Text to Speech
  • Language Understanding Intelligent Service (LUIS)
  • Text Language Translation

For each I show a working example and demo.

I then walked through my Voice Assistant for Microsoft Identity Manager and how I integrated three of those services along with Azure IoT, Azure Serverless and Azure PaaS Services.

GitPitch Presents: github/darrenjrobinson/SydAzureUG-CognitiveServices

The Markdown Presentation Service on Git.

If you weren’t present I hope this presentation can still give you a start to integrating and leveraging Azure Services.

Find me on Twitter @darrenjrobinson

Automating Azure AD B2B Guest Invitations using Microsoft Identity Manager

Update: Oct 30 '18 
Also see this post that adds support for Microsoft's updates 
to the Microsoft Graph to include additional information 
about Azure AD B2B Guest users.

Introduction

Earlier this year Microsoft released the Microsoft Identity Manager Azure AD B2B Management Agent. I wrote about using it to write to Azure AD in this post here. As detailed in that post my goal was to write to Azure AD using the MA. I provided an incomplete example of doing that for Guests. This post fills in the gap and unlike the note preceding the post indicates, I’ve updated my MA to use the Graph API over the Azure AD PowerShell Module. It does though work in unison with the Microsoft Azure AD B2B Management Agent.

Overview

The process is;

  • Using the Microsoft Azure B2B Management Agent connect to an Azure AD Tenant that contains users that you want to invite as Guests to your Tenant. Flow in the naming information for users and their email address and any other metadata that you need to drive the logic for who you wish to invite
  • Use my Azure AD B2B Invitation Management Agent to automate the invitation of users to your Azure AD Tenant using Azure AD B2B

My Azure AD B2B Invitation Management Agent works in two phases;

  1. Invitation of Users as Guests
  2. Update of Guests with naming information (Firstname, Lastname, DisplayName)

The Azure AD B2B Invite Management Agent uses my favorite PowerShell Management Agent (the Granfeldt PSMA). I’ve posted many times on how to configure it. See these posts here if you are new to it.

Prerequisites

Setting up an Azure AD User Account for the Management Agent

In your Azure AD create a New User that will be used by the Management Agent to invite users to your Azure AD. I named mine B2B Inviter as shown below.

Inviter Account.PNG

You then want to assign them the Guest inviter role as shown below. This will be enough permissions to invite users to the Azure AD.

Inviter Role.PNG

However depending on how you want these invitee’s to look, you probably also want their names to be kept consistent with their home Azure AD. To also enable the Management Agent to do that you need to also assign the User administrator role as shown below.

Add User Admin Role.PNG

Now log in using that account to Azure AD and change the password. The account is now ready to go.

Management Agent Scripts

The Management Agent uses the Granfeldt PowerShell Management Agent. This is a cut down version of my MIM Azure AD Management Agent. 

Schema Script

I’ve kept the schema small with just enough interesting info to facilitate the functionality required. Expand it if you need additional attributes and update the import.ps1 accordingly.

Import.ps1

The Import script imports users from the Azure AD Tenant that you will be inviting remote Azure AD users too (as Guests).

  • Change line 10 for your file path
  • Change line 24 for the version of an AzureAD or AzureADPreview PowerShell Module that you have installed on the MIM Sync Server so that the AuthN Helper Lib can be used. Note if using a recent version you will also need to change the AuthN calls as well as the modules change. See this post here for details.
  • Change line 27 for your tenant name
  • Change line 47/48 for a sync watermark file
  • The Import script also contains an attribute from the MA Schema named AADGuestUser that is a boolean attribute. I create the corresponding attribute in the MetaVerse and MIM Service Schemas for the Person/User objectClasses. This is used to determine when a Guest has been successfully created so their naming attributes can then be updated (using a second synchronisation rule).

Export.ps1

The Export script handles the creation (invitation) of users from another azure AD Tenant as Guests as well synchronizing their naming data. It doesn’t include deletion logic, but that is simple enough include a deletion  API call based on your MA Deprovisioning logic and requirements.

  • By default I’m not sending invitation notifications. If you want to send invitation notifications change “sendInvitationMessage“= $false to $true on Line 129. You should then also change the Invitation Reply URL on line 55 to your Tenant/Application.
  • Change Line 10 for the path for the debug logging
  • Change Line 24 as per the Import Script if you are using a different version of the help lib
  • Change Line 27 for your Azure AD Tenant Name

Declarative Sync Rules

I’m not going to cover import flow configurations on the MS Azure AD B2B MA here. See here for that. Below details how I’ve configured my Invitation MA for the Creation/Export functions. My join rule (configured in the Sync Engine Invitation MA Config) is email address as shown below. Not the best anchor as it isn’t immutable. But as we don’t know what the DN is going to be until after it is created this is the next best thing.

Join Rule.PNG

Creation Sync Rule

Here are the three attributes I’m syncing to the B2B Invite Management Agent to perform the invitation. I’m using the mail attribute for the DN as it matches the anchor for the schema. We don’t know what objectID will be assigned until the directory service does it. By using email/upn once created we will get the join and won’t end up with two objects on the MA for the same user.

Outbound Flow for Create 2.PNG

For Inbound I’m flowing in the AADGuestUser boolean value. You will need to create this attribute in the MetaVerse and then the MIM Service. In the MIM Service allow the Sync Service Account to manage the attribute and change the MIM Service Filter Permissions to allow Admins to use the attribute in Sets. Also on the MIM Service MA add an Export flow from the MV to the MIM Service for AADGuestUser.

Inbound Flow Create.PNG

Naming Update Sync Rule

The second Sync Rule is to update the guests GivenName, Surname and DisplayName. This sync rule has a dependency on the creation sync rule and has a corresponding Set, Workflow and MPR associated with value of the AADGuestUser boolean attribute populated by the Import script. If True (which it will be after successful creation and the confirming import) the second synchronization rule will be applied.

Sync Naming Synchronisation Rule.PNG

I will trigger an export flow for the three naming attributes.

Outbound Flow for Naming.PNG

Example of Inviting Guests

In this example Rick Sanchez is a member of a guest organisation and meets the criteria of my rules to be invited as a guest to our Tenant. We then, that we get an Add for Rick on the B2B Invite MA.

Create Rick Sanchez.PNG

On export Rick is created in our Azure AD as a Guest User

Rick Created Sync Engine.PNG

Rick appears in Azure AD as a Guest via the Azure Portal.

Rick Created AzureAD.PNG

Following the confirming import our second sync rule fires and flows through an update to DisplayName and adds GivenName and Surname.

Update Rick.PNG

This naming attributes are then successfully exported.

Success Export.PNG

Going to the Azure AD Portal we see that Rick has indeed been updated.

Rick Updated.PNG

Notification Emails

If you enable notification emails a generic notification email is sent like shown below. The import.ps1 MA script has them disabled by default.

Email Invite Notification2.PNG

Summary

Using a combination of the Microsoft Azure AD B2B Management Agent and my Azure AD B2B Invitation Management Agent you can automate the invitation of Guest users to your Azure AD Tenant.

A Voice Assistant for Microsoft Identity Manager

This is the third and final post in my series around using your voice to query/search Microsoft Identity Manager or as I’m now calling it, the Voice Assistant for Microsoft Identity Manager.

The two previous posts in this series detail some of my steps and processes in developing and fleshing out this concept. The first post detailed the majority of the base functionality whilst the second post detailed the auditing and reporting aspects into Table Storage and Power BI.

My final architecture is depicted below.

Identity Manager integration with Cognitive Services and IoT Hub 4x3
Voice Assistant for Microsoft Identity Manager Architecture

I’ve put together more of an overview in a presentation format embedded here.

GitPitch Presents: github/darrenjrobinson/MIM-VoiceAssistant/presentation

The Markdown Presentation Service on Git.

If you’re interested in building the solution checkout the Github Repo here which includes the Respeaker Python Script, Azure Function etc.

Let me know how you go @darrenjrobinson

Using your Voice to Search Microsoft Identity Manager – Part 1

Introduction

Yes, you’ve read the title correctly. Speaking to Microsoft Identity Manager. The concept behind this was born off the back of some other work I was doing with Microsoft Cognitive Services. I figured it shouldn’t be that difficult if I just break down the concept into individual elements of functionality and put together a proof of concept to validate the idea. That’s what I did and this is the first post of the solution as an overview.

Here’s a quick demo.

 

Overview

The diagram below details the basis of the solution. There are a few extra elements I’m still working on that I’ll cover in a future post if there is any interest in this.

Searching MIM with Speech Overview

The solution works like this;

  1. You speak to a microphone connected to a single board computer with the query for Microsoft Identity Manager
  2. The spoken phrase is converted to text using Cognitive Speech to Text (Bing Speech API)
  3. The text phrase is;
    1. sent to Cognitive Services Language Understanding Intelligent Service (LUIS) to identify the target of the query (firstname lastname) and the query entity (e.g. Mailbox)
    2. Microsoft Identity Manager is queried via API Management and the Lithnet REST API for the MIM Service
  4. The result is returned to the single board computer as a text result phase which it then uses Cognitive Services Text to Speech to convert the response to audio
  5. The result is spoken back

Key Functional Elements

  • The microphone array I’m using is a ReSpeaker Core v1 with a ReSpeaker Mic Array
  • All credentials are stored in an Azure Key Vault
  • An Azure Function App (PowerShell) interfaces with the majority of the Cognitive Services being used
  • Azure API Management is used to front end the Lithnet MIM Webservice
  • The Lithnet REST API for the MIM Service provides easy integration with the MIM Service

 

Summary

Leveraging a lot of Serverless (PaaS) Services, a bunch of scripting (Python on the ReSpeaker and PowerShell in the Azure Function) and the Lithnet REST API it was pretty simple to integrate the ReSpeaker with Microsoft Identity Manager. An alternative to MIM could be any other service you have an API interface into. MIM is obviously a great choice as it can aggregate from many other applications/services.

Why a female voice? From a small response it was the popular majority.

Let me know what you think on twitter @darrenjrobinson

How to use the FIM/MIM Azure Graph Management Agent for B2B Member/Guest Sync between Azure Tenants

Introduction

UPDATE: August 2018
As promised below I've finally written up my 
Azure AD B2B Invitation Management Agent. 
You can find it in this post here.

UPDATE: June 2018
When I originally wrote this post the intent was to test
the ability of the Graph MA to export to Azure AD. 
That works.

That then extended to messing with an identity type other 
than member (which works to an extent) but I detailed 
guests. However that is incomplete. I do have a working 
solution that utilises the Graph Invitation API via my 
favourite PowerShell MA (Granfeldt PS MA) and the 
PowerShell cmdlet New-AzureADMSInvitation from the 
Azure AD PowerShell Module.

That solution involves the MS Graph MA connected to a 
Partner tenant to get visibility of partner users and 
then creating relevant users in the home tenant via a 
PowerShell MA and the New-AzureADMSInvitation cmdlet. 
Another MS Graph MA connected to the home tenant provides 
easy visibility of additional guest user attributes for
ongoing functions such as reporting and de-provisioning. 

I will write that up later in July.  Stay tuned and keep
the above in mind when reading this post.

Just landed from the Microsoft Identity Manager Engineering Team is a new Management Agent built specifically for managing Azure Users and Groups and Contacts.

Microsoft have documented a number of scenarios for implementing the management agent. The scenarios the MA has been built for are valid and I have customers that will benefit from the new MA immediately. There is however another scenario I’m seeing from a number of customers that is possible but not detailed in the release notes. That is B2B Sync between Azure Tenants; using Microsoft Identity Manager to automate the creation of Guests in an Azure Tenant.

This could be one-way or multi-way depending on what you are looking to achieve. Essentially this is the Azure equivalent of using FIM/MIM for Global Address List Sync.

B2B MA.png

Overview

The changes are minimal to the documentation provided with the Management Agent. Essentially;

  • ensure you enable Write Permissions to the Application you create in the AAD Tenant you will be writing too
  • Enable the Invite Guest users to the organization permission on the AAD Application
  • Create an Outbound Sync Rule to an AAD Tenant with the necessary mandatory attributes
  • Configure the Management Agent for Export Sync Profiles

In the scenario I’m detailing here I’m showing taking a number of users from Org2 and provisioning them as Guests in Org1.

What I’m detailing here supplements the Microsoft documentation. For configuring the base MA definitely checkout their documentation here.

Microsoft Graph Permissions

When setting up the Graph Permissions you will need to have Write permissions to the Target Azure AD for at least Users. If you plan to also synchronize Groups or Contacts you’ll need to have Write permissions for those too.

Graph Permissions 1

In addition as we will be automating the invitation of users from one Tenant to another we will need to have the permission ‘Invite guest users to the organization’.

Graph Permissions 2

With those permissions selected and while authenticated as an Administrator select the Grant Permissions button to assign those permissions to the Application.

Grant Permissions 1Grant Permissions 2

Repeat this in both Azure AD Tenants if you are going to do bi-directional sync.  If not you only need write and invite permissions on the Tenant you will be creating Guest accounts in.

Creating the Import/Inbound Sync Rules Azure Tenants

Here is an example of my Import Sync Rules to get Members (Users) in from an Azure Tenant. I have an inbound sync rule for both Azure Tenants.

Sync Rules.PNG

Make sure you have ‘Create Resource in FIM‘ configured on the source (or both if doing bi-directional) Graph Connector.

Sync Rule Relationship.PNG

The attribute flow rules I’ve used are below. They are a combination of the necessary attributes to create the corresponding Guest account on the associated management agent and enough to be used as logic for scoping who gets created as a Guest in the other Tenant. I’ve also used existing attributes negating the need to create any new ones.

Inbound SyncRule Flow.PNG

Creating the Export/Outbound Sync Rule to a Partner B2B Tenant

For your Export/Outbound rule make sure you have ‘Create resource in external system’ configured.

Export Relationship.PNG

There are a number of mandatory attributes that need to be flowed out in order to create Guests in Azure AD. The key attributes are;

  • userType = Guest
  • accountEnabled = True
  • displayName is required
  • password is required (and not export_password as normally required on AD style MA’s in FIM/MIM)
  • mailNickname is required
  • for dn and id initially I’m using the id (flowed in import to employeeID) from the source tenant. This needs to be provided to the MA to get the object created. Azure will generate new values on export so we’ll see a rename come back in on the confirming import
  • userPrincipalName is in the format of
    • SOURCEUPN (with @ replaced with _ ) #EXT# DestinationUPNSuffix
    • e.g user1_org2.com#EXT#org1.com

Export Attributes.PNG

Here is an example of building a UPN.

UPN Rule.PNG

Sets, Workflows and MPR’s

I didn’t need to do anything special here. I just created a Set based on attributes coming in from the source Azure Tenant to scope who gets created in the target Tenant. An MPR that looks for transition into the Set and applies the Workflow that associates the Sync Rule.

End to End

After synchronizing in from the source (B2B Org 2) the provisioning rules trigger and created the Users as Guests on B2B Org 1.

Prov to Org1 1.PNG

Looking at the Pending Export we can see our rules have applied.

Pending Export.PNG

On Export the Guest accounts are successfully created.

Export Success.PNG

On the confirming import we get the rename as Azure has generated a new CN and therefore DN for the Guest user.

Rename on Import 2.PNG

Looking into Azure AD we can see one of our new Guest users.

User in AAD.PNG

Summary

Using the Microsoft Azure B2B Graph Management Agent we can leverage it to create users from one Tenant as Azure AD Members in another Tenant. Stay tuned for another post detailed the solution detailed in the Update in the Introduction.

Identifying Active Directory Users with Pwned Passwords using Microsoft/Forefront Identity Manager v2, k-Anonymity and Have I Been Pwned

Microsoft Identity Manager - Have I Been Pwned

Background

In August 2017 Troy Hunted released a sizeable list of Pwned Passwords. 320 Million in fact.

I subsequently wrote this post on Identifying Active Directory Users with Pwned Passwords using Microsoft/Forefront Identity Manager which called the API and sets a boolean attribute in the MIM Service that could be used with business logic to force users with accounts that have compromised passwords to change their password on next logon.

Whilst that was a proof of concept/discussion point of sorts AND  I had a disclaimer about sending passwords across the internet to a third-party service there was a lot of momentum around the HIBP API and I developed a solution and wrote this update to check the passwords locally.

Today Troy has released v2 of that list and updated the API with new features and functionality. If you’re playing catch-up I encourage you to read Troy’s post from August last year, and my two posts about checking Active Directory passwords against that list.

Leveraging V2 (with k-Anonymity) of the Have I Been Pwned API

With v2 of the HIBP passwod list and API the number of leaked credentials in the list has grown to half a billion. 501,636,842 Pwned Passwords to be exact.

With the v2 list in conjunction with Junade Ali from Cloudflare the API has been updated to be leveraged with a level of anonymity. Instead of sending a SHA-1 hash of the password to check if the password you’re checking is on the list you can now send a truncated version of the SHA-1 hash of the password and you will be returned a set of passwords from the HIBP v2 API. This is done using a concept called k-anonymity detailed brilliantly here by Junade Ali.

v2 of the API also returns a score for each password in the list. Basically how many times the password has previously been seen in leaked credentials lists. Brilliant.

Updated Pwned PowerShell Management Agent for Pwned Password Lookup

Below is an updated Password.ps1 script for the previous API version of my Pwned Password Management Agent for Microsoft Identity Manager. It functions by;

  • taking the new password received from PCNS
  • hashes the password to SHA-1 format
  • looks up the v2 HIBP API using part of the SHA-1 hash
  • updates the MIM Service with Pwned Password status

Checkout the original post with all the rest of the details here.

Summary

Of course you can also download (recommended via Torrent) the Pwned Password dataset. Keep in mind that the compressed dataset is 8.75 GB and uncompressed is 29.4 GB. Convert that into an On-Premise SQL Table(s) as I did in the linked post at the beginning of this post and you’ll be well in excess of that.

Awesome work from Troy and Junade.