ADFS – Migrate Relying party Trusts to New Server
Overview
I just came across the requirement to migrate a relying party trusts (RPT) from existing ADFS Server to New ADFS Server. I did not wanted to do it manually as there are many of them. I searched and quickly found an article with great script from Sarah Duncan – https://blog.keyfactor.com/migrating-relying-party-trusts
I then modified the script to automate the entire lot, as Sarah has done to manually create one by one. I wanted to just provide the current identifiers and then automatically create all of them on new Server
This procedure can be used to Copy existing Replying Party Trust or Create on Separate Sever.
First, export all the relying party trusts that need migrating to XML files using the below export-rps.ps1 PowerShell script. The output from the script will be a file with a file name based on the relying party identifier. For example:
- rptname-something.com
- https—rptname.something.com
Then Export all Existing Identifiers to automate provision on new Server.
Third and last step is to Import on New Server.
Step-by-step guide
Export Relying party trusts and Identifiers
- Log on to Existing Federation Server
- Open Powershell
- To Export all Relying party Trust – Execute the “Export-RPT.ps1
- This will export to xml file to “C:\IT\extract-rpt\”
- To Export all Relying party Trust identifiers only – Execute the “Export-RPT-Identifiers.ps1
- This will export text file “C:\IT\extract-rpt\”
- Copy both exported files to new ADFS Server
Import Relying party trusts and Identifiers
- Log on to New Federation Server
- Open Powershell
- Make sure you have both of the exported files in C:\Export-RPT\ Folder
- To Import the Relying party Trusts, Execute Import-RPT.ps1
- Open ADFS Management and confirm all Relying party’s Trusts are created
Appendix
Export-RPT.ps1
# The directory where the relying parties should be extracted
$filePathBase = “C:\extract-rp\”$AdfsRelyingPartyTrusts = Get-AdfsRelyingPartyTrust
foreach ($AdfsRelyingPartyTrust in $AdfsRelyingPartyTrusts)
{
# The identifier is actually an array of identifiers, we will just use the first one
$rpIdentifier = $AdfsRelyingPartyTrust.Identifier[0]# We want a filename for this so we will try to make the identifier safe
# Replace all of the following characters with a –
# : ” / \ | ? *
$fileNameSafeIdentifier = $rpIdentifier -replace ”, ‘-‘ -replace ‘:’, ‘-‘ -replace ‘”‘, ‘-‘ -replace ‘/’, ‘-‘ -replace ‘\\’, ‘-‘ -replace ‘\|’, ‘-‘ -replace ‘\?’, ‘-‘ -replace ‘\*’, ‘-‘# Create the filename of the XML file we will export
$filePath = $filePathBase + $fileNameSafeIdentifier + ‘.xml’# Use Export-Clixml to export the object to an XML file
$AdfsRelyingPartyTrust | Export-Clixml $filePath}
Export-RPT-Identifier.ps1
Get-ADFSRelyingPartyTrust | select identifier | Export-CSV C:\extract-rp\RPT.txt
Import-RPT.ps1
# location where the extracted XML files can be found
$filePathBase = “C:\Export-rpt\”$c = Get-Content “C:\Export-rpt\rp.txt”
Foreach ($c1 in $c)
{# Identifier of the Relying Party (RP) we want to import
#$rpIdentifier = “urn:federation:identifier.example.com”
$rpIdentifier = $c1 -replace ‘{‘, ” -replace ‘}’, ”# We want the name we created during extract for this so we will try to make the identifier safe
# Replace all of the following characters with a –
# : ” / \ | ? *
$directoryNameSafeIdentifier = $rpIdentifier -replace ”, ‘-‘ -replace ‘:’, ‘-‘ -replace ‘”‘, ‘-‘ -replace ‘/’, ‘-‘ -replace ‘\\’, ‘-‘ -replace ‘\|’, ‘-‘ -replace ‘\?’, ‘-‘ -replace ‘\*’, ‘-‘$xmlFile = $filePathBase + $directoryNameSafeIdentifier + “.xml”
$xmlFile
if (!(Test-Path -path $xmlFile))
{
“File not found” + $xmlFile
}
else
{$ADFSRelyingPartyTrust = Import-clixml $xmlFile
$NewADFSRelyingPartyTrust = Add-ADFSRelyingPartyTrust -Identifier $rpIdentifier -Name $ADFSRelyingPartyTrust.Name
$rpIdentifierUri = $NewADFSRelyingPartyTrust.IdentifierSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -AutoUpdateEnabled $ADFSRelyingPartyTrust.AutoUpdateEnabled
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -DelegationAuthorizationRules $ADFSRelyingPartyTrust.DelegationAuthorizationRules
# note we need to do a ToString to not just get the enum number
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -EncryptionCertificateRevocationCheck $ADFSRelyingPartyTrust.EncryptionCertificateRevocationCheck.ToString()Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -IssuanceAuthorizationRules $ADFSRelyingPartyTrust.IssuanceAuthorizationRules
# note we need to do a ToString to not just get the enum number
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -SigningCertificateRevocationCheck $ADFSRelyingPartyTrust.SigningCertificateRevocationCheck.ToString()Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -WSFedEndpoint $ADFSRelyingPartyTrust.WSFedEndpoint
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -IssuanceTransformRules $ADFSRelyingPartyTrust.IssuanceTransformRules
# Note ClaimAccepted vs ClaimsAccepted (plural)
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -ClaimAccepted $ADFSRelyingPartyTrust.ClaimsAccepted### NOTE this does not get imported
#$ADFSRelyingPartyTrust.ConflictWithPublishedPolicySet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -EncryptClaims $ADFSRelyingPartyTrust.EncryptClaims
### NOTE this does not get imported
#$ADFSRelyingPartyTrust.EnabledSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -EncryptionCertificate $ADFSRelyingPartyTrust.EncryptionCertificate
# Identifier is actually an array but you can’t add it when
# using Set-ADFSRelyingPartyTrust -TargetIdentifier
# so we use -TargetRelyingParty instead
$targetADFSRelyingPartyTrust = Get-ADFSRelyingPartyTrust -Identifier $rpIdentifier
Set-ADFSRelyingPartyTrust -TargetRelyingParty $targetADFSRelyingPartyTrust -Identifier $ADFSRelyingPartyTrust.Identifier# SKIP we don’t need to import these
# $ADFSRelyingPartyTrust.LastMonitoredTime
# $ADFSRelyingPartyTrust.LastPublishedPolicyCheckSuccessful
# $ADFSRelyingPartyTrust.LastUpdateTimeSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier `
-MetadataUrl $ADFSRelyingPartyTrust.MetadataUrlSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -MonitoringEnabled $ADFSRelyingPartyTrust.MonitoringEnabled
# Name is already done
#Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -Name $ADFSRelyingPartyTrust.NameSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -NotBeforeSkew $ADFSRelyingPartyTrust.NotBeforeSkew
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -Notes “$ADFSRelyingPartyTrust.Notes”
### NOTE this does not get imported
#$ADFSRelyingPartyTrust.OrganizationInfoSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -ImpersonationAuthorizationRules $ADFSRelyingPartyTrust.ImpersonationAuthorizationRules
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -ProtocolProfile $ADFSRelyingPartyTrust.ProtocolProfile
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -RequestSigningCertificate $ADFSRelyingPartyTrust.RequestSigningCertificate
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -EncryptedNameIdRequired $ADFSRelyingPartyTrust.EncryptedNameIdRequired
# Note RequireSignedSamlRequests vs SignedSamlRequestsRequired,
#Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -RequireSignedSamlRequests $ADFSRelyingPartyTrust.SignedSamlRequestsRequired
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -SignedSamlRequestsRequired $ADFSRelyingPartyTrust.SignedSamlRequestsRequired# Note SamlEndpoint vs SamlEndpoints (plural)
# The object comes back as a
# [Deserialized.Microsoft.IdentityServer.PowerShell.Resources.SamlEndpoint]
# so we will reconstitute# create a new empty array
$newSamlEndPoints = @()
foreach ($SamlEndpoint in $ADFSRelyingPartyTrust.SamlEndpoints)
{
# Is ResponseLocation defined?
if ($SamlEndpoint.ResponseLocation)
{
# ResponseLocation is not null or empty
$newSamlEndPoint = New-ADFSSamlEndpoint -Binding $SamlEndpoint.Binding -Protocol $SamlEndpoint.Protocol -Uri $SamlEndpoint.Location -Index $SamlEndpoint.Index -IsDefault $SamlEndpoint.IsDefault
}
else
{
$newSamlEndPoint = New-ADFSSamlEndpoint -Binding $SamlEndpoint.Binding -Protocol $SamlEndpoint.Protocol -Uri $SamlEndpoint.Location -Index $SamlEndpoint.Index -IsDefault $SamlEndpoint.IsDefault -ResponseUri $SamlEndpoint.ResponseLocation
}
$newSamlEndPoints += $newSamlEndPoint
}
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -SamlEndpoint $newSamlEndPointsSet-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -SamlResponseSignature $ADFSRelyingPartyTrust.SamlResponseSignature
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -SignatureAlgorithm $ADFSRelyingPartyTrust.SignatureAlgorithm
Set-ADFSRelyingPartyTrust -TargetIdentifier $rpIdentifier -TokenLifetime $ADFSRelyingPartyTrust.TokenLifetime
}
# For comparison testing you can uncomment these lines
# to export your new import as a ___.XML.new file
# $targetADFSRelyingPartyTrust = Get-ADFSRelyingPartyTrust -Identifier $rpIdentifier
# $filePath = $xmlFile + “.new”
# $AdfsRelyingPartyTrust | Export-Clixml $filePath
}
Reference – https://blog.keyfactor.com/migrating-relying-party-trusts
No Comments