Copy-RelyingPartyTrust.ps1
<#PSScriptInfo .VERSION 1.1 .GUID 3e549ec2-6bd5-4ddc-833f-a4e732753bd3 .AUTHOR Brad.Held@Microsoft.com .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES Currently tested on ADFS 2019, but should also work for ADFS 2016 .PRIVATEDATA #> <# .DESCRIPTION Exports a Relying Party Trust from ADFS farm and allows importing into a different ADFS farm. -Example Export: Copy-RelyingPartyTrust.ps1 -sourceRPID testing:saml:com -path C:\Folder -filename SamlTest.json -import false Note: Based on configuration of RP may create 3-4 files - all files need to be moved to the new farm Example Import: Copy-RelyingPartyTrust.ps1 -sourceRPID testing:saml:com -path C:\Folder -filename SamlTest.json -import true #> Param([Parameter(Mandatory = $true)] [String] $sourceRPID, [Parameter(Mandatory = $true)] [String] $path, [Parameter(Mandatory = $true)] [String] $filename, [ValidateSet("true","True","false","False")] [Parameter(Mandatory = $false)] [String] $import = "false" ) #Returns the identifier for the RP function Get-sRpIdentifier { [string]$rpidentifier = ""; $identifiers = Get-AdfsRelyingPartyTrust | Select-Object Identifier; foreach($id in $identifiers.Identifier) { if($id.IndexOf($sourceRPID, [System.StringComparison]::OrdinalIgnoreCase) -ge 0) { $rpidentifier = $id; break; } } if ($rpidentifier -eq "") { throw "Unable to get the ADFS source relying party trust identifier."; } return $rpidentifier; } #Backup Target RP function store-RP { $rp = Get-AdfsRelyingPartyTrust -Identifier $(Get-sRpIdentifier); $rpName = $rp.Name; $currentpath = Resolve-Path -Path $path $filenameJSON = "$currentpath$filename"; $rp | ConvertTo-Json | out-file $filenameJSON; Write-Host = "Completed exporting Relying PartyTrust: $filenameJSON"; Backup-IssuanceTransformRules; Backup-IssuanceAuthorizationRules; Backup-AdditionalAuthenticationRules; return $rp } #Backup Claim Issuance rules function Backup-IssuanceTransformRules { $issuanceRules = "$currentpath\Claims-$filename"; $claims = $rp | Select-Object IssuanceTransformRules; $stream = [System.IO.StreamWriter] $issuanceRules foreach($claim in $claims.IssuanceTransformRules) { $stream.WriteLine($claim); } $stream.close(); Write-Host = "Backup file with claim rules created: $issuanceRules"; return } #Backup Issuance Authorization Rules function Backup-IssuanceAuthorizationRules { $authRules = "$currentpath\Authorization-$filename"; $auths = $rp | Select-Object IssuanceAuthorizationRules; if ($auths -ne "" -and $auths -ne $null){ $stream = [System.IO.StreamWriter] $authRules foreach($auth in $auths.IssuanceAuthorizationRules) { $stream.WriteLine($auth); } $stream.close(); Write-Host = "Backup file with authorization rules created: $authRules"; } return } #Backup Additional Authentication Rules function Backup-AdditionalAuthenticationRules { $addRules = "$currentpath\Additional-$filename"; $adds = $rp | Select-Object AdditionalAuthenticationRules; $boolHasValue = $false; foreach ($add in $adds.AdditionalAuthenticationRules){ if ($add -ne "" -and $add -ne $null){ $boolHasValue = $true; } } if ($boolHasValue){ $stream = [System.IO.StreamWriter] $addRules foreach($add in $adds.AdditionalAuthenticationRules) { $stream.WriteLine($add); } $stream.close(); Write-Host = "Backup file with AdditionalAuthenticationRules rules created: $addRules"; } return } function import-RP { #Using Hashtable to collect all of the parameters and then splat them into add-adfsrelyingpartytrust $hashTable = @{}; $rawRP = Get-Content -Path $path$filename | ConvertFrom-Json; #$issueruleset = New-AdfsClaimRuleSet -ClaimRuleFile "$path\Claims-$filename"; $hashTable.add("Name", $rawRP.Name); $hashTable.add("Identifier", $rawRP.Identifier); #$hashTable.add("IssuanceTransformRulesFile", $issueruleset); #boolean values $hashTable.add("EncryptClaims", [System.Convert]::ToBoolean($rawRP.EncryptClaims)); $hashTable.add("Enabled", [System.Convert]::ToBoolean($rawRP.Enabled)); $hashTable.add("AutoUpdateEnabled", [System.Convert]::ToBoolean($rawRP.AutoUpdateEnabled)); $hashTable.add("EncryptedNameIdRequired", [System.Convert]::ToBoolean($rawRP.EncryptedNameIdRequired)); $hashTable.add("SignedSamlRequestsRequired", [System.Convert]::ToBoolean($rawRP.SignedSamlRequestsRequired)); $hashTable.add("AlwaysRequireAuthentication", [System.Convert]::ToBoolean($rawRP.AlwaysRequireAuthentication)); $hashTable.add("RequestMFAFromClaimsProviders", [System.Convert]::ToBoolean($rawRP.RequestMFAFromClaimsProviders)); $hashTable.add("EnableJWT", [System.Convert]::ToBoolean($rawRP.EnableJWT)); $hashTable.add("RefreshTokenProtectionEnabled", [System.Convert]::ToBoolean($rawRP.RefreshTokenProtectionEnabled)); $hashTable.add("MonitoringEnabled", [System.Convert]::ToBoolean($rawRP.MonitoringEnabled)); #certificate values #Encryption Certificate - There can only be one if ($rawRP.EncryptionCertificate -ne "" -and $rawRP.EncryptionCertificate -ne $null){ $enc = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($rawRP.EncryptionCertificate.RawData))) $hashTable.add("EncryptionCertificate", $enc); } #Signing Certificates - There may be more that one configured if ($rawRP.RequestSigningCertificate -ne "" -and $rawRP.RequestSigningCertificate -ne $null){ $i = 0; foreach ($signingCert in $rawRP.RequestSigningCertificate) { $tmpString = $signingCert.RawData; [byte[]]$tmpBytes = @($tmpString.Split(" ")); if ($i -eq 0) { $tmpCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($tmpBytes))) $certs = @($tmpCert); $i += 1; }else { $tmpCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String([System.Convert]::ToBase64String($tmpBytes))) $certs += $tmpCert; $i += 1; } } $hashTable.add("RequestSigningCertificate", $certs); } #uris if ($rawRP.WSFedEndPoint -ne "" -and $rawRP.WSFedEndPoint -ne $null){ $hashTable.add("WSFedEndPoint", [System.Uri]$rawRP.WSFedEndPoint); } #text/misc values if ($rawRP.Notes -ne "" -and $rawRP.Notes -ne $null){ $hashTable.add("Notes", $rawRP.Notes); } else { $dt = Get-Date; $hashTable.add("Notes", $dt); } if ($rawRP.ClaimAccepted -ne "" -and $rawRP.ClaimAccepted -ne $null){ $hashTable.add("ClaimAccepted", $rawRP.ClaimAccepted); } if ($rawRP.TokenLifetime -ne "" -and $rawRP.TokenLifetime -ne $null){ $hashTable.add("TokenLifetime", $rawRP.TokenLifetime); } if ($rawRP.NotBeforeSkew -ne "" -and $rawRP.NotBeforeSkew -ne $null){ $hashTable.add("NotBeforeSkew", $rawRP.NotBeforeSkew); } if ($rawRP.ProtocolProfile -ne "" -and $rawRP.ProtocolProfile -ne $null){ $hashTable.add("ProtocolProfile", $rawRP.ProtocolProfile); } if ($rawRP.SignatureAlgorithm -ne "" -and $rawRP.SignatureAlgorithm -ne $null){ $hashTable.add("SignatureAlgorithm", $rawRP.SignatureAlgorithm); } if ($rawRP.SamlResponseSignature -ne "" -and $rawRP.SamlResponseSignature -ne $null){ $hashTable.add("SamlResponseSignature", $rawRP.SamlResponseSignature); } if ($rawRP.AllowedClientTypes -ne "" -and $rawRP.AllowedClientTypes -ne $null){ $hashTable.add("AllowedClientTypes", $rawRP.AllowedClientTypes); } if ($rawRP.IssueOAuthRefreshTokensTo -ne "" -and $rawRP.IssueOAuthRefreshTokensTo -ne $null){ $hashTable.add("IssueOAuthRefreshTokensTo", $rawRP.IssueOAuthRefreshTokensTo); } if ($rawRP.AdditionalWSFedEndpoint -ne "" -and $rawRP.AdditionalWSFedEndpoint -ne $null){ $hashTable.add("AdditionalWSFedEndpoint", $rawRP.AdditionalWSFedEndpoint); } if ($rawRP.AllowedAuthenticationClassReferences -ne "" -and $rawRP.AllowedAuthenticationClassReferences -ne $null){ $hashTable.add("AllowedAuthenticationClassReferences", $rawRP.AllowedAuthenticationClassReferences); } switch ($rawRP.SigningCertificateRevocationCheck){ 0 { $hashTable.add("SigningCertificateRevocationCheck", 'None'); } 1 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckEndCert'); } 2 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckEndCertCacheOnly'); } 3 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckChain'); } 4 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainCacheOnly'); } 5 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainExcludeRoot'); } 6 { $hashTable.add("SigningCertificateRevocationCheck", 'CheckChainExcludeRootCacheOnly'); } } switch ($rawRP.EncryptionCertificateRevocationCheck){ 0 { $hashTable.add("EncryptionCertificateRevocationCheck", 'None'); } 1 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckEndCert'); } 2 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckEndCertCacheOnly'); } 3 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChain'); } 4 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainCacheOnly'); } 5 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainExcludeRoot'); } 6 { $hashTable.add("EncryptionCertificateRevocationCheck", 'CheckChainExcludeRootCacheOnly'); } } $newRP = Add-AdfsRelyingPartyTrust @hashTable; #Add SAML Endpoints if neccesary if ($rawRP.SamlEndpoints -ne "" -and $rawRP.SamlEndpoints -ne $null){ $EPs = New-Object -TypeName "System.Collections.ArrayList"; foreach ($saml in $rawRP.SamlEndpoints){ $Binding = $saml.Binding; $Index = $saml.Index; $IsDefault = $saml.IsDefault; $Protocol = $saml.Protocol; $Uri = $saml.Location; if ($saml.ResponseLocation -ne "null") { $ResponseUri = $saml.ResponseLocation; $EP = New-AdfsSamlEndpoint -Binding $Binding -Index $Index -IsDefault $IsDefault -Protocol $Protocol -Uri $Uri -ResponseUri $ResponseUri; } else { $EP = New-AdfsSamlEndpoint -Binding $Binding -Index $Index -IsDefault $IsDefault -Protocol $Protocol -Uri $Uri; } #write-host $Uri; $EPs.Add($EP); } Set-AdfsRelyingPartyTrust -TargetIdentifier $sourceRPID -SamlEndpoint $EPs; } #Get the claim rules/authorization/additional authentication created Import-Claims; } function Import-Claims { $issuanceRules = "$path\Claims-$filename"; if (Test-Path $issuanceRules -PathType Leaf) { #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $issuanceRules; Set-AdfsRelyingPartyTrust -TargetIdentifier $sourceRPID -IssuanceTransformRulesFile $issuanceRules; } $authorizationRules = "$path\Authorization-$filename"; if (Test-Path $authorizationRules -PathType Leaf) { #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $authorizationRules; Set-AdfsRelyingPartyTrust -TargetIdentifier $sourceRPID -IssuanceAuthorizationRulesFile $authorizationRules; } $additionalRules = "$path\Additional-$filename"; if (Test-Path $additionalRules -PathType Leaf) { #$ruleset = New-AdfsClaimRuleSet -ClaimRuleFile $additionalRules; Set-AdfsRelyingPartyTrust -TargetIdentifier $sourceRPID -IssuanceAuthorizationRulesFile $additionalRules; } } function Validate-RP { $rp = Get-AdfsRelyingPartyTrust -Identifier $sourceRPID; if ($rp -ne $null) { throw "Relying Party Trust already exists."; } else { $Result = import-RP; $Result; } } switch($import){ true{} True{ Validate-RP; break } false{} False{ $savedRP = store-RP; break } Default { throw "Invalid -import parameter. Use True or False";} } |