AD FS 2.0: Bulk Add Trust Relationships and Claim Rules for Testing

Overview

Included in this article is a Powershell script sample which allows bulk additions and deletions of test Claims Provider Trusts, Relying Party Trusts, and Claim Rules. These test trust relationships and claim rules may be useful for web testing in a lab environment.

Usage

Be sure to utilize Set-ExecutionPolicy to allow execution of Powershell scripts on your system.

Example

Set-ExecutionPolicy Unrestricted

Execute ADFS20BulkTestTrusts.ps1 from an administrative Powershell console window.

The prompts will ask which item type you would like to work with and how you would like to work with that item.

Example of adding 10 CP Trusts:

Note: Adding CP Trusts can take a considerable amount of time due to the certificate work the script performs when adding CP Trusts.

Example of removing 100 RP Trusts:

Example of adding 1000 Claim Rules to 100 RP Trusts:

Sample Code

Note: This sample is provided AS-IS with no warranties and confers no rights. This sample is meant for testing purposes in a development environment, and should never be executed in a production environment.

Paste the following code sample into a text editor and save as ADFS20BulkTestTrusts.ps1:

#SCRIPT TITLE - ADFS20BulkTestTrusts.ps1

#AUTHOR - Adam Conkle - Microsoft Corporation

#VERSION 1.0

#Write header info to the screen

Write-Host "`n AD FS 2.0: Add or Remove Bulk Test Claims Provider Trusts, Relying Party Trusts or Claim Rules"

Write-Host "`n IMPORTANT: This sample is provided AS-IS with no warranties and confers no rights." -ForegroundColor "yellow"

Write-Host "`n Trusts and rules will be created and removed following the naming convention: `"TestXY`","

Write-Host " where X = the number of trusts or rules you would like to add or remove,"

Write-Host " and Y = CP, RP, or Rule."

Write-Host "`n`tExample`n`tYou select options to add 3 RP trusts, and the result is`:"

Write-Host "`t`"Test1RP`", `"Test2RP`", `"Test3RP`"`n"

#Ignore errors and proceed

$ErrorActionPreference = "SilentlyContinue"

#Add the AD FS 2.0 PSH snap-in. Exit if it fails

If (!((Get-PSSnapin Microsoft.Adfs.Powershell).Name))

{

Write-Host " The AD FS 2.0 snap-in is not loaded`n`tAttempting to load it"

Add-PSSnapin Microsoft.Adfs.Powershell

If ((Get-PSSnapin Microsoft.Adfs.Powershell).Name)

{

Write-Host "`tSuccess" -ForeGroundColor "green"

}

Else

{

Write-Host "`tFailed to load AD FS 2.0 snap-in`n`tExiting" -ForeGroundColor "red"

Exit

}

}

#Initialize vars

$CPRPRule = "foo"

$AddorRemove = "foo"

$Iterations = 0

#Prompt for modification type

Write-Host " CP, RP, or Rule`?" -NoNewline

#allow for short-hand input

While (($CPRPRule -ne "CP") -and ($CPRPRule -ne "RP") -and ($CPRPRule -ne "C") -and ($CPRPRule -ne "R") -and ($CPRPRule -ne "Rule") -and ($CPRPRule -ne "CR") -and ($CPRPRule -ne "X"))

{

$CPRPRule = Read-Host " (CP/RP/Rule or X to exit)"

}

#Fix short-hand input

If (($CPRPRule -eq "C") -or ($CPRPRule -eq "R"))

{

$CPRPRule += "P"

}

ElseIf (($CPRPRule -eq "CR") -or ($CPRPRule -eq "Rule"))

{

$CPRPRule = "claim rule"

}

ElseIf ($CPRPRule -eq "X")

{

Write-Host " Exiting`n" -ForegroundColor "red"

Exit

}

$CPRPRule = ($CPRPRule).ToUpper()

#Prompt for add or remove

Write-Host " Add or Remove`?" -NoNewline

#Allow short-hand input

While (($AddorRemove -ne "Add") -and ($AddorRemove -ne "Remove") -and ($AddorRemove -ne "A") -and ($AddorRemove -ne "R") -and ($AddorRemove -ne "X"))

{

$AddorRemove = Read-Host " (Add/Remove or X to exit)"

}

#Fix short-hand input

If ($AddorRemove -eq "A")

{

$AddorRemove += "dd"

}

ElseIf ($AddorRemove -eq "R")

{

$AddorRemove += "emove"

}

ElseIf ($AddorRemove -eq "X")

{

Write-Host " Exiting`n" -ForegroundColor "red"

Exit

}

#If adding/removing claim rules, we need to know what they want to modify

#Options include: CP, RP, or the built-in AD CP Trust

If ($CPRPRule -eq "Claim Rule")

{

$RuleAction = "foo"

#Capitalize first letter to make it look nice

$AddorRemove = $AddorRemove.Replace($AddorRemove.Substring(0,1),($AddorRemove.Substring(0,1).ToUpper()))

Write-Host " $AddorRemove claim rules where`?" -NoNewline

#Allow short-hand input

While (($RuleAction -ne "ADCP") -and ($RuleAction -ne "CP") -and ($RuleAction -ne "RP") -and ($RuleAction -ne "AD") -and ($RuleAction -ne "C") -and ($RuleAction -ne "R") -and ($RuleAction -ne "A") -and ($RuleAction -ne "X"))

{

$RuleAction = Read-Host " (CP/RP/ADCP or X to exit)"

}

#Fix short-hand input

If (($RuleAction -eq "C") -or ($RuleAction -eq "R"))

{

$RuleAction += "P"

}

ElseIf (($RuleAction -eq "AD") -or ($RuleAction -eq "A"))

{

$RuleAction = "ADCP"

}

ElseIf ($RuleAction -eq "X")

{

Write-Host " Exiting`n" -ForegroundColor "red"

Exit

}

$RuleAction = $RuleAction.ToUpper()

#Prompt for number of CP or RP test trusts they would like to modify

#Does not apply to the built-in AD CP Trust since there is only one

If ($RuleAction -ne "ADCP")

{

$AddorRemove = $AddorRemove.ToLower()

Write-Host " How many $RuleAction would you like to $AddorRemove rules for`?" -NoNewline

$RuleIterations = Read-Host " (integer)"

while ($RuleIterations -notmatch "^\d+$")

{

$RuleIterations = Read-Host " (integer)"

}

}

}

#Prompt for number of objects they would like to add/remove

If ($CPRPRule -eq "claim rule") {$CPRPRule = $CPRPRule.ToLower()}

Write-Host " How many $CPRPRule would you like to $AddorRemove`?" -NoNewline

#Check for integer input

$Iterations = Read-Host " (integer)"

while ($Iterations -notmatch "^\d+$")

{

$Iterations = Read-Host " (integer)"

}

#Notify the user about the work to be done

If ($CPRPRule -eq "claim rule") {$CPRPRule = $CPRPRule.ToLower()}

If ($AddorRemove -eq "Add")

{

Write-Host " Adding $Iterations $CPRPRule"

}

Else

{

Write-Host " Removing $Iterations $CPRPRule"

}

#Add CP Trusts

If (($CPRPRule -eq "CP") -and ($AddorRemove -eq "Add"))

{

For ($Count = 1; $Count -le $Iterations; $Count++)

{

#Generate cert in local computer My store

$name = new-object -com "X509Enrollment.CX500DistinguishedName.1"

$name.Encode("CN=DO_NOT_TRUST_Test"+$Count+"CP", 0)

$key = new-object -com "X509Enrollment.CX509PrivateKey.1"

$key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"

$key.KeySpec = 1

$key.Length = 2048

$key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"

$key.MachineContext = 1

$key.Create()

$serverauthoid = new-object -com "X509Enrollment.CObjectId.1"

$serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")

$ekuoids = new-object -com "X509Enrollment.CObjectIds.1"

$ekuoids.add($serverauthoid)

$ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"

$ekuext.InitializeEncode($ekuoids)

$cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"

$cert.InitializeFromPrivateKey(2, $key, "")

$cert.Subject = $name

$cert.Issuer = $cert.Subject

$cert.NotBefore = get-date

$cert.NotAfter = $cert.NotBefore.AddDays(365)

$cert.X509Extensions.Add($ekuext)

$cert.Encode()

$enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"

$enrollment.InitializeFromRequest($cert)

$certdata = $enrollment.CreateRequest(0)

$enrollment.InstallResponse(2, $certdata, 0, "")

$Cert = @(dir cert: -Recurse | Where-Object { $_.subject -match "DO_NOT_TRUST_Test"+$Count+"CP" })[0]

#Add the new CP Trust using the new cert and name

$URI = "urn`:test`:test"+$Count+"CP"

$TrustName = "Test"+$Count+"CP"

Add-ADFSClaimsProviderTrust -Identifier $URI -Name $TrustName -TokenSigningCertificate $Cert

}

#Clean up the certs from the local machine My store

$store = new-object system.security.cryptography.x509certificates.x509Store 'My', 'LocalMachine'

$store.Open('ReadWrite')

$Certs = @(dir cert: -Recurse | Where-Object { $_.subject -like "*DO_NOT_TRUST_Test*" })

foreach ($cert in $certs) {$store.Remove($cert)}

$store.Close()

}

#Remove CP Trusts

ElseIf (($CPRPRule -eq "CP") -and ($AddorRemove -eq "Remove"))

{

For ($Count = 1; $Count -le $Iterations; $Count++)

{

$TrustName = "Test"+$Count+"CP"

Remove-ADFSClaimsProviderTrust -TargetName $TrustName

}

}

#Add RP Trusts

ElseIf (($CPRPRule -eq "RP") -and ($AddorRemove -eq "Add"))

{

For ($Count = 1; $Count -le $Iterations; $Count++)

{

$URI = "urn`:test`:test"+$Count+"RP"

$TrustName = "Test"+$Count+"RP"

Add-ADFSRelyingPartyTrust -Identifier $URI -Name $TrustName

}

}

#Remove RP Trusts

ElseIf (($CPRPRule -eq "RP") -and ($AddorRemove -eq "Remove"))

{

For ($Count = 1; $Count -le $Iterations; $Count++)

{

$TrustName = "Test"+$Count+"RP"

Remove-ADFSRelyingPartyTrust -TargetName $TrustName

}

}

#Add claim rule

ElseIf (($CPRPRule -eq "Claim Rule") -and ($AddorRemove -eq "Add"))

{

#Add claim rule for CP

If ($RuleAction -eq "CP")

{

#Loop through trusts

For ($TrustCount = 1; $TrustCount -le $RuleIterations; $TrustCount++)

{

#Get the original rule set to file

$RulesFile = "$env:TEMP\Test"+$TrustCount+"CP_Rules.txt"

$TrustName = "Test"+$TrustCount+"CP"

(Get-ADFSClaimsProviderTrust -Name $TrustName).AcceptanceTransformRules | Out-File $RulesFile

#Loop through number of rules and append to the original set

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleName = "Test"+$RuleCount+"Rule"

"`@RuleName `= `"$RuleName`"

c`:`[Type == `"http://schemas.contoso.com/claims/test/ClaimType$RuleCount`"`]

`=`> issue`(claim `= c`)`;" | Out-File $RulesFile -Append

}

#Set the new rules to the trust

$TrustName = "Test"+$TrustCount+"CP"

Set-ADFSClaimsProviderTrust -TargetName $TrustName -AcceptanceTransformRulesFile $RulesFile

#Clean up

Remove-Item $RulesFile

}

}

#Add claim rule for RP

ElseIf ($RuleAction -eq "RP")

{

#Loop through trusts

For ($TrustCount = 1; $TrustCount -le $RuleIterations; $TrustCount++)

{

#Get original rule set to file

$RulesFile = "$env:TEMP\Test"+$TrustCount+"RP_Rules.txt"

$TrustName = "Test"+$TrustCount+"RP"

(Get-ADFSRelyingPartyTrust -Name $TrustName).IssuanceTransformRules | Out-File $RulesFile

#Loop through number of rules and append to the original set

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleName = "Test"+$RuleCount+"Rule"

"`@RuleName `= `"$RuleName`"

c`:`[Type == `"http://schemas.contoso.com/claims/test/ClaimType$RuleCount`"`]

`=`> issue`(claim `= c`)`;" | Out-File $RulesFile -Append

}

#Set the new rules to the trust

$TrustName = "Test"+$TrustCount+"RP"

Set-ADFSRelyingPartyTrust -TargetName $TrustName -IssuanceTransformRulesFile $RulesFile

#Clean up

Remove-Item $RulesFile

}

}

#Add claim rule for the built-in AD CP Trust

ElseIf ($RuleAction -eq "ADCP")

{

#Get the original set of AD CP trust rules to file

$RulesFile = "$env:TEMP\ADCP_Rules.txt"

(Get-ADFSClaimsProviderTrust -Name "Active Directory").AcceptanceTransformRules | Out-File $RulesFile

#Loop through the rules and append to the original set

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleName = "Test"+$RuleCount+"Rule"

"`@RuleName `= `"$RuleName`"

c`:`[Type == `"http://schemas.contoso.com/claims/test/ClaimType$RuleCount`"`]

`=`> issue`(claim `= c`)`;" | Out-File $RulesFile -Append

}

#Set the AD CP Trust with the new rule set

Set-ADFSClaimsProviderTrust -TargetName "Active Directory" -AcceptanceTransformRulesFile $RulesFile

Remove-Item $RulesFile

}

Else

{

#Catch bad options

Write-Host " Invalid action. Exiting`n" -ForegroundColor "red"

Exit

}

}

#Remove claim rules

ElseIf (($CPRPRule -eq "Claim Rule") -and ($AddorRemove -eq "Remove"))

{

#Remove claim rules from CP trusts

If ($RuleAction -eq "CP")

{

#Loop through trusts

For ($TrustCount = 1; $TrustCount -le $RuleIterations; $TrustCount++)

{

#Get the rules into an array

$RulesFile = "$env:TEMP\TestCP"+$TrustCount+"_Rules.txt"

$TrustName = "Test"+$TrustCount+"CP"

$RuleArray = ((Get-ADFSClaimsProviderTrust -Name $TrustName).AcceptanceTransformRules).Split(";")

#Loop through the rule array and add the delimiter back

For ($ElementCount = 0; $ElementCount -lt ($RuleArray.Count)-1; $ElementCount++)

{

$RuleArray[$ElementCount] += ";"

}

#Loop through rule names and add only keep names to a new array

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleArray = $RuleArray | Where {$_ -notmatch "Test"+$RuleCount+"Rule"}

}

#Write the new rule set to file

$RuleArray | Out-File $RulesFile

#Set the new rule set to the trust

$TrustName = "Test"+$TrustCount+"CP"

Set-ADFSClaimsProviderTrust -TargetName $TrustName -AcceptanceTransformRulesFile $RulesFile

#Clean up

Remove-Item $RulesFile

}

}

#Remove claim rules from RP

ElseIf ($RuleAction -eq "RP")

{

#Loop through trusts

For ($TrustCount = 1; $TrustCount -le $RuleIterations; $TrustCount++)

{

#Get current rule set to array

$RulesFile = "$env:TEMP\TestRP"+$TrustCount+"_Rules.txt"

$TrustName = "Test"+$TrustCount+"RP"

$RuleArray = ((Get-ADFSRelyingPartyTrust -Name $TrustName).IssuanceTransformRules).Split(";")

#Loop through the rule array and add the delimiter back

For ($ElementCount = 0; $ElementCount -lt ($RuleArray.Count)-1; $ElementCount++)

{

$RuleArray[$ElementCount] += ";"

}

#Loop through rule names and add only keep names to a new array

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleArray = $RuleArray | Where {$_ -notmatch "Test"+$RuleCount+"Rule"}

}

#Write the new rule set to file

$RuleArray | Out-File $RulesFile

#Set the new rule set to the trust

$TrustName = "Test"+$TrustCount+"RP"

Set-ADFSRelyingPartyTrust -TargetName $TrustName -IssuanceTransformRulesFile $RulesFile

#Clean-up

Remove-Item $RulesFile

}

}

#Remove claim rules from the built-in AD CP Trust

ElseIf ($RuleAction -eq "ADCP")

{

#Get the current rule set to array

$RulesFile = "$env:TEMP\ADCP_Rules.txt"

$RuleArray = ((Get-ADFSClaimsProviderTrust -Name "Active Directory").AcceptanceTransformRules).Split(";")

#Loop through the rule array and add the delimiter back

For ($ElementCount = 0; $ElementCount -lt ($RuleArray.Count)-1; $ElementCount++)

{

$RuleArray[$ElementCount] += ";"

}

#Loop through rule names and add only keep names to a new array

For ($RuleCount = 1; $RuleCount -le $Iterations; $RuleCount++)

{

$RuleArray = $RuleArray | Where {$_ -notmatch "Test"+$RuleCount+"Rule"}

}

#Write the new rule set to file

$RuleArray | Out-File $RulesFile

#Set the new rule set to the trust

Set-ADFSClaimsProviderTrust -TargetName "Active Directory" -AcceptanceTransformRulesFile $RulesFile

#Clean up

Remove-Item $RulesFile

}

Else

{

#Catch bad options

Write-Host " Invalid action. Exiting`n" -ForegroundColor "red"

Exit

}

}

Else

{

#Catch bad input

Write-Host "`tUnsupported input`n`tExiting`n" -ForegroundColor "red"

Exit

}

#Notify

Write-Host "`tDone`n" -ForegroundColor "green"

#################################################