Long story short: we are releasing on Codeplex a set of PowerShell cmdlets which wrap the management API of the Windows Azure AppFabric Access Control Service.

This is hopefully for the joy of our IT admin friends who want to add ACS to their arsenal, but I bet that this will make many developers happy as well. I’ve never really used PowerShell before, and I’m using those cmdlets like crazy since the very first internal drop!

You can use those new cmdlets to save repetitive provisioning processes in form of PowerShell scripts, and consistently reuse them just by passing as parameters the targeted namespace and corresponding management key. You can use them for backing up your namespace settings on file and restore them at a later time, or copy settings from one namespace to the other. You can easily integrate ACS management in your existing scripts, or even just use the cmdlets to perform quick queries and adjustments to your namespace directly from PowerShell ISE or the command line. In fact, you can do whatever you are used to do with PowerShell cmdlets Smile.


The initial set we are releasing today is not 100% exhaustive, for example we don’t touch the service identities yet, but it already enables most of the scenarios we encountered. The command names are self-explanatory:







Rule Groups






There’s just 23 of them, and we might shrink them further in the future. For example: do we really need an Add-DefaultPassThroughRules cmdlet or can we just rely on Add-Rule? You tell us!
All cmdlets support get-help including the –Full option, although things are not too verbose at the moment: in subsequent releases we’ll tidy things up, but we wanted to put this in your hands ASAP.

Now for the usual disclaimer:  Those cmdlets are distributed in source code form and are not part of the product. you should consider them a code sample, even if we provide you with a setup that will automatically compile and install them so that you can use them without ever opening the project in visual studio if you don’t want to. Of course we are happy to take your feedback, especially now that the package is still a bit rough on the edges, but you should always remember that those cmdlets are unsupported.
Other disclaimer: this release have been thoroughly tested only on Windows 7 x64 SP1, and quickly tested on Windows 7 x86 SP1 and Windows 2008 R2 x64 SP1. There are known problems on older platforms, which we’ll iron out moving forward. Think of this release as one preview.

That said, I am sure you’ll have a lot of fun using the cmdlets for exploring the features that ACS offers.

Some More Background, and One Example

If you want to manage your ACS namespaces, there’s no shortage of options: you can take advantage of the management portal (new in 2.0) or you can use the OData API exposed via management service.

In my team we make pretty heavy use of ACS, both for our internal tooling (for example managing content and events) and for the samples, demos and hands on lab we produce.
In order to enable the scenario we want to implement, at setup time all of those deliverables require us to go through fixed sets of configuration steps in ACS. For example, when you use the template in the Windows Azure Toolkit for Windows Phone 7 to generate an ACS-ready project, the initialization code needs to:

  • Add Google as an IP
  • Add Yahoo! as an IP
  • Remove any RP which may collide with the new one
  • Create the new RP
  • Get rid of all the rules which may already be in the rule group we are targeting
  • Generate all the pass-through rules for the various IPs

This is a relatively simple sequence of operations; other setups we have to do, like the enterprise subscription provisioning flow we follow when we handle a new FabrikamShipping subscriber, are WAY more complicated.
In order to automate those processes, we progressively populated a class library of C# wrappers for the ACS management APIs. Then we started including that library in the Setup folder of various projects, together with a console app which calls those wrappers in the sequence that the specific sample being set up dictates; for example, the sequence described above for the Windows Azure toolkit for Windows Phone 7
In that specific case, the setup solution (it’s C:WAZToolkitForWP7SetupacsAcsSetup.sln if you have the toolkit and you are curious) is almost 580 lines of code.

Now, multiply that for all the projects we have (for the newest ones see this post) and the number starts to look significant. Add it to the frequent requests we get from customers to extend the cmdlets we created for Windows Azure to other services in the Windows Azure platform, and you’ll see why we decided to create a set of cmdlets for ACS.
Quite frankly, it was also because it was a low hanging fruit for us. We already had our wrapper library for the ACS management API, and we had the cmdlets wrapper solution we used for generating the Windows Azure cmdlets; putting the two together was pretty straightforward.

Once we had the right set of cmdlets we went ahead and re-created the sequence above in for of PowerShell script, and the improvement in respect to the AcsSetup.sln approach is impressive. Check it out:

# Coordinates of your namespace
$acsNamespace = "<yourNamespace>";
$mgmtKey = "<yourManagementKey>";

# Constants
$rpName = "WazMobileToolkit";
$groupName = "Default Rule Group for $rpName";
$signingSymmetricKey = "2RGYmQiFT9uslnxTTUn9MFr/nU+HeVwkmMJ6MwBNGuQ=";

$allowedIdentityProviders = @("Windows Live ID","Yahoo!", "Google”);

# Include ACS Management SnapIn
Add-PSSnapin ACSManagementToolsSnapIn;

# Get the ACS management token for securing all subsequent API calls
$mgmtToken = Get-AcsManagementToken -namespace $acsNamespace -managementKey $mgmtKey;

# Configure Preconfigured Identity Providers
Write-Output "Add PreConfigured Identity Providers (Google and Yahoo!)…";
$googleIp = Add-IdentityProvider -mgmtToken $mgmtToken -type "Preconfigured" –preconfiguredIPType "Google";
$yahooIp = Add-IdentityProvider -mgmtToken $mgmtToken -type "Preconfigured" –preconfiguredIPType "Yahoo!";

# Remove RP (if it already exists)
Write-Output "Remove Relying Party ($rpName) if exists…";
Remove-RelyingParty -mgmtToken $mgmtToken -name $rpName;

# Remove All Rules In Group (if they already exist)
Write-Output "Remove All Rules In Group ($groupName) if exists…";
Get-Rules -mgmtToken $mgmtToken -groupName $groupName | ForEach-Object { Remove-Rule -mgmtToken $mgmtToken -rule $_ };

# Create Relying Party
Write-Output "Create Relying Party ($rpName)…";
$rp = Add-RelyingParty -mgmtToken $mgmtToken -name $rpName -realm "uri:wazmobiletoolkittest" -tokenFormat "SWT" -allowedIdentityProviders $allowedIdentityProviders -ruleGroup $groupName -signingSymmetricKey $signingSymmetricKey;

# Generate default pass-through rules
Write-Output "Create Default Passthrough Rules for the configured IPs ($allowedIdentityProviders)…";
$rp.IdentityProviders | ForEach-Object { Add-DefaultPassthroughRules -mgmtToken $mgmtToken -groupName $groupName -identityProviderName $_.Name }

Write-Output "Done";

Excluding the comments (but counting the Write-Output) those are 20 lines of very understandable code, which you can modify in notepad (typically just for the namespace and namespace key) and run with a simple double-click; or, if you are fancy, you can open it up in PowerShell ISE and execute it line by line if you want to. Does it show that I am excited about this? Open-mouthed smile

Let’s play a bit more. Let’s say that you now want to add Facebook as an identity provider. First you’ll need to add some config values at the beginning of the script:

$fbAppIPName = "Facebook IP";
$fbAppSecret = "XXXXXXXXXXXXX";

We can even be fancy and subordinate the Facebook setup to the existance of non-empty facebook app coordinates in the script:

$facebookEnabled = (($fbAppId -ne "") -and ($fbAppSecret -ne ""));

Then we just add those few lines right where we create the preconfigured IPs:

# Configure Facebook App Identity Provider
if ($facebookEnabled)
    Write-Output "Add Facebook App Identity Provider ($fbAppIPName)…";
    # Remove FB App IP (if exists)
    Remove-IdentityProvider -mgmtToken $mgmtToken -name $fbAppIPName;
    # Add FB App IP
    $fbIp = Add-IdentityProvider -mgmtToken $mgmtToken -type "FacebookApp" -name $fbAppIPName -fbAppId $fbAppId -fbAppSecret $fbAppSecret;

Super straightforward; and the part that I love is that you can just test those commands one by one and see the results immediately, saving them in the script only when you are certain they do what you want them to do. For management tasks, it definitely beats fiddling with the debugger and the immediate window.

Want to play a bit more? Sure. One thing I often need to do is wiping a namespace clean after I did a demo during a session. Sometimes I have many sessions in a day, from time to time even back to back: as you can imagine, clicking around the portal for deleting entities is not fun nor very fast. But now I can just double click on the following script and I am done!

$acsNamespace = "holacsfederation";
# Include ACS Management SnapIn
Add-PSSnapin ACSManagementToolsSnapIn;

$mgmtToken = Get-AcsManagementToken -namespace $acsNamespace -managementKey $mgmtKey;
Write-Output "Wiping IPs (and associated rules)";
Get-IdentityProviders -mgmtToken $mgmtToken | where {$_.SystemReserved -eq $false} | ForEach-Object { Remove-IdentityProvider -mgmtToken $mgmtToken -name $_.Name };
Write-Output "Wiping RPs (and associated rules)";
Get-RelyingParties -mgmtToken $mgmtToken | where {$_.SystemReserved -eq $false} | ForEach-Object { Remove-RelyingParty -mgmtToken $mgmtToken -name $_.Name };
Write-Output "Wiping Rule Groups";
Get-RuleGroups -mgmtToken $mgmtToken | where {$_.SystemReserved -eq $false} | ForEach-Object { Remove-RuleGroup -mgmtToken $mgmtToken -name $_.Name };

Here I delete all IPs (which will delete the associated rules), all RPs and all rule groups. All three commands have the same structure. Let’s pick the IP one:

Get-IdentityProviders -mgmtToken $mgmtToken
     | where {$_.SystemReserved -eq $false}
          | ForEach-Object { Remove-IdentityProvider -mgmtToken $mgmtToken -name $_.Name };

Get-IdentityProviders returns all IPs in the namespace; the where clause excludes the system reserved ones (Windows Live ID) which we’d be unable to delete anyway, then the ForEach-Object cycles through all the IPs and removes them. You’ve got to love PowerShell piping.

Well, this barely scratches the surface of what you can do with the ACS cmdlets. Please do check them out! We look forward for your feedback, and for once not just from developers! Winking smile


2 Responses to Announcing: Sample ACS Cmdlets for the Windows Azure AppFabric Access Control Service

  1. Joongs says:

    Wow, this is what I saw in Teched NA yesterday. Thank you for sharing this cool tool!

Leave a Reply

Your email address will not be published. Required fields are marked *