Making this chunk of code a little cleaner. (Counting values).

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 3 years, 9 months ago.

  • Author
    Posts
  • #9866
    Profile photo of Troy Helms
    Troy Helms
    Participant

    I'm working with some values I have in an ADFS configuration. I'm trying to add values back in, based on values I'm pulling back out of a CLIXML file.

    Manually, I can do the commands I need all day. I'm wanting to automate the process, but I'm lacking some of the skills to handle what I want to do. Any help is appreciated.

    Here is the example of how to add SAMLEndpoints on a ClaimsProviderTrust:


    $samlEndpoint1 = New-ADFSSamlEndpoint -Protocol 'SAMLAssertionConsumer' -Uri 'https://samlsts1.contoso.com/samlprp-0/' -Binding 'POST' -IsDefault $false -Index 0
    $samlEndpoint2 = New-ADFSSamlEndpoint -Protocol 'SAMLAssertionConsumer' -Uri ''https://samlsts1.contoso.com/samlprp-0/samlprp-0/Consumer.aspx' -Binding 'POST' -IsDefault $true -Index 1
    $samlEndpoint3 = New-ADFSSamlEndpoint -Protocol 'SAMLLogout' -Uri ''https://samlsts1.contoso.com/samlprp-0/Logout.aspx' -ResponseUri ''https://samlsts1.contoso.com/samlprp-0/LogoutResponse.aspx' -Binding 'Redirect'
    $samlEndpoint4 = New-ADFSSamlEndpoint -Protocol 'SAMLLogout' -Uri ''https://samlsts1.contoso.com/samlprp-0/Logout.aspx' -ResponseUri ''https://samlsts1.contoso.com/samlprp-0/LogoutResponse.aspx' -Binding 'POST'

    Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint @($samlEndpoint1, $samlEndpoint2, $samlEndpoint3, $samlEndpoint4)

    The first lines build the variables, the last line applies them. Easy enough.

    The challenge comes in for me, because nothing is static in the configurations, I'm not sure how to automate it in a script.

    For example, it could have 1 endpoint, it could have 4 endpoints, etc.

    Here is a sample:

    Binding : Redirect
    BindingUri : urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
    Index : 0
    IsDefault : False
    Location : https://contoso.com/Consumer.aspx
    Protocol : SAMLSingleSignOn
    ResponseLocation :

    Binding : POST
    BindingUri : urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
    Index : 0
    IsDefault : False
    Location : https://someotherurl.com/sso
    Protocol : SAMLSingleSignOn
    ResponseLocation :

    I'm not sure how to determine how to count the endpoints, then add them back in based on the number.

    I can get the total count with $v.SamlEndpoints.Count (in this example, it's 2).

    I was going to build several sections of code based on the count # like this:

    If ($v.SamlEndpoints.Count -eq 1) {
    $samlEndpoint1 = New-ADFSSamlEndpoint -Protocol $v.SamlEndpoints.Protocol -Uri $v.SamlEndpoints.Location -Binding $v.SamlEndpoints.Binding -IsDefault $v.SamlEndpoints.IsDefault -Index $v.SamlEndpoints.Index -ResponseUri $v.SamlEndpoints.ResponseLocation
    Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint @($samlEndpoint1)
    }

    ElseIf ($v.SamlEndpoints.Count -eq 2) {
    $samlEndpoint1 = New-ADFSSamlEndpoint -Protocol $v.SamlEndpoints.Item(1).Protocol -Uri $v.SamlEndpoints.Item(1).Location -Binding $v.SamlEndpoints.Item(1).Binding -IsDefault $v.SamlEndpoints.Item(1).IsDefault -Index $v.SamlEndpoints.Item(1).Index -ResponseUri $v.SamlEndpoints.Item(1).ResponseLocation
    $samlEndpoint1 = New-ADFSSamlEndpoint -Protocol $v.SamlEndpoints.Item(2).Protocol -Uri $v.SamlEndpoints.Item(2).Location -Binding $v.SamlEndpoints.Item(2).Binding -IsDefault $v.SamlEndpoints.Item(2).IsDefault -Index $v.SamlEndpoints.Item(2).Index -ResponseUri $v.SamlEndpoints.Item(2).ResponseLocation
    Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint @($samlEndpoint1, $samlEndpoint2)
    }

    Although I think that will work, it seems like there is a better way. Any suggestions?

  • #9867
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    I haven't used the ADFS cmdlets you're using, so I can't say at this point whether there are any problems with that syntax. It looks like all you need is a foreach loop, though:

    foreach ($endpoint in $v.SamlEndpoints)
    {
        $samlEndpoint = New-ADFSSamlEndpoint -Protocol $endpoint.Protocol -Uri $endpoint.Location -Binding $endpoint.Binding -IsDefault $endpoint.IsDefault -Index $endpoint.Index -ResponseUri $endpoint.ResponseLocation    
        Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint $samlEndpoint
    }
    

    This still looks a bit odd to me, though... $v.SamlEndpoints looks like it might already be a collection of the same types of objects returned by New-ADFSSamlEndpoint. If so, you could even ditch the loop and just do this with one command:

    Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint $v.SamlEndpoints
    
  • #9868
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Actually, the way I wrote the foreach loop may not work, as it's not exactly what you were doing with multiple endpoints (in my example, there was a separate call to Set-ADFSRelyingPartyTrust for each endpoint, instead of one call that passes in the whole list).

    I'm not sure if that difference will matter, but just in case it does, here's a way to use a foreach loop and still only make a single call to Set-ADFSRelyingPartyTrust (assuming you can't just pass $v.SamlEndpoints to the cmdlet, as I mentioned). There are several ways you could write this to get identical results; this one just required the fewest changes to what I had already posted:

    $endpoints = foreach ($endpoint in $v.SamlEndpoints)
    {
        New-ADFSSamlEndpoint -Protocol $endpoint.Protocol -Uri $endpoint.Location -Binding $endpoint.Binding -IsDefault $endpoint.IsDefault -Index $endpoint.Index -ResponseUri $endpoint.ResponseLocation    
    }
    
    Set-ADFSRelyingPartyTrust -TargetName samlpsite3-0 -SamlEndpoint $endpoints
    
  • #9871
    Profile photo of Troy Helms
    Troy Helms
    Participant

    Thanks so much! That worked perfectly. Just incase anyone is looking for a way to export/import a Claims Provider Trust on AD FS 2.x, in full, here is my script I finished.
    #========================================================================
    # Created with: SAPIEN Technologies, Inc., PowerShell Studio 2012 v3.1.22
    # Created on: 8/30/2013 3:27 PM
    # Created by: Troy D. Helms
    # Filename: Import-CPTrust.ps1
    #========================================================================

    #Imports the PS Object in full from an export file made using the following line:
    # Get-ADFSClaimProviderTrust -name "CPTrustName" | Export-CLIXML ExportedClaimsProviderTrust.xml
    $CPTrust = Import-Clixml ExportedClaimsProviderTrust.xml

    #Creates the "stub" ClaimsProviderTrust in ADFS with the most basic values. (It also puts in all TokenSigningCertificates at once!)
    Add-ADFSClaimsProviderTrust -Identifier $CPTrust.Identifier -Name $CPTrust.Name -TokenSigningCertificate $CPTrust.TokenSigningCertificates

    #Each of the following lines sets the values for the ClaimsProviderTrust if they aren't null to match the original export.
    If ($CPTrust.AcceptanceTransformRules) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -AcceptanceTransformRules $CPTrust.AcceptanceTransformRules}
    If ($CPTrust.AllowCreate) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -AllowCreate $CPTrust.AllowCreate}
    If ($CPTrust.EncryptedNameIdRequired) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -EncryptedNameIdRequired $CPTrust.EncryptedNameIdRequired}
    If ($CPTrust.EncryptionCertificate) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -EncryptionCertificate $CPTrust.EncryptionCertificate}
    If ($CPTrust.EncryptionCertificateRevocationCheck) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -EncryptionCertificateRevocationCheck $CPTrust.EncryptionCertificateRevocationCheck}
    If ($CPTrust.MetadataUrl) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -MetadataUrl $CPTrust.MetadataUrl}
    If ($CPTrust.MonitoringEnabled) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -MonitoringEnabled $CPTrust.MonitoringEnabled}
    If ($CPTrust.Notes) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -Notes $CPTrust.Notes}
    If ($CPTrust.ProtocolProfile) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -ProtocolProfile $CPTrust.ProtocolProfile}
    If ($CPTrust.RequiredNameIdFormat) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -RequiredNameIdFormat $CPTrust.RequiredNameIdFormat}
    If ($CPTrust.SamlAuthenticationRequestIndex) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SamlAuthenticationRequestIndex $CPTrust.SamlAuthenticationRequestIndex}
    If ($CPTrust.SamlAuthenticationRequestParameters) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SamlAuthenticationRequestParameters $CPTrust.SamlAuthenticationRequestParameters}
    If ($CPTrust.SamlAuthenticationRequestProtocolBinding) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SamlAuthenticationRequestProtocolBinding $CPTrust.SamlAuthenticationRequestProtocolBinding}
    If ($CPTrust.SignatureAlgorithm) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SignatureAlgorithm $CPTrust.SignatureAlgorithm}
    If ($CPTrust.SignedSamlRequestsRequired) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SignedSamlRequestsRequired $CPTrust.SignedSamlRequestsRequired}
    If ($CPTrust.SigningCertificateRevocationCheck) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SigningCertificateRevocationCheck $CPTrust.SigningCertificateRevocationCheck}
    If ($CPTrust.WSFedEndpoint) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -WSFedEndpoint $CPTrust.WSFedEndpoint}

    #This creates the SAMLEndpoints if there are any.
    If ($CPTrust.SamlEndpoints) {
    $endpoints = foreach ($endpoint in $CPTrust.SamlEndpoints) {New-ADFSSamlEndpoint -Protocol $endpoint.Protocol -Uri $endpoint.Location -Binding $endpoint.Binding -IsDefault $endpoint.IsDefault -Index $endpoint.Index -ResponseUri $endpoint.ResponseLocation}

    Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -SamlEndpoint $endpoints
    }

    #The only values I have yet to understand how to migrate on a ClaimsProviderTrust is the ClaimsOffered & the Organization data.
    #Claims offered SHOULD work using something like this line:
    #If ($CPTrust.ClaimsOffered) {Set-ADFSClaimsProviderTrust -TargetName $CPTrust.name -ClaimOffered $CPTrust.ClaimsOffered}
    #However, I can't make it work. Lots of trial and error, with no success. It's not important for what I'm doing, but it would be nice to handle it.
    #Organization information doesn't seem to have a parameter on the Set-ADFSClaimsProviderTrust cmdlet to actually add it.
    #I considered tossing that information into the NOTES section, since it's informational only anyway.

  • #9892
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Two suggestions for you. First, look at the help for Set-ADFSClaimsProviderTrust. As an example, look at 'Get-Help Copy-Item -Full' and pay attention to Accept pipeline input. If it shows True, by property name, then you can pass the object directly to the command (i.e. $CPTrust | Set-ADFSClaimsProviderTrust). The cmdlet should eliminate null values and process the passed params if the columns match the parameters (or Alias).

    -Path
    Specifies the path to the items to copy.

    Required? true
    Position? 1
    Default value
    Accept pipeline input? true (ByValue, ByPropertyName)
    Accept wildcard characters? false

    Second suggestion if the cmdlet does NOT accept pipeline, use a splat and run a single command for the targetname versus running a command for each parameter:

    PS C:\Windows\system32> 
    #Empty object to emulate data
    #Note the different properties populated with null values
    $CPTrust = @()
     
    $CPTrust += New-Object –TypeName PSObject -Property `
            (@{'TargetName'="MyTarget1"; 
                'AcceptanceTransformRules'= "rule";
                'AllowCreate'= "True";
                'EncryptedNameIdRequired'= $null;
                'EncryptionCertificate'= $null;
                'EncryptionCertificateRevocationCheck'= $null;
                'MetadataUrl'= $null;
                'MonitoringEnabled'= $null;
                'Notes'= "Example Splat";
                'ProtocolProfile'= "4";
                'RequiredNameIdFormat'= $null;
                'SamlAuthenticationRequestIndex'= $null;
                'SamlAuthenticationRequestParameters'= $null;
                'SamlAuthenticationRequestProtocolBinding'= $null;
                'SignatureAlgorithm'= "E=Mc2";
                'SignedSamlRequestsRequired'= "True";
                'SigningCertificateRevocationCheck'= "False";
                'WSFedEndpoint'= "MyEndPoint";})
    
    $CPTrust += New-Object –TypeName PSObject -Property `
            (@{'TargetName'="MyTarget2"; 
                'AcceptanceTransformRules'= "anotherrule";
                'AllowCreate'= $null;
                'EncryptedNameIdRequired'= "True";
                'EncryptionCertificate'= $null;
                'EncryptionCertificateRevocationCheck'= "False";
                'MetadataUrl'= "www.mymeta.com";
                'MonitoringEnabled'= $null;
                'Notes'= $null;
                'ProtocolProfile'= $null;
                'RequiredNameIdFormat'= $null;
                'SamlAuthenticationRequestIndex'= "2";
                'SamlAuthenticationRequestParameters'= $null;
                'SamlAuthenticationRequestProtocolBinding'= $null;
                'SignatureAlgorithm'= "E=Mc2";
                'SignedSamlRequestsRequired'= "True";
                'SigningCertificateRevocationCheck'= "False";
                'WSFedEndpoint'= "MyEndPoint";})
    
    
    
    foreach ($row in $CPTrust) { 
        #Create empty hash table for Splatting
        $params = @{}
        foreach ($column in $row.PSObject.Properties) {
            #if the value is not null, add it to the Splat hash table
            if ($column.Value) {$params.add($column.Name,$column.Value)}
         }
        #Set-ADFSClaimsProviderTrust $params
        $params
    }
    
    
    
    Name                           Value                                                                                                                                                                     
    ----                           -----                                                                                                                                                                     
    TargetName                     MyTarget1                                                                                                                                                                 
    SignatureAlgorithm             E=Mc2                                                                                                                                                                     
    WSFedEndpoint                  MyEndPoint                                                                                                                                                                
    Notes                          Example Splat                                                                                                                                                             
    SigningCertificateRevocatio... False                                                                                                                                                                     
    AcceptanceTransformRules       rule                                                                                                                                                                      
    SignedSamlRequestsRequired     True                                                                                                                                                                      
    AllowCreate                    True                                                                                                                                                                      
    ProtocolProfile                4                                                                                                                                                                         
    
    TargetName                     MyTarget2                                                                                                                                                                 
    SamlAuthenticationRequestIndex 2                                                                                                                                                                         
    SignatureAlgorithm             E=Mc2                                                                                                                                                                     
    WSFedEndpoint                  MyEndPoint                                                                                                                                                                
    MetadataUrl                    www.mymeta.com                                                                                                                                                            
    EncryptedNameIdRequired        True                                                                                                                                                                      
    SigningCertificateRevocatio... False                                                                                                                                                                     
    AcceptanceTransformRules       anotherrule                                                                                                                                                               
    SignedSamlRequestsRequired     True                                                                                                                                                                      
    EncryptionCertificateRevoca... False
    

You must be logged in to reply to this topic.