Bulk registration of FIM SSPR question and answer gate (QA Gate) answers

Most, but probably not all, will know that the FIMAutomation PowerShell snapin that shipped with Forefront Identity Manager 2010 R2 included additional cmdlets to those that shipped with FIM 2010.  The new cmdlets are for Self Service Password Reset (SSPR) registration.  There are various scenarios for utilising these cmdlets, e.g.:

  • you pre-populate answers from an internal system, i.e. you don’t give users the choice of their secret answers because you have them in HR or some other system; or
  • you want to register a load of users for performance testing; or
  • you want to pre-populate some answers and allow the users to register some others (this is not available OOB but not too difficult to develop in ASP.NET if you have a couple of days spare).

The cmdlets in question are:

There’s good documentation on using the cmdlets in the Programmatic User Registration information/article.

I’ve been using the cmdlets to pre-register a load of users for load testing.  I thought I’d share the script I used for easy reference.  Before I do that let’s step through the process.

Pre-requisites

The permissions required for registration are relative to the requestor, which means I can register for myself but not for another.  Before you can bulk-load registration data you therefore require an MPR.  As I’m only registering QAGate answers I just need the one MPR to allow me to do this:

  • Type: Request
  • Operation: Create resource, Delete resource
  • Permissions: Grants Permission (True/checked)
  • Target Resource Definition Before Request: All Gate Registrations
  • Target Resource Definition After Request: All Gate Registrations
  • Resource Attributes: All Attributes (sloppy, but it’s for admins so not too big a deal, feel free to get more granular)

You define your own set of requestors or just use the administrators set.  You define a name and description, I’m not going to tell you what to put in there.  And there’s no WFs needed.  This is all about granting you permissions to do what needs to be done.

What needs to be answered?

Logon to one of your servers running the FIM Service and open a PowerShell shell and import the FIMAutomation snap-in:

Add-PSSnapin fimautomation

Grab the AuthN WF you want to register users for and dump the questions to the screen:

(Get-AuthenticationWorkflowRegistrationTemplate `
    –AuthenticationWorkflowName 'msresource365dotCom Password Reset AuthN Workflow'
).GateRegistrationTemplates.Data.Name

The order is important!  So copy and paste that list into PowerShell_ISE or whatever you use to write scripts.

Creating the answers

Next we clone the template (we could have done this earlier but we didn’t), populate the answers and then we’re ready to perform the registration.

To clone the template we call the Clone() method of the object returned by the command we’ve just run:

$enAuthNWFTemplate = (
    Get-AuthenticationWorkflowRegistrationTemplate `
        -AuthenticationWorkflowName 'msresource365dotCom Password Reset AuthN Workflow'
).Clone()

Next we populate the answers.  We use an index, which is why we dumped the questions earlier, e.g.

# What is your favourite food?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value = "Burger, chips and a glass of Shiraz"

# What is your favourite colour?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[1].Value = "Coch tywyll"

# What is the name of your favourite musical artist, band, symphony or piece?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[2].Value = "Pearl Jam"

# What was the name of your elementary / primary school?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[3].Value = "Chateau fort de Roquetaillade"

# What was your first car/bike?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[4].Value = "Aston Martin V12 Vantage S"

# Enter a memorable date other than your birthday (YYYY/MM/DD)
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[5].Value = "14/10/1066"

# What is your favourite movie or show?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[8].Value = "The Expendables"

Registration

Submit the populated template along with a username to the FIM Service:

Register-AuthenticationWorkflow `
    -UserName corp\pawill `
    -AuthenticationWorkflowRegistrationTemplate $enAuthNWFTemplate

That returns a success status, but just in case let’s verify the operation:

Confirm-AuthenticationWorkflowRegistration `
    -UserName corp\pawill `
    –AuthenticationWorkflowName $enAuthNWFTemplate.DisplayName

Putting it all together

From my examples and the links to the documentation you can see it’s pretty easy to register a user.  The following script was very quickly written to register a large number of users so that we can do some load testing.  For the purpose of testing we need the same answers for all in-scope objects, therefore I created a CSV file of account names, prefixed with their domain, e.g. DOMAIN\sAMAccountName.  The column is called user.  The following PowerShell script reads the file from the current directory, loads the FIM PowerShell snap-in, clones the QAGate, populates it with answers, and the iterates the CSV file registering each user in the file with the same QAGate data.


Write-Host "`nSSPR QAGate bulk registration script v0.1ps1`n`tPaul Williams (pa***will****@microsoft.com) October 2013`n"

Write-Host "Consuming input CSV file"
$users = Import-Csv -Path .\sSPRBulkRegistrationUsers-Batch1-enGB.csv

if(!$?)
{
    Exit
}

if( (Get-PSSnapin -Registered | ? { $_.Name -eq 'fimautomation' }).Count -eq 1 -and
    (Get-PSSnapin | ? { $_.Name -eq 'fimautomation' }).Count -eq 0)
{
    Write-Host "Loading FIMAutomation PowerShell module"
    Add-PSSnapin fimautomation
}

if(!$?)
{
    Exit
}

Write-Host "Retrieving AuthN WF to clone"
$enAuthNWFTemplate = (Get-AuthenticationWorkflowRegistrationTemplate `
    -AuthenticationWorkflowName 'msresource365dotCom Password Reset AuthN Workflow - ENG').Clone()

Write-Host "Populating question answers"

# What is your favourite food?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value = "Burger, chips and a glass of Shiraz"

# What is your favourite colour?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[1].Value = "Coch tywyll"

# What is the name of your favourite musical artist, band, symphony or piece?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[2].Value = "Pearl Jam"

# What was the name of your primary/elementary school?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[3].Value = "Chateau fort de Roquetaillade"

# What was your first car/bike?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[4].Value = "Aston Martin V12 Vantage S"

# Enter a memorable date other than your birthday (YYYY/MM/DD)
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[5].Value = "14/10/1066"

# What is your favourite movie or show?
$enAuthNWFTemplate.GateRegistrationTemplates[0].Data[8].Value = "The Expendables"

Write-Host "Registering users"
foreach($user in $users)
{
    $userName = $user.user
    Write-Host "Registering en-GB QAGate for user <$userName>..." -NoNewline
    Register-AuthenticationWorkflow `
        -UserName $userName `
        -AuthenticationWorkflowRegistrationTemplate $enAuthNWFTemplate
}

Write-Host "`nScript complete.`n"

I hope this is helpful!

Advertisements

About Paul Williams

IT consultant working for Microsoft specialising in Identity Management and Directory Services.
This entry was posted in FIM, FIM 2010 R2 and tagged , , , , , , , , , . Bookmark the permalink.

8 Responses to Bulk registration of FIM SSPR question and answer gate (QA Gate) answers

  1. Kunal says:

    Hi,

    Thanks for an extremely informative article, however I seem to be stuck at one point.

    I bulk registered a few dummy users for SSPR, the scenario being that each users already has answers stored in an HR system. For this, I amended my CSV file to have columns for user name, answer1, answer2, answer3 and populated the CSV file with dummy data. Further, I modified your script slighlty so that I pass the answers to $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value (e.g. $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value = $userdata.answer1)

    This seems to work in so far as the users do get registered, however ever time I try and reset the password by supplying the answers the reset portal complains that the answers don’t match on what was supplied.

    Any idea what could be causing this?

    Thanks

  2. Kunal says:

    Sordid fingers of mine, it does work I had made a stupid typo in the powershell code which meant the wrong input answers were being presented for registration!

    Apologies for the double post too, my browser wasn’t displaying my original comment until I restarted

    Thanks once again for a very well explained post

  3. Peter says:

    Hi,
    How could this script be amended to check for the existence of a user in the FIM portal before attempting to register the user?
    Thanks

    • You have a couple of options. You could build the $users variable by querying for users using XPath or you could just add some logic to ensure the object exists first. If performing the latter, the most efficient option is to use Import-FIMConfig. You can create an unresolved ImportObject and use this to get the GUID (or a failure). Otherwise you use Export-FIMConfig -CustomConfig. I don’t have an example handy because I’m traveling. I will post an example ASAP.

  4. Asdrúbal Veloz says:

    Hi, i follow these steps, but after i run the “register-authenticationworkflow” i get the following error:

    Register-AuthenticationWorkflow : Failure on making enumeration web service call.
    Filter = /GateRegistration[(UserID=’2c7b19c2-3e7d-4ac5-9c9a-a3e0b71fd63f’ and WorkflowDefinition=’9c3aca59-a85c-437f-bb67-9ce5a70521d7′)]
    Error= Microsoft.ResourceManagement.WebServices.Client.AuthenticationRequiredException: Authentication information is required
    at Microsoft.ResourceManagement.WebServices.Client.ResourceManagementClient.DeleteResource(UniqueIdentifier resourceIdentifier, ContextualSecurityToken securityToken)
    at Microsoft.ResourceManagement.Automation.Utilities.DeleteGateRegistrations(BaseCmdlet cmdlet, Guid userGuid, Guid workflowGuid, Boolean terminateOnError)

  5. Pingback: FIM Password Self Service Challenges – Part 2 – Project KB Blog

  6. Have an updated script to use from the csv file
    user,DOB,Mobile,Year,School
    Domain\Fakey.McSun,22/05/1980,0070091234,2000,MySchool

    Script
    #Record transcript for logging purposes
    Import-Module Microsoft.PowerShell.Host
    Start-Transcript -Path “C:\Service\PWDRegistration\RegisterLog.txt”

    Write-Host “Consuming input CSV file”
    $users = Import-Csv -Path “C:\Service\PWDRegistration\REGInputFile.txt”

    if(!$?)
    {
    Exit
    }

    if( (Get-PSSnapin -Registered | ? { $_.Name -eq ‘fimautomation’ }).Count -eq 1 -and
    (Get-PSSnapin | ? { $_.Name -eq ‘fimautomation’ }).Count -eq 0)
    {
    Write-Host “Loading FIMAutomation PowerShell module”
    Add-PSSnapin fimautomation
    }

    if(!$?)
    {
    Exit
    }

    Write-Host “Retrieving AuthN WF to clone”
    $enAuthNWFTemplate = (Get-AuthenticationWorkflowRegistrationTemplate `
    -AuthenticationWorkflowName ‘Password Reset AuthN Workflow’).Clone()

    Write-Host “Populating question answers”

    # What is your date of birth? (MM\DD\YYYY)$line.
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value = “$user.DOB”
    # What is your mobile number including country code?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[1].Value = “$user.Mobile”
    # What was your last year at secondary school?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[2].Value = “$user.Year”
    # What was the name of the last secondary school you attended?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[3].Value = “$user.School”
    #OneTimePasswordMobilePhone (WorkFlow “Password Reset AuthN Workflow” added “One-Time Password SMS Gate” after QA Gate. make sure your sms gateway is setup using SmsServiceProvider.dll)

    $enAuthNWFTemplate.GateRegistrationTemplates[1].Data[0].Value = “$user.Mobile”

    Write-Host “Registering users”
    foreach($user in $users)
    {
    $userName = $user.user
    Write-Host “Populating question answers”

    # What is your date of birth? (MM\DD\YYYY).
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[0].Value = $user.DOB
    # What is your mobile number including country code?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[1].Value = $user.Mobile
    # What was your last year at secondary school?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[2].Value = $user.Year
    # What was the name of the last secondary school you attended?
    $enAuthNWFTemplate.GateRegistrationTemplates[0].Data[3].Value = $user.School
    # OneTimePasswordMobilePhone
    $enAuthNWFTemplate.GateRegistrationTemplates[1].Data[0].Value = $user.Mobile

    Write-Host “Registering en-GB QAGate and Mobile for user … $enAuthNWFTemplate” -NoNewline
    Register-AuthenticationWorkflow `
    -UserName $userName `
    -AuthenticationWorkflowRegistrationTemplate $enAuthNWFTemplate
    }

    Write-Host “`nScript complete.`n”
    get-AuthenticationWorkflowRegistrationTemplate –AuthenticationWorkflowName “Password Reset AuthN Workflow” |fl *

    # Stop transcript logging
    Stop-Transcript

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s