PowerShell Attribute Store for AD FS 2.0

*WARNING: Academic exercise only – I’m not sure how this would scale in production*

Download the PowerShell Attribute Store

So I was at an event last week and a buddy of mine told me that he had an intern create an attribute store for AD FS that would provision an AD account if one didn’t exist. I got to thinking about this, and I thought why stop at provisioning accounts?  Why not have an attribute store that you can use to call any PowerShell script that you want and return the results as strings that you can use in claims.

So I went back and wrote it up and decided to share it with everyone. Feel free to download the attribute store and try it out.  It’s really simple – here’s how it works:

  1. Create the PowerShell Attribute Store in AD FS
  2. Create the PowerShell script.  In the script, pass the string that you want to give back to AD FS with the Write-Output cmdlet
  3. Create a claim rule that calls the attribute stor. Pass in a query string in the following format:

FULL_PATH_OF_SCRIPT;SCRIPT_PARAMETERS

I’ll illustrate how to use the PowerShell Attribute Store with an example. In this example, I’m going to get the size of the user’s home directory as a claim.

Example: Getting the User’s Home Directory Size as a Claim

Step 1: Install the PowerShell Attribute Store DLL

Download the PowerShell Attribute Store and copy the file PshAttrStore.dll into your AD FS installation folder. For example, C:\Program Files\Active Directory Federation Services 2.0

 

Step 2: Create the PowerShell Attribute Store

Create the PowerShell Attribute store as a custom attribute store in AD FS.  In this example, I called it PshAttrStore.  The class name is Class1 (I know it’s lazy, but I literally just threw it together in a few minutes), so use the following string for the class name in the custom attribute store: PshAttrStore.Class1, PshAttrStore

 

Step 3: Set AD FS Account Permissions

Give the AD FS Service Account permissions to run the script.  I just added the AD FS Service Account to the local Administrators group on the AD FS server.  Ideally, you would want to take the time to figure out what permissions it actually needs in order to execute PowerShell scripts, but I didn’t take the time to do that.  If anyone figures it out, post it as a comment and I’ll update this post with the information.

Step 4: Create Your PowerShell Script

For this example, I’m going to use a script that takes in the name of a folder and returns the size of it as a claim.  When returning the data back to AD FS, you have to use the Write-Output command at the end of the script.  Here’s my example script:

## GetFolderSize.ps1

## -------------------

## A sample script to return the size of the folder passed into the

## script as an argument

 

## Get the name of the folder as the first argument in the script

$directory = $args[0];

 

## Get the combined size of all of the items in the folder

$size = Get-ChildItem $directory | Measure-Object -Property Length –Sum

 

## Calculate the size in MB and format the size to 2 decimal places

$displayedSize = "{0:N2}" -f ($size.sum / 1MB) + " MB"

 

## Return the size of the folder back to AD FS

Write-Output $displayedSize

 

Step 5: Create the Claim Rule

I’m going to use my GetFolderSize.ps1 script to get the size of the user’s home directory. To do this, I’ll need two claim rules:

  • Claim Rule 1: Get the path of the user’s home directory by querying the homeDirectory attribute in Active Directory
  • Claim Rule 2: Call the GetFolderSize.ps1 script and pass in the home directory path that I got in the first claim rule

Here is what the claim rules for this look like

Claim Rule 1: Get Home Directory Path

Claim Rule 2: Get Home Directory Size

Step 6: Testing It Out

To test this, I’m going to use ClaimGrabber, which is a tool that I wrote to assist in claim rule authoring.  I’m using a beta version of ClaimGrabber in this post, which I’ll finish writing and post shortly.

You’ll notice in the ClaimGrabber output (below) that we are passing the application a claim called http://eag.demo/directorySize with a value of 14.77 MB. This claim is what we got back from the PS1 script!

Other Uses and Feedback

I thought this was an interesting idea to try out and I’m rather surprised how well it worked.  The results are pretty quick – there’s no noticeable delay when the user logs in, but I’m only running a simple script. I could see scenarios where you might want to use this to run some complex scripts. There are a ton of scenarios that you could use this for. Here are some that I could think of off the top of my head:

  • An easy way to do custom attribute stores without having to write a compiled .NET DLL
  • Auto-provision user accounts based on the claims
  • Kick off a FIM sync script for on-demand provisioning
  • Log some data about the user to an alternate audit log

I’m really interested to hear some feedback on this – in particular:

  • Would something like this be useful to deploy in production?
  • What other scenarios / scripts could you use this for?