Coder Social home page Coder Social logo

adfsdsc's Introduction

AdfsDsc

Build Status Azure DevOps coverage (branch) codecov Azure DevOps tests PowerShell Gallery (with prereleases) PowerShell Gallery

The AdfsDsc module contains DSC resources for deployment and configuration of Active Directory Federation Services.

These DSC resources allow you to configure a new ADFS server farm, add new server nodes to an existing ADFS server farm and manage the configuration of ADFS, relying party trusts, pplication groups and associated resources.

Code of Conduct

This project has adopted this Code of Conduct.

Releases

For each merge to the branch main a preview release will be deployed to PowerShell Gallery. Periodically a release version tag will be pushed which will deploy a full release to PowerShell Gallery.

Documentation and Examples

For a full list of resources in AdfsDsc and examples on their use, check out the AdfsDsc wiki.

Contributing

Please check out common DSC Community contributing guidelines.

Change log

A full list of changes in each version can be found in the change log.

adfsdsc's People

Contributors

watschi avatar x-guardian avatar yvand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

adfsdsc's Issues

AdfsWebApiApplication: Add Support for Custom Access Control Policy Parameters

To support custom Access Control Policy Parameters, the MSFT_AdfsAccessControlPolicyParameters class needs extending with the following additional parameters:

Parameter Type ValueMap Description
ClaimsParameter MSFT_AdfsClaim Array Specifies the claims to match in the request
GroupExceptionParameter String Array Specifies the exception group name
ClaimsExceptionParameter MSFT_AdfsClaim Array Specifies the exception claims to match in the request

The MSFT_AdfsClaim class would contain the following properties:

Parameter Type ValueMap Description
ClaimType String Specifies the claim type
Operator String "Equals", "IsPresent", "RegexMatches", "Contains", "StartsWith", "EndsWith", "IssuerEquals", "OriginalIssuerEquals" Specifies the claim operator
Value String Specifies the claim value

Example AccessControlPolicyParameters property:

AccessControlPolicyParameters = MSFT_AdfsAccessControlPolicyParameter
@{
    GroupParameter           = @(
        'CONTOSO\AppGroup1 Users'
        'CONTOSO\AppGroup1 Admins'
    )
    ClaimsParameter          = @(
        MSFT_AdfsClaim
        {
            ClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'
            Operator  = 'Equals'
            Value     = 'test'
        }
    )
    GroupExceptionParameter  = @(
        'CONTOSO\AppGroup1 Banned Users'
        'CONTOSO\AppGroup1 Banned Admins'
    )
    ClaimsExceptionParameter = @(
        MSFT_AdfsClaim
        {
            ClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'
            Operator  = 'Equals'
            Value     = 'test2'
        }
    )
}

AdfsProperties: The property 'AdditionalErrorPageInfo' cannot be found on this object

Details of the scenario you tried and the problem that is occurring

Tried to apply the MonitoringInterval but got an error when applying.

Verbose logs showing the problem

2021-04-08T10:44:56.0757773Z VERBOSE: Operation 'Invoke CimMethod' complete.
2021-04-08T10:44:56.0776905Z VERBOSE: Set-DscLocalConfigurationManager finished in 0.133 seconds.
2021-04-08T10:44:56.0988928Z VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = 
2021-04-08T10:44:56.0990018Z SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = 
2021-04-08T10:44:56.0990891Z root/Microsoft/Windows/DesiredStateConfiguration'.
2021-04-08T10:44:56.1093095Z VERBOSE: An LCM method call arrived from computer SOP-STAGE-APP03 with user sid 
2021-04-08T10:44:56.1098768Z S-1-5-21-2909328277-3842075283-3334363682-1364.
2021-04-08T10:44:56.1161952Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Start  Set      ]
2021-04-08T10:44:56.4059235Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Start  Resource ]  [[AdfsProperties]CommonAdfsProperties]
2021-04-08T10:44:56.4064873Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Start  Test     ]  [[AdfsProperties]CommonAdfsProperties]
2021-04-08T10:44:56.4190014Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[AdfsProperties]CommonAdfsProperties] Testing 
2021-04-08T10:44:56.4190472Z 'adfs-stage.contosocrm.se'. (PRO002)
2021-04-08T10:44:56.4238864Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[AdfsProperties]CommonAdfsProperties] Getting 
2021-04-08T10:44:56.4241754Z 'adfs-stage.contosocrm.se'. (PRO001)
2021-04-08T10:44:57.2267313Z The property 'AdditionalErrorPageInfo' cannot be found on this object. Verify that the property exists.
2021-04-08T10:44:57.2267826Z     + CategoryInfo          : NotSpecified: (:) [], CimException
2021-04-08T10:44:57.2268154Z     + FullyQualifiedErrorId : PropertyNotFoundStrict
2021-04-08T10:44:57.2269666Z     + PSComputerName        : sop-stage-adfs1.stagead.contosocrm.se
2021-04-08T10:44:57.2269958Z  
2021-04-08T10:44:57.2282809Z Cannot bind argument to parameter 'CurrentValues' because it is null.
2021-04-08T10:44:57.2283433Z     + CategoryInfo          : InvalidData: (:) [], CimException
2021-04-08T10:44:57.2283792Z     + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Compare-ResourcePropertyState
2021-04-08T10:44:57.2284159Z     + PSComputerName        : sop-stage-adfs1.stagead.contosocrm.se
2021-04-08T10:44:57.2284384Z  
2021-04-08T10:44:57.2292272Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[AdfsProperties]CommonAdfsProperties] 'adfs-stage.contosocrm.se'
2021-04-08T10:44:57.2293599Z  is in the desired state. (PRO005)
2021-04-08T10:44:57.2304969Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ End    Test     ]  [[AdfsProperties]CommonAdfsProperties]  in 0.8130 seconds.
2021-04-08T10:44:57.2419254Z The PowerShell DSC resource '[AdfsProperties]CommonAdfsProperties' with SourceInfo 'C:\AzurePipelineAgent\_work\1\platf
2021-04-08T10:44:57.2419830Z orm\src\platform\configuration\adfs-config.ps1::19::9::AdfsProperties' threw one or more non-terminating errors while r
2021-04-08T10:44:57.2420284Z unning the Test-TargetResource functionality. These errors are logged to the ETW channel called Microsoft-Windows-DSC/O
2021-04-08T10:44:57.2420600Z perational. Refer to this channel for more details.
2021-04-08T10:44:57.2420916Z     + CategoryInfo          : InvalidOperation: (:) [], CimException
2021-04-08T10:44:57.2421220Z     + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
2021-04-08T10:44:57.2421607Z     + PSComputerName        : sop-stage-adfs1.stagead.contosocrm.se
2021-04-08T10:44:57.2421844Z  
2021-04-08T10:44:57.2563915Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Start  Resource ]  [[Script]KronobergClaimProvider]
2021-04-08T10:44:57.2569399Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Start  Test     ]  [[Script]KronobergClaimProvider]
2021-04-08T10:44:57.3041154Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[Script]KronobergClaimProvider] AdfsClaimsProviderTrust found
2021-04-08T10:44:57.3071594Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[Script]KronobergClaimProvider] MetadataUrl matches
2021-04-08T10:44:57.3093652Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[Script]KronobergClaimProvider] MonitoringEnabled is true
2021-04-08T10:44:57.3114280Z VERBOSE: [SOP-STAGE-ADFS1]:                            [[Script]KronobergClaimProvider] AutoUpdateEnabled is true
2021-04-08T10:44:57.3231471Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ End    Test     ]  [[Script]KronobergClaimProvider]  in 0.1250 seconds.
2021-04-08T10:44:57.3242442Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ Skip   Set      ]  [[Script]KronobergClaimProvider]
2021-04-08T10:44:57.3250453Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ End    Resource ]  [[Script]KronobergClaimProvider]
2021-04-08T10:44:57.3257729Z VERBOSE: [SOP-STAGE-ADFS1]: LCM:  [ End    Set      ]
2021-04-08T10:44:57.3560301Z The SendConfigurationApply function did not succeed.
2021-04-08T10:44:57.3561083Z     + CategoryInfo          : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
2021-04-08T10:44:57.3561648Z     + FullyQualifiedErrorId : MI RESULT 1
2021-04-08T10:44:57.3563105Z     + PSComputerName        : sop-stage-adfs1.stagead.contosocrm.se
2021-04-08T10:44:57.3563491Z  
2021-04-08T10:44:57.3573997Z VERBOSE: Operation 'Invoke CimMethod' complete.
2021-04-08T10:44:57.3580709Z VERBOSE: Time taken for configuration job to complete is 1.276 seconds

Suggested solution to the issue

Implement more flexibility in the code for those installations of ADFS where AdditionalErrorPageInfo does not exist in the configuration. Perhaps it might depend on the Windows/ADFS version. In some installations that I maintain, $(Get-AdfsProperties).AdditionalErrorPageInfo returns a value, on the other it returns $null.

The same code works on a Windows 2019 machine without the issue.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

AdfsProperties CommonAdfsProperties
{
    FederationServiceName   = "adfs-stage.contoso.se"
    MonitoringInterval      = 10
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2016 Standard
OsOperatingSystemSKU : StandardServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 14393.4283.amd64fre.rs1_release.210303-1802
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value
----                           -----
PSVersion                      5.1.14393.3866
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.3866
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the DSC module that was used

1.1.0

AdfsWebApiApplication: Add Support for Access Control Policy Parameters

The AdfsWebApiApplication resource needs to support Access Control Policy Parameters.

New resource property required:

Property Name Type Description
AccessControlPolicyParameters MSFT_AdfsAccessControlPolicyParameters Specifies the parameters and their values to pass to the Access Control Policy.

The MSFT_AdfsAccessControlPolicyParameters class would contain the following properties:

Parameter Type ValueMap Description
GroupParameter String Array Specifies the group parameter

This is enough to provide support for the built-in Access Control Policies and the ability to later add support for custom Access Control Policies.

Here are details of the built-in Access Control Policies and what parameters they take:

AccessControlPolicyName                                              AccessControlPolicyParameters
-----------------------                                              -----------------------------
Permit everyone
Permit everyone and require MFA
Permit everyone and require MFA for specific group                   {GroupParameter}
Permit everyone and require MFA from extranet access
Permit everyone and require MFA from unauthenticated devices
Permit everyone and require MFA, allow automatic device registration
Permit everyone for intranet access
Permit specific group                                                {GroupParameter}

Example AccessControlPolicyParameters property:

AccessControlPolicyParameters = MSFT_AdfsAccessControlPolicyParameter
    @{
        GroupParameter = @(
            'CONTOSO\AppGroup1 Users'
            'CONTOSO\AppGroup1 Admins'
        )
    }

AdfsNonClaimsAwareRelyingPartyTrust: New Resource Proposal

Description

This resource is needed to manage non-claims aware relying party trusts.

Proposed properties

Parameter Type ValueMap Description
Name String Specifies the display name of the Web Application Proxy relying party trust.
Identifier String[] Specifies an array of unique identifiers for the non-claims-aware relying party trust. No other trust can use an identifier from this list. As common practice, you can use Uniform Resource Identifiers (URIs) as unique identifiers for a relying party trust, or you can use any string.
AlwaysRequire Authentication Boolean Indicates that access requires authentication, even if this relying party has previously authenticated credentials for access. Specify this parameter to require users to always supply credentials to access sensitive resources.
Enabled Boolean Indicates whether to enable this relying party trust.
Issuance AuthorizationRules String Specifies the authorization rules for issuing claims to the relying party.
Notes String Specifies notes for the relying party trust. Use this parameter to store information such as owners and contacts when you manage a large number of applications.
Additional AuthenticationRules String Specifies rules for additional authentication on the relying party.
AccessControl PolicyName String Specifies the name of the Access Control Policy to apply to the relying party trust.
AccessControl PolicyParameters MSFT_AdfsAccess ControlPolicyParameters Specifies the parameters and their values to pass to the Access Control Policy.
ClaimsProvider Name String[] Specifies an array of claims provider names.
Ensure String 'Present', 'Absent' Specifies whether the non-claims are relying party trust should be present or absent. Default value is 'Present'.

The MSFT_AdfsAccessControlPolicyParameters class would contain the following properties:

Parameter Type ValueMap Description
GroupParameter String Array Specifies the group parameter

Resource Cmdlets

AdfsProperties: Remove Obsolete Properties

Details of the scenario you tried and the problem that is occurring

The PromptLoginFederation and PromptLoginFallbackAuthenticationType properties of the AdfsProperties resource are obsolete and should be removed.

Verbose logs showing the problem

Set-AdfsProperties : PS0346: PromptLoginFederation and PromptLoginFallbackAuthenticationType are obselete. Please set these properties on individual 
Claims Provider Trusts.
At line:1 char:1
+ Set-AdfsProperties -PromptLoginFederation None
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-AdfsProperties], ArgumentException
    + FullyQualifiedErrorId : PS0346,Microsoft.IdentityServer.Management.Commands.SetServicePropertiesCommand

AdfsContactPerson: Add Support for an Empty Contact

Details of the scenario you tried and the problem that is occurring

The AdfsContactPerson resource errors if the current contact person is empty, or if the contact person is set to empty values.

Suggested solution to the issue

Add support for reading and writing an empty contact.

Version of the DSC module that was used ('dev' if using current dev branch)

1.0.0

Reusing instances of MSFT_AdfsIssuanceTransformRule

Is there a way to create instances of MSFT_AdfsIssuanceTransformRule and reuse them in a configuration? I'm creating an AdfsApplicationGroup that contains several AdfsWebApiApplication. I use a standard set of issuance transform rules with each of them and would like to define that set once (e.g. as a variable) and reuse that set with each application. As it stands, I'm having to redefine the collection in AdfsWebApiApplication.IssuanceTransformRules of each application definition.

AdfsWebApiApplication fails Test for CustomClaims IssuanceTransformRules

Hi,

I'm trying to setup a WebApi application, which just works great.
But the test always comes back as non-compliant, but the verbose logs shows absolutely nothing to be non compliant.

After digging into the module, I found the issue - I create two IssuanceTransformRules using the module, which works great.
But evaluating if there are two rules - with only one rule, it works fine.

I tried outputting the content of $propertiesNotInDesiredState as it had a count of 1, where I expected 0.

VERBOSE: [ADFS001]: [[AdfsWebApiApplication]afmotorWebAPI] Testing: 1
VERBOSE: [ADFS001]: [[AdfsWebApiApplication]afmotorWebAPI] key Expected ParameterName InDesiredState Actual Microsoft.Management.Infrastructure.CimInstance[] IssuanceTransformRules False Microsoft.Management.
Infrastructure.CimInstance[]

To me, it seems the compare function can't handle multiple instances of IssuanceTransformRules

My two rules are:

       IssuanceTransformRules        = @(
          MSFT_AdfsIssuanceTransformRule
           {
               TemplateName = 'CustomClaims'
               Name         = 'Issue NameIdentifier'
               CustomRule   = 'c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"), query = ";givenName;{0}", param = c.Value);'

           }
           MSFT_AdfsIssuanceTransformRule
           {
               TemplateName       = 'EmitGroupClaims'
               Name               = 'GroupClaims'
               GroupName          = "SendingGroup"
               OutgoingClaimType  = 'http://schemas.xmlsoap.org/claims/Group'
               OutgoingClaimValue = 'Smurf'
           }
       )

AdfsCertificate: TokenSigningCertificates Add-ADFSCertificate missing?

Details of the scenario you tried and the problem that is occurring

Problem occurs when configuring fresh ADFS farm and trying to set 'token-signing' certificate with AdfsCertificate.

I get the error: PS0006: The IsPrimary parameter must be specified when a Token-Encryption or Token-Signing certificate is specified. But the real problem is that the certificate is not added in the first place.

Verbose logs showing the problem

Code="VMExtensionProvisioningError" Message="VM has reported a failure when processing extension 'TestDSC'. Error message: \"DSC Configuration 'CreateRootDomain' completed with error(s). Following are the first few: PowerShell DSC resource MSFT_AdfsCertificate  failed to execute Set-TargetResource functionality with error message: System.InvalidOperationException: Error setting 'Token-Signing'. (CERERR002) ---> System.ArgumentException: PS0006: The IsPrimary parameter must be specified when a Token-Encryption or Token-Signing certificate is specified.
   at Microsoft.IdentityServer.Management.Commands.SetCertificateCommand.DoProcessing()
   at Microsoft.IdentityServer.Management.Commands.SetCertificateCommand.EndProcessingOverride()
   --- End of inner exception stack trace ---  PowerShell DSC resource MSFT_AdfsCertificate  failed to execute Set-TargetResource functionality with error message: System.InvalidOperationException: Error setting 'Token-Decrypting'. (CERERR002) ---> System.ArgumentException: PS0006: The IsPrimary parameter must be specified when a Token-Encryption or Token-Signing certificate is specified.
   at Microsoft.IdentityServer.Management.Commands.SetCertificateCommand.DoProcessing()
   at Microsoft.IdentityServer.Management.Commands.SetCertificateCommand.EndProcessingOverride()
   --- End of inner exception stack trace ---  The SendConfigurationApply function did not succeed. LCM failed to start desired state configuration manually.\"

Suggested solution to the issue

Add-AdfsCertificate before setting it.

Following command produces same error as in DSC.

PS C:\Users\adminuser> Set-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint $thumbprint
Set-AdfsCertificate : PS0006: The IsPrimary parameter must be specified when a Token-Encryption or Token-Signing
certificate is specified.
At line:1 char:1
+ Set-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint "7ED ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-AdfsCertificate], ArgumentException
    + FullyQualifiedErrorId : PS0006,Microsoft.IdentityServer.Management.Commands.SetCertificateCommand

Adding -IsPrimary to the command produces another error.

PS C:\Users\adminuser> Set-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint $thumbprint -IsPrimary
Set-AdfsCertificate : PS0010: You must add the certificate before you can set it to be the primary certificate.
At line:1 char:1
+ Set-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint "7ED ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-AdfsCertificate], ArgumentException
    + FullyQualifiedErrorId : PS0010,Microsoft.IdentityServer.Management.Commands.SetCertificateCommand

After adding the certificate as suggested in PS0010. It is possible to set the certificate to token-signing. So I think this is the part missing.

PS C:\Users\adminuser> Add-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint $thumbprint
PS C:\Users\adminuser> Set-AdfsCertificate -CertificateType "Token-Signing" -Thumbprint $thumbprint -IsPrimary

The only place In the code I can find the Add-AdfsCertificate is in AdfsDsc/Tests/Unit/Stubs/AdfsStub.psm1

The DSC configuration that is used to reproduce the issue (as detailed as possible)

WindowsFeature adfs-federation
{
    Ensure               = "Present"
    Name                 = "adfs-federation"
    IncludeAllSubFeature = $True
    DependsOn            = "[PendingReboot]RebootAfterInstallingAD"
}
ADKDSKey CreateKDSRootKeyInPast
{
    Ensure                   = 'Present'
    EffectiveTime            = '1/1/2021 13:00'
    AllowUnsafeEffectiveTime = $true # Use with caution
}
ADManagedServiceAccount AddADFSGMSA
{
    Ensure                    = 'Present'
    ServiceAccountName        = 'adfs_gmsa'
    AccountType               = 'Group'
    ManagedPasswordPrincipals = 'Domain Controllers'
    DependsOn                 = "[ADKDSKey]CreateKDSRootKeyInPast"
}
AdfsFarm ConfigureADFS
{
    FederationServiceName         = "sts.$ExternalDnsDomain"
    FederationServiceDisplayName  = "$domain dev ADFS Service"
    CertificateThumbprint         = "$thumbprint"
    GroupServiceAccountIdentifier = "$domain\adfs_gmsa$"
    Credential                    = $DomainCreds
}
        
AdfsProperties ADFSFarmProperties
{
    FederationServiceName         = "sts.$ExternalDnsDomain"
    EnableIdPInitiatedSignonPage  = $True
    AutoCertificateRollover       = $False
    DependsOn                     = "[AdfsFarm]ConfigureADFS"
}

AdfsCertificate TokenSigningCertificates
{
    CertificateType = 'Token-Signing'
    Thumbprint      = "$thumbprint"
    DependsOn       = "[AdfsProperties]ADFSFarmProperties"
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2019 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture       : 64-bit
WindowsVersion       : 1809
WindowsBuildLabEx    : 17763.1.amd64fre.rs5_release.180914-1434
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value
----                           -----
PSVersion                      5.1.17763.1490
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.1490
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the DSC module that was used

1.1.0

AdfsGlobalAuthenticationPolicy: Errors with older Versions of ADFS

Details of the scenario you tried and the problem that is occurring

When specifying PrimaryExtranetAuthenticationProvider & PrimaryIntranetAuthenticationProvider an error occurs. It appears to be looking for properties that do not exist in my environment, I am assuming due to the version. It seems like the compare is comparing parameters that are not being passed when using Windows Server 2012 R2.

Verbose logs showing the problem

VERBOSE: [ADFS01]: LCM:  [ Start  Resource ]  [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy]
VERBOSE: [ADFS01]: LCM:  [ Start  Test     ]  [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy]
VERBOSE: [ADFS01]:                            [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy] Testing 'sts.contoso.com'. (GAP002
)
VERBOSE: [ADFS01]:                            [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy] Getting 'sts.contoso.com'. (GAP001
)
The property 'AllowAdditionalAuthenticationAsPrimary' cannot be found on this object. Verify that the property exists.
    + CategoryInfo          : NotSpecified: (:) [], CimException
    + FullyQualifiedErrorId : PropertyNotFoundStrict
    + PSComputerName        : ADFS01
 
Cannot bind argument to parameter 'CurrentValues' because it is null.
    + CategoryInfo          : InvalidData: (:) [], CimException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Compare-ResourcePropertyState
    + PSComputerName        : ADFS01
 
VERBOSE: [ADFS01]:                            [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy] 'sts.contoso.com' is in the desire
d state. (GAP005)
VERBOSE: [ADFS01]: LCM:  [ End    Test     ]  [[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy]  in 0.7660 seconds.
The PowerShell DSC resource '[AdfsGlobalAuthenticationPolicy]GlobalAuthenticationPolicy' with SourceInfo 
'C:\temp\ADFSConfig.ps1::57::9::AdfsGlobalAuthenticationPolicy' threw one or more non-terminating errors while running the 
Test-TargetResource functionality. These errors are logged to the ETW channel called Microsoft-Windows-DSC/Operational. Refer to this 
channel for more details.
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : ADFS01
 
VERBOSE: [ADFS01]: LCM:  [ End    Set      ]

Suggested solution to the issue

The DSC configuration that is used to reproduce the issue (as detailed as possible)

AdfsGlobalAuthenticationPolicy GlobalAuthenticationPolicy
{
    FederationServiceName                  = $node.FederationServiceName
    PrimaryExtranetAuthenticationProvider  = 'CertificateAuthentication'
    PrimaryIntranetAuthenticationProvider  = 'WindowsAuthentication'
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2012 R2 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 9600.19761.amd64fre.winblue_ltsb.200610-0600
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value                                                                                                        
----                           -----                                                                                                        
PSVersion                      5.1.14409.1005                                                                                               
PSEdition                      Desktop                                                                                                      
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                      
BuildVersion                   10.0.14409.1005                                                                                              
CLRVersion                     4.0.30319.42000                                                                                              
WSManStackVersion              3.0                                                                                                          
PSRemotingProtocolVersion      2.3                                                                                                          
SerializationVersion           1.1.0.1   

Version of the DSC module that was used

1.0.0

AdfsRelyingPartyTrust: Add Support for SAML Endpoints

The AdfsRelyingPartyTrust resource needs to support SAML endpoints.

New resource properties required:

Property Name Type Description
SamlEndpoint MSFT_AdfsSamlEndpoint Array Specifies an array of Security Assertion Markup Language (SAML) protocol endpoints for this relying party.

The MSFT_AdfsSamlEndpoint class would contain the following properties:

Parameter Type ValueMap Description
Binding String Artifact, POST, Redirect, SOAP Specifies the binding type of the endpoint.
Index SInt32 Specifies the index that is defined for this endpoint.
IsDefault Boolean Indicates whether this is a default endpoint for the particular protocol type.
Protocol String SAMLArtifactResolution, SAMLAssertionConsumer, SAMLLogout, SAMLSingleSignOn Specifies the type of service at the endpoint.
ResponseUri String Specifies the response URI for the endpoint.
Uri String Specifies the URI of this endpoint.

Example DSC configuration would look like:

AdfsRelyingPartyTrust Example
{
    Name         = 'Example'
    SamlEndpoint = @(
        MSFT_AdfsSamlEndpoint
        {
            Binding     = 'POST'
            Index       = 0
            IsDefault   = $false
            Protocol    = 'SAMLAssertionConsumer'
            Uri         = 'https://example.com'
        }
    )
}

AdfsWebApiApplication: Test-DscConfiguration Always Returns `$false` if Multiple `AllowedClientTypes` are Defined

Details of the scenario you tried and the problem that is occurring

If multiple AllowedClientTypes are defined on an AdfsWebApiApplication resource, Test-DscResource will always return $false.

Verbose logs showing the problem

VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = TestConfiguration,'className' = 
MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer ADFS01 with user sid S-1-5-21-3553084080-2500667019-4197401787-500.
VERBOSE: [ADFS01]: LCM:  [ Start  Test     ]
VERBOSE: [ADFS01]: LCM:  [ Start  Resource ]  [[AdfsApplicationGroup]AppGroup1]
VERBOSE: [ADFS01]: LCM:  [ Start  Test     ]  [[AdfsApplicationGroup]AppGroup1]
VERBOSE: [ADFS01]:                            [[AdfsApplicationGroup]AppGroup1] Testing 'AppGroup1'. (AG002)
VERBOSE: [ADFS01]:                            [[AdfsApplicationGroup]AppGroup1] Getting 'AppGroup1'. (AG001)
VERBOSE: [ADFS01]:                            [[AdfsApplicationGroup]AppGroup1] 'AppGroup1' is in the desired state. (AG007)
VERBOSE: [ADFS01]: LCM:  [ End    Test     ]  [[AdfsApplicationGroup]AppGroup1] True in 2.8600 seconds.
VERBOSE: [ADFS01]: LCM:  [ End    Resource ]  [[AdfsApplicationGroup]AppGroup1]
VERBOSE: [ADFS01]: LCM:  [ Start  Resource ]  [[AdfsWebApiApplication]WebApiApp1]
VERBOSE: [ADFS01]: LCM:  [ Start  Test     ]  [[AdfsWebApiApplication]WebApiApp1]
VERBOSE: [ADFS01]:                            [[AdfsWebApiApplication]WebApiApp1] Testing 'AppGroup1 - App1 Web API'. (WEB002)
VERBOSE: [ADFS01]:                            [[AdfsWebApiApplication]WebApiApp1] Getting 'AppGroup1 - App1 Web API'. (WEB001)
VERBOSE: [ADFS01]:                            [[AdfsWebApiApplication]WebApiApp1] The parameter 'AllowedClientTypes' is not in the desired state. 
Expected 'Public, Confidential', Actual 'Public, Confidential'. (ADFSCOMMON0003)

Suggested solution to the issue

The AlllowedClientTypes property of the WebApiApplication is an Microsoft.IdentityServer.Protocols.PolicyStore.AllowedClientTypes enum and needs converting to a string array in the Get-TargetResource function.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Configuration AdfsWebApiApplication_Config
{
    param()

    Import-DscResource -ModuleName AdfsDsc

    Node localhost
    {
        AdfsWebApiApplication WebApiApp1
        {
            Name                          = 'AppGroup1 - Web API'
            ApplicationGroupIdentifier    = 'AppGroup1'
            Identifier                    = 'e7bfb303-c5f6-4028-a360-b6293d41338c'
            Description                   = 'App1 Web Api'
            AccessControlPolicyName       = 'Permit everyone'
            AlwaysRequireAuthentication   = $false
            AllowedClientTypes            = 'Public', 'Confidential'
            IssueOAuthRefreshTokensTo     = 'AllDevices'
            NotBeforeSkew                 = 0
            RefreshTokenProtectionEnabled = $true
            RequestMFAFromClaimsProviders = $false
            TokenLifetime                 = 0
        }
    }
}

The operating system the target node is running

<!--
    Please provide as much as possible about the target node, for example
    edition, version, build and language.
    On OS with WMF 5.1 the following command can help get this information.

    Get-ComputerInfo -Property @(
        'OsName',
        'OsOperatingSystemSKU',
        'OSArchitecture',
        'WindowsVersion',
        'WindowsBuildLabEx',
        'OsLanguage',
        'OsMuiLanguages')
-->
OsName               : Microsoft Windows Server 2019 Standard
OsOperatingSystemSKU : StandardServerEdition
OsArchitecture       : 64-bit
WindowsVersion       : 1809
WindowsBuildLabEx    : 17763.1.amd64fre.rs5_release.180914-1434
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

<!--
    To help with this information, please run this command:
    $PSVersionTable
-->
PSVersion                      5.1.17763.3770
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.3770
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the DSC module that was used

1.3.0

ADFSFarm: Install ADFS Farm without Domain Admins privileges

Details of the scenario you tried and the problem that is occurring

We would like to install our ADSF Farm without Domain Admins privileges, following the procedure Microsoft provides in https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/install-ad-fs-delegated-admin.

We would first manually pre-create an ADFS Farm in Active Directory following these instructions https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/install-ad-fs-delegated-admin#prepare-ad-1

We would then like to use AdfsDsc, and teh ADFSFarm resource, to create the ADFS Farm like it is being done in https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/install-ad-fs-delegated-admin#create-the-ad-fs-farm-1. This method requires the parameter -AdminConfiguration, which is currently not supported in AdfsDsc.

Verbose logs showing the problem

Suggested solution to the issue

Add the parameter AdminConfiguration, to the ADFSFarm resource. The value must be a hashtable according to documentation https://docs.microsoft.com/en-us/powershell/module/adfs/install-adfsfarm?view=win10-ps.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

The operating system the target node is running

Version and build of PowerShell the target node is running

Version of the DSC module that was used

Declaring IssuanceTransformRules with ConfigurationData

Is it possible to send IssuanceTransformRules using ConfigurationData? I'm trying to set up node data for use with AdfsWebApiApplication, but I cannot get it to compile properly.

If I try to declare the data type outside of the DSC module, I get "Unable to find type [MSFT_AdfsIssuanceTransformRule]"

If I use example syntax within AllNodes and then pass to configuration, I receive:
"Convert property 'IssuanceTransformRules' value from type 'STRING[]' to type 'INSTANCE[]' failed

AdfsRelyingPartyTrust: Add Support for EncryptionCertificate and RequestSigningCertificate

The AdfsRelyingPartyTrust resource needs to support an Encryption Certificate and Request Signing Certificates.

New resource properties required:

Property Name Type Description
EncryptionCertificate String Specifies the certificate to be used for encrypting claims that are issued to this relying party. This should be in Base64 CER encoded format.
RequestSigningCertificate String Array Specifies an array of certificates to be used to verify the signature on a request from the relying party. This should be in Base64 CER encoded format.

The AdfsRelyingPartyTrust cmdlets expect to be passed values of type System.Security.Cryptography.X509Certificates.X509Certificate2 for these parameters.

The following code can be used to create an X509Certificate2 object from the Base64 CER data:

$certCerAsciiData = '<CertCERData>'
$certCerByteData = [System.Text.Encoding]::UTF8.GetBytes($certCerAsciiData)
$x509Certificate2 = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certCerByteData)

The following code can be used to extract Base64 CER data from an x509Certificate2 object:

$certCerAsciiData = @(
    '-----BEGIN CERTIFICATE-----'
    [System.Convert]::ToBase64String($x509Certificate2.RawData, 'InsertLineBreaks')
    '-----END CERTIFICATE-----'
) | Out-String

AdfsClaimsProviderTrust: New Resource Proposal

Description

A counterpart of the Add-AdfsClaimsProviderTrust/Get-AdfsClaimsProviderTrust/Remove-AdfsClaimsProviderTrust would be great to have in the module.

Adfs Cmdlets Used

Proposed properties

Parameter Type Description Allowed Values
Name Required - String Specifies the friendly name of the claims provider trust.
Identifier Key - String Specifies the unique identifier for the claims provider trust. No other trust can use an identifier from this list. Uniform Resource Identifiers (URIs) are often used as unique identifiers for a claims provider trust, but any string of characters can be used.
TokenSigningCertificate String[] Specifies an array of token-signing certificates that the claims provider use. This should be in Base64 CER encoded format.
AutoUpdateEnabled Write - Boolean Indicates whether changes to the federation metadata by the MetadataURL parameter apply automatically to the configuration of the trust relationship. If this parameter has a value of $True, partner claims, certificates, and endpoints are updated automatically.
AllowCreate Write - Boolean Indicates whether the Security Assertion Markup Language (SAML) parameter AllowCreate is sent in SAML requests to the claims provider. The default value is $True.
AnchorClaimType Write - String
CustomMFAUri Write - String
EncryptionCertificateRevocationCheck String Check Specifies the type of validation that occurs for the encryption certificate before it is used for encrypting claims. CheckChain, CheckChainCacheOnly, CheckChainExcludeRoot, CheckChainExcludeRootCacheOnly, CheckEndCert, CheckEndCertCacheOnly, None
Enabled Write - Boolean Indicates whether the claims provider trust is enabled or disabled.
Notes Write - String Specifies notes for this claims provider trust.
ProtocolProfile Write - String Specifies which protocol profiles the claims provider supports. The default value is WsFed-SAML. WSFederation, WsFed-SAML, SAML
EncryptedNameIdRequired Write - Boolean Indicates whether the relying party requires that the NameID claim be encrypted. This setting applies to SAML logout requests.
SamlAuthenticationRequestIndex Write - Uint16 Specifies the value of AssertionConsumerServiceIndex that will be placed in SAML authentication requests that are sent to the claims provider.
SamlAuthenticationRequestParameters Write - String Specifies which parameter to use in SAML authentication requests to the claims provider. Index, None, ProtocolBinding, Url, UrlWithProtocolBinding
SamlAuthenticationRequestProtocolBinding Write - String Specifies the value of ProtocolBinding to place in SAML authentication requests to the claims provider. Artifact, POST, Redirect
SignatureAlgorithm Write - String Specifies the signature algorithm that the claims provider uses for signing and verification. http://www.w3.org/2000/09/xmldsig#rsa-sha1, http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
SigningCertificateRevocationCheck Write- String Specifies the type of certificate validation that occurs when signatures are verified on responses or assertions from the claims provider. CheckChain, CheckChainCacheOnly, CheckChainExcludeRoot, CheckChainExcludeRootCacheOnly, CheckEndCert, CheckEndCertCacheOnly, None
SupportsMfa Write - Boolean
PromptLoginFederation Write - String None, FallbackToProtocolSpecificParameters, ForwardPromptAndHintsOverWsFederation, Disabled
PromptLoginFallbackAuthenticationType Write - String Specifies a fallback authentication type for a prompt login request.
RequiredNameIdFormat Write - String Specifies the format that is required for NameID claims to be included in SAML requests to the claims provider. By default, no format is required.
EncryptionCertificate Write- String Specifies the certificate to be used for encrypting a NameID to this claims provider in SAML logout requests. Encrypting the NameID is optional. This should be in Base64 CER encoded format.
OrganizationalAccountSuffix Write - String[] Specifies an array of organizational account suffixes an administrator can configure for the claims provider trust for a Home Realm Discovery (HRD) scenario.
WSFedEndpoint Write -String Specifies the WS-Federation Passive URL for this claims provider.
ClaimOffered Write - String[] Specifies an array of claims that are offered by this claims provider.
SamlEndpoint Write - MSFT_AdfsSaml Endpoint Specifies an array of SAML protocol endpoints for this claims provider.
SignedSamlRequestsRequired Write - Boolean Indicates whether the Federation Service requires signed SAML protocol requests from the relying party. If you specify a value of $True, the Federation Service rejects unsigned SAML protocol requests.
AcceptanceTransformRules Write - String Specifies the claim acceptance transform rules for accepting claims from this claims provider. These rules determine the information that is accepted from the partner represented by the claims provider trust.
MonitoringEnabled Write - String Indicates whether periodic monitoring of this claims provider's federation metadata is enabled. The URL of the claims provider's federation metadata is specified by the MetadataUrl parameter.
MetadataUrl Write - String Specifies the URL at which the federation metadata for the claims provider trust is available.

Special considerations or limitations

AdfsRelyingPartyTrust: Add Missing Parameters

The following parameters are missing from the AdfsRelyingPartyTrust resource and needs adding.

Property Name Type Description Allowed Values
AllowedClientTypes String Array Specifies allowed client types. "None","Public","Confidential"
AlwaysRequireAuthentication Boolean Indicates to always require authentication.
RequestMFAFromClaimsProviders Boolean Indicates whether to use the request MFA from claims providers option.
AllowedAuthenticationClassReferences String Array
IssueOAuthRefreshTokensTo String Specifies the refresh token issuance device types. "NoDevice", "WorkplaceJoinedDevices", "AllDevices"
RefreshTokenProtectionEnabled Boolean Indicates that refresh token protection is enabled.

AdfsDsc: Migrate to using DscResource.Common Module

Some of the common functions implemented within the AdfsDsc.Common module have now been implemented in the DSC Community DscResource.Common module so these should be used in preference.

Functions:

  • Get-LocalizedData
  • New-InvalidArgumentException
  • New-InvalidOperationException
  • New-ObjectNotFoundException
  • New-InvalidResultException
  • New-NotImplementedException
  • Assert-Module

AdfsOrganization: Add Support for an Empty Organization

Details of the scenario you tried and the problem that is occurring

The AdfsOrganization resource errors if the current organization is empty, or if the organization is set to empty values.

Suggested solution to the issue

Add support for reading and writing an empty organization.

Version of the DSC module that was used ('dev' if using current dev branch)

1.0.0

ADFSFarm: Test-Targetresource fails trying to use domain name as NetBIOS name

Details of the scenario you tried and the problem that is occurring

I am using DSC to setup a lab server including ADDS, ADCS and ADFS on a single machine. Setting up the ADFS throws an error after the first reboot during the teststage. It complains about an unkown NetBIOS name and seems to use the domain name as a query, which fails.

Verbose logs showing the problem

Set completes with a couple of warnings.

LCM:  [ Start  Resource ]  [[WindowsFeature]ADFSInstall]  "},
LCM:  [ Start  Test     ]  [[WindowsFeature]ADFSInstall]  "},
                           [[WindowsFeature]ADFSInstall] The operation 'Get-WindowsFeature' started: ADFS-Federation"},
                           [[WindowsFeature]ADFSInstall] The operation 'Get-WindowsFeature' succeeded: ADFS-Federation"},
LCM:  [ End    Test     ]  [[WindowsFeature]ADFSInstall]  in 0.2190 seconds."},
LCM:  [ Skip   Set      ]  [[WindowsFeature]ADFSInstall]  "},
LCM:  [ End    Resource ]  [[WindowsFeature]ADFSInstall]  "},
LCM:  [ Start  Resource ]  [[AdfsFarm]ADFSLab]  "},
LCM:  [ Start  Test     ]  [[AdfsFarm]ADFSLab]  "},
                           [[AdfsFarm]ADFSLab] Testing 'adfs.lab.local'. (FRM002)"},
                           [[AdfsFarm]ADFSLab] Getting 'adfs.lab.local'. (FRM001)"},
                           [[AdfsFarm]ADFSLab] 'adfs.lab.local' is absent but should be present. (FRM007)"},
LCM:  [ End    Test     ]  [[AdfsFarm]ADFSLab]  in 0.0630 seconds."},
LCM:  [ Start  Set      ]  [[AdfsFarm]ADFSLab]  "},
                           [[AdfsFarm]ADFSLab] Setting 'adfs.lab.local'. (FRM003)"},
                           [[AdfsFarm]ADFSLab] Getting 'adfs.lab.local'. (FRM001)"},
                           [[AdfsFarm]ADFSLab] Installing 'adfs.lab.local'. (FRM004)"},
                           [[AdfsFarm]ADFSLab] A machine restart is required to complete ADFS service configuration. For more information, see: http://go.microsoft.com/fwlink/?LinkId=798725"},
                           [[AdfsFarm]ADFSLab] The SSL certificate subject alternative names do not support host name 'certauth.adfs.lab.local'. Configuring certificate authentication binding on port '49443' and hostname 'adfs.lab.local'."},
                           [[AdfsFarm]ADFSLab] The SSL certificate does not contain all UPN suffix values that exist in the enterprise.  Users with UPN suffix values not represented in the certificate will not be able to Workplace-Join their devices.  For more information, see http://go.microsoft.com/fwlink/?LinkId=311954."},
                           [[AdfsFarm]ADFSLab] 'adfs.lab.local' has been installed successfully. A reboot is now required. (FRM005)"},
LCM:  [ End    Set      ]  [[AdfsFarm]ADFSLab]  in 26.4210 seconds."},
LCM:  [ End    Resource ]  [[AdfsFarm]ADFSLab]  "},
                           [] A reboot is scheduled to progress further. Configuration will be continued after the reboot."},
                           [] A reboot is scheduled to progress further. Configuration will be continued after the reboot."},
                           [] Consistency check completed."}

After reboot it picks up but fails the test and exits.

"type": "verbose", "message": "[WIN-I0BA3HA4226]: LCM:  [ Start  Resource ]  [[AdfsFarm]ADFSLab]  "},
"type": "verbose", "message": "[WIN-I0BA3HA4226]: LCM:  [ Start  Test     ]  [[AdfsFarm]ADFSLab]  "},
"type": "verbose", "message": "[WIN-I0BA3HA4226]:                            [[AdfsFarm]ADFSLab] Testing 'adfs.lab.local'. (FRM002)"},
"type": "verbose", "message": "[WIN-I0BA3HA4226]:                            [[AdfsFarm]ADFSLab] Getting 'adfs.lab.local'. (FRM001)"},
"type": "verbose", "message": "[WIN-I0BA3HA4226]: LCM:  [ End    Test     ]  [[AdfsFarm]ADFSLab]  in 1.0000 seconds."},
"type": "error", "message": "PowerShell DSC resource MSFT_AdfsFarm  failed to execute Test-TargetResource functionality with error message: The Active Directory NetBIOS name is unknown. (ADFSCOMMON0018)\r\nParameter name: lab.local "},     

Suggested solution to the issue

I am very new to DSC and have not found any hint on how the NetBIOS name is acquired in this instance. The Parameter name it shows i the actual domain lab.local, the NetBIOS name would be lab. I cannot rule out that I made a configuration mistake.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

configuration ADFSInstallation {
    param (
        [Parameter(Mandatory)]
        [String]$DomainName,

        [Parameter(Mandatory)]
        [System.Management.Automation.PSCredential]$AdminCreds,

        [Int]$RetryCount = 60,
        [Int]$RetryIntervalSec = 5
    )

    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xActiveDirectory -ModuleVersion 3.0.0.0
    Import-DscResource -ModuleName xAdcsDeployment -ModuleVersion 1.4.0.0
    Import-DscResource -ModuleName ADCSTemplate -ModuleVersion 1.0.1.0
    Import-DscResource -ModuleName AdfsDsc -ModuleVersion 1.3.2
    Import-DscResource -ModuleName xNetworking -ModuleVersion 5.7.0.0
    Import-DscResource -ModuleName CertificateDsc -ModuleVersion 5.1.0

    [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("$DomainName\$($AdminCreds.UserName)", $AdminCreds.Password)
    [System.Management.Automation.PSCredential]$svcCreds = New-Object System.Management.Automation.PSCredential ("$DomainName\adfs-svc", $AdminCreds.Password)

    Node $AllNodes.NodeName {
        
        LocalConfigurationManager
        {
            ActionAfterReboot = 'ContinueConfiguration'
            ConfigurationMode = 'ApplyOnly'
            RebootNodeIfNeeded = $true
            AllowModuleOverWrite = $true
        }        
        
        WindowsFeature ADDSInstall 
        { 
            Ensure = 'Present'
            Name = 'AD-Domain-Services'
        }  

        WindowsFeature ADDSPowerShell
        { 
            Ensure = 'Present' 
            Name = 'RSAT-AD-PowerShell'
        }

        # Optional GUI tools
        WindowsFeature ADDSTools
        { 
            Ensure = 'Present' 
            Name = 'RSAT-ADDS'
        }

        # Install the DNS Server role
        WindowsFeature DNSInstall {
            Ensure = 'Present'
            Name = 'DNS'
        }

        WindowsFeature DNSTools {
            Ensure = 'Present'
            Name = 'RSAT-DNS-Server'
        }

        # Configure the DNS Server
        xDnsServerAddress DNSConfiguration {
            Address = '127.0.0.1'
            AddressFamily = 'IPv4'
            InterfaceAlias = (Get-NetIPAddress | Where-Object { $_.AddressFamily -eq 'IPv4' -and $_.InterfaceIndex -eq (Get-NetRoute -DestinationPrefix '0.0.0.0/0').InterfaceIndex }).InterfaceAlias
            DependsOn = '[WindowsFeature]DNSInstall'
        }

        xADDomain FirstDS 
        {
            DomainName = $DomainName
            DomainAdministratorCredential = $DomainCreds
            SafemodeAdministratorPassword = $DomainCreds
            DomainNetbiosName = ($DomainName -split '\.')[0]
            DependsOn = "[WindowsFeature]ADDSInstall"
        }

        xWaitForADDomain DscForestWait
        {
            DomainName = $DomainName
            DomainUserCredential = $DomainCreds
            RetryCount = $RetryCount
            RetryIntervalSec = $RetryIntervalSec
            DependsOn = "[xADDomain]FirstDS"
        } 

        xADRecycleBin RecycleBin
        {
           EnterpriseAdministratorCredential = $DomainCreds
           ForestFQDN = $DomainName
           DependsOn = '[xWaitForADDomain]DscForestWait'
        }
        
        ### USERS ###
        $DomainRoot = "DC=$($DomainName -replace '\.',',DC=')"
        $DependsOn_User = @()
        $Users = $ConfigurationData.NonNodeData.UserData | ConvertFrom-CSV
        ForEach ($User in $Users) {

            xADUser "NewADUser_$($User.UserName)"
            {
                DomainName = $DomainName
                Ensure = 'Present'
                UserName = $User.UserName
                UserPrincipalName = "$($User.UserName)@$($DomainName)"
                GivenName = $User.FirstName
                Surname = $User.LastName
                EmailAddress = "$($User.UserName)@$($DomainName)"
                DisplayName = "$($User.FirstName) $($User.LastName)"
                Path = "CN=Users,$($DomainRoot)"
                Enabled = $true
                Department = $User.Department
                PasswordAuthentication = 'Negotiate'
                Password = New-Object -TypeName PSCredential -ArgumentList 'JustPassword', (ConvertTo-SecureString -String $User.Password -AsPlainText -Force)
                DependsOn = '[xADRecycleBin]RecycleBin'
            }
            $DependsOn_User += "[xADUser]NewADUser_$($User.UserName)"
        }

        ### GROUPS ###
        ForEach ($ADGroup in $ConfigurationData.NonNodeData.Groups) {
            xADGroup "NewADGroup_$ADGroup"
            {
                GroupName = "G_$ADGroup"
                GroupScope = 'Global'
                Description = "Global group for $ADGroup"
                Category = 'Security'
                Members = ($Users | Where-Object {$_.Department -eq $ADGroup}).UserName
                Path = "CN=Users,$($DomainRoot)"
                Ensure = 'Present'
                DependsOn = $DependsOn_User
            }
        }

        # Install Active Directory Certificate Services (ADCS)
        WindowsFeature ADCS-Cert-Authority
        {
            Ensure = 'Present'
            Name = 'ADCS-Cert-Authority'
            DependsOn = '[xADRecycleBin]RecycleBin'
        }

        WindowsFeature ADCS-Web-Enrollment
        {
            Ensure = 'Present'
            Name = 'ADCS-Web-Enrollment'
            DependsOn = '[xADRecycleBin]RecycleBin'
        }

        WindowsFeature RSAT-ADCS
        {
            Ensure = 'Present'
            Name = 'RSAT-ADCS'
            DependsOn = '[xADRecycleBin]RecycleBin'
        }

        xADCSCertificationAuthority ADCS
        {
            Ensure = 'Present'
            Credential = $DomainCreds
            CAType = 'EnterpriseRootCA'
            DependsOn = '[WindowsFeature]ADCS-Cert-Authority'              
        }

        xADCSWebEnrollment CertSrv
        {
            IsSingleInstance = 'Yes'
            Ensure = 'Present'
            Credential = $DomainCreds
            DependsOn = '[xADCSCertificationAuthority]ADCS'
        }

        # Create ADFS Template
        ADCSTemplate ADFSTemplate
        {
            Ensure = 'Present'
            DisplayName = 'ADFS Template'
            JSON = $ConfigurationData.NonNodeData.JSON_ADFS
            Publish = $true
            Identity = "$DomainName\Domain Computers", "$DomainName\Domain Controllers"
            AutoEnroll = $true
            PsDscRunAsCredential = $DomainCreds
            DependsOn = '[xADCSWebEnrollment]CertSrv'
        }

        # Create Service Account for ADFS
        xADUser 'adfs-svc'
        {
            Ensure      = 'Present'
            UserName    = 'adfs-svc'
            UserPrincipalName = "adfs-svc@$($DomainName)"
            PasswordAuthentication = 'Negotiate'
            Password    = $AdminCreds
            DomainName  = $DomainName
            Path        = "CN=Users,$($DomainRoot)"
            ChangePasswordAtLogon   = $false
            CannotChangePassword    = $true
            PasswordNeverExpires    = $true
            DependsOn = '[xADRecycleBin]RecycleBin'
        }

        # Generate Certificate
        CertReq ADFSCert
        {
            Subject = "adfs.$($DomainName)"
            SubjectAltName  = "dns=adfs.$($DomainName)"
            CertificateTemplate = "ADFSTemplate"
            DependsOn = '[ADCSTemplate]ADFSTemplate'
            #FriendlyName = "Cert for ADFS"
        }


        # Install Active Directory Federation Services (ADFS)
        WindowsFeature ADFSInstall 
        {
            Ensure = 'Present'
            Name = 'ADFS-Federation'
            DependsOn = '[CertReq]ADFSCert'
        }

        # Configure ADFS
        AdfsFarm ADFSLab
        {
            FederationServiceName = "adfs.$($DomainName)"
            FederationServiceDisplayName = "Test ADFS"
            CertificateDnsName = "adfs.$($DomainName)"
            ServiceAccountCredential = $svcCreds
            Credential = $DomainCreds
            DependsOn = '[WindowsFeature]ADFSInstall'
        }

        AdfsProperties ADFSLabProperties
        {
            FederationServiceName = "adfs.$($DomainName)"
            EnableIdPInitiatedSignonPage = $true
            DependsOn = '[AdfsFarm]ADFSLab'
        }


    }
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2016 Datacenter
OsOperatingSystemSKU : DatacenterServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 14393.1794.amd64fre.rs1_release.171008-1615
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value
----                           -----
PSVersion                      5.1.14393.1884
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.1884
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the DSC module that was used

1.3.2

ADFSCertificate, ADFSFarm: Use latest cert that matches a CN

Details of the scenario you tried and the problem that is occurring

Working to fully automate an ADFS deployment but with a static thumbprint, the MOF must be recompiled any time the certificate changes. Full automation includes the request of a certificate for the ADFS server, so the thumbprint is not known until DSC applies.

Verbose logs showing the problem

Suggested solution to the issue

Remove thumbprint parameter in favor of a CommonName parameter. Find the latest certificate in the computer store with the matching CN and apply that certificate.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

The operating system the target node is running

Windows Server 2022

OsName : Microsoft Windows Server 2022 Standard Evaluation
OsOperatingSystemSKU : 79
OsArchitecture : 64-bit
WindowsVersion : 2009
WindowsBuildLabEx : 20348.1.amd64fre.fe_release.210507-1500
OsLanguage : en-US
OsMuiLanguages : {en-US}

Version and build of PowerShell the target node is running

PSVersion 5.1.20348.1366
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.20348.1366
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

Version of the DSC module that was used

v1.3

AdfsRelyingPartyTrust: Add Support for Access Control Policies

The AdfsRelyingPartyTrust resource needs to support Access Control Policies.

New resource properties required:

Property Name Type Description
AccessControlPolicyName String Specifies the name of the Access Control Policy to apply to the relying party trust.
AccessControlPolicyParameters MSFT_AdfsAccess ControlPolicyParameters Specifies the parameters and their values to pass to the Access Control Policy.

The MSFT_AdfsAccessControlPolicyParameters class would contain the following properties:

Parameter Type ValueMap Description
GroupParameter String Array Specifies the group parameter

This is enough to provide support for the built-in Access Control Policies and the ability to later add support for custom Access Control Policies.

Here are details of the built-in Access Control Policies and what parameters they take:

AccessControlPolicyName                                              AccessControlPolicyParameters
-----------------------                                              -----------------------------
Permit everyone
Permit everyone and require MFA
Permit everyone and require MFA for specific group                   {GroupParameter}
Permit everyone and require MFA from extranet access
Permit everyone and require MFA from unauthenticated devices
Permit everyone and require MFA, allow automatic device registration
Permit everyone for intranet access
Permit specific group                                                {GroupParameter}

Example AccessControlPolicyParameters property:

AccessControlPolicyParameters = MSFT_AdfsAccessControlPolicyParameter
    @{
        GroupParameter = @(
            'CONTOSO\AppGroup1 Users'
            'CONTOSO\AppGroup1 Admins'
        )
    }

AdfsApplicationPermission: 'Scopenames' Test expects particular order

Details of the scenario you tried and the problem that is occurring

Looks to be similar scenario as Issue #63, Pull #64
When setting multiple "ScopeNames", the order is checked along with the contents. While the resource is configured correctly, the Test will always return $False unless the order seen in the verbose logs matches the MOF order.

Verbose logs showing the problem

[[AdfsApplicationPermission]ServiceNow] The parameter 'ScopeNames' is not in the desired state. Expected 'allatclaims, email, openid', Actual 'email, openid, allatclaims'. (ADFSCOMMON0003)
[[AdfsApplicationPermission]ServiceNow] client role 'ServiceNow Server Application ID' server role 'ServiceNow Server Application ID' is not in the desired state. (AG008)

This seems to be related to the order that the MOF stores the data vs how the configuration is set.

Suggested solution to the issue

Compare Desired ScopeNames to current ScopeNames with no consideration of order

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Configuration AdfsApplicationPermission_Config
{
    Import-DscResource -ModuleName AdfsDsc

    Node localhost
    {
        AdfsApplicationPermission AppPermission1
        {
                ClientRoleIdentifier = 'ServiceNow Server Application ID'
                ServerRoleIdentifier = 'ServiceNow Server Application ID'
                ScopeNames = @('allatclaims','email','openid')
        }
    }
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2022 Standard Evaluation
OsOperatingSystemSKU : 79
OsArchitecture       : 64-bit
WindowsVersion       : 2009
WindowsBuildLabEx    : 20348.1.amd64fre.fe_release.210507-1500
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value                                                                                                                                                  
----                           -----                                                                                                                                                  
PSVersion                      5.1.20348.1366
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.20348.1366}
BuildVersion                   10.0.20348.1366
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1   

Version of the DSC module that was used

1.3.1

Project status

What is the status of this resource? Is it a community driven project or sponsored by Microsoft?

I'm interested in helping as I have a need to manage roughly 400 Relying Party configurations with adfs 2016

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.