From ffe2a81c28b2ff89a2f2bf241b9e0cb427e11a96 Mon Sep 17 00:00:00 2001 From: Fabien Tschanz Date: Thu, 25 Apr 2024 13:16:23 +0200 Subject: [PATCH] Add certificate display names to wired network config --- CHANGELOG.md | 4 + ...figurationWiredNetworkPolicyWindows10.psm1 | 376 ++++++++++++++---- ...tionWiredNetworkPolicyWindows10.schema.mof | 5 + ...ationWiredNetworkPolicyWindows10.Tests.ps1 | 164 +++++--- 4 files changed, 415 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 764b863c49..ae7bbe0fd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ onboarding blob is generated by the Defender for Endpoint service. * IntuneDeviceConfigurationPolicyMacOS * Fixed an issue where the update policy setting was not handled properly. +* IntuneDeviceConfigurationWiredNetworkPolicyWindows10 + * Added functionality for specifying the certificates with a display name since their + ids in the blueprint might be from a different source tenant. + FIXES [#4582](https://github.com/microsoft/Microsoft365DSC/issues/4582) * MISC * Added support for AccessTokens in EXO resources. * Updated MSCloudLoginAssistant dependencies to version 1.1.16. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.psm1 index ee7805aa68..0558d97ea4 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.psm1 @@ -90,22 +90,42 @@ function Get-TargetResource [System.String[]] $RootCertificatesForServerValidationIds, + [Parameter()] + [System.String[]] + $RootCertificatesForServerValidationDisplayNames, + [Parameter()] [System.String] $IdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $IdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $SecondaryIdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $SecondaryIdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $RootCertificateForClientValidationId, + [Parameter()] + [System.String] + $RootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $SecondaryRootCertificateForClientValidationId, + [Parameter()] + [System.String] + $SecondaryRootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $Description, @@ -232,42 +252,53 @@ function Get-TargetResource } #endregion + $rootCertificateForClientValidation = Get-DeviceConfigurationPolicyCertificate -DeviceConfigurationPolicyId $getValue.Id -CertificateName rootCertificateForClientValidation + $rootCertificatesForServerValidation = Get-DeviceConfigurationPolicyCertificate -DeviceConfigurationPolicyId $getValue.Id -CertificateName rootCertificatesForServerValidation + $identityCertificateForClientAuthentication = Get-DeviceConfigurationPolicyCertificate -DeviceConfigurationPolicyId $getValue.Id -CertificateName identityCertificateForClientAuthentication + $secondaryIdentityCertificateForClientAuthentication = Get-DeviceConfigurationPolicyCertificate -DeviceConfigurationPolicyId $getValue.Id -CertificateName secondaryIdentityCertificateForClientAuthentication + $secondaryRootCertificateForClientValidation = Get-DeviceConfigurationPolicyCertificate -DeviceConfigurationPolicyId $getValue.Id -CertificateName secondaryRootCertificateForClientValidation + $results = @{ #region resource generator code - AuthenticationBlockPeriodInMinutes = $getValue.AdditionalProperties.authenticationBlockPeriodInMinutes - AuthenticationMethod = $enumAuthenticationMethod - AuthenticationPeriodInSeconds = $getValue.AdditionalProperties.authenticationPeriodInSeconds - AuthenticationRetryDelayPeriodInSeconds = $getValue.AdditionalProperties.authenticationRetryDelayPeriodInSeconds - AuthenticationType = $enumAuthenticationType - CacheCredentials = $getValue.AdditionalProperties.cacheCredentials - DisableUserPromptForServerValidation = $getValue.AdditionalProperties.disableUserPromptForServerValidation - EapolStartPeriodInSeconds = $getValue.AdditionalProperties.eapolStartPeriodInSeconds - EapType = $enumEapType - Enforce8021X = $getValue.AdditionalProperties.enforce8021X - ForceFIPSCompliance = $getValue.AdditionalProperties.forceFIPSCompliance - InnerAuthenticationProtocolForEAPTTLS = $enumInnerAuthenticationProtocolForEAPTTLS - MaximumAuthenticationFailures = $getValue.AdditionalProperties.maximumAuthenticationFailures - MaximumEAPOLStartMessages = $getValue.AdditionalProperties.maximumEAPOLStartMessages - OuterIdentityPrivacyTemporaryValue = $getValue.AdditionalProperties.outerIdentityPrivacyTemporaryValue - PerformServerValidation = $getValue.AdditionalProperties.performServerValidation - RequireCryptographicBinding = $getValue.AdditionalProperties.requireCryptographicBinding - SecondaryAuthenticationMethod = $enumSecondaryAuthenticationMethod - TrustedServerCertificateNames = $getValue.AdditionalProperties.trustedServerCertificateNames - RootCertificatesForServerValidationIds = Get-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $getValue.Id -CertificateName rootCertificatesForServerValidation - IdentityCertificateForClientAuthenticationId = Get-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $getValue.Id -CertificateName identityCertificateForClientAuthentication - SecondaryIdentityCertificateForClientAuthenticationId = Get-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $getValue.Id -CertificateName secondaryIdentityCertificateForClientAuthentication - RootCertificateForClientValidationId = Get-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $getValue.Id -CertificateName rootCertificateForClientValidation - SecondaryRootCertificateForClientValidationId = Get-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $getValue.Id -CertificateName secondaryRootCertificateForClientValidation - Description = $getValue.Description - DisplayName = $getValue.DisplayName - Id = $getValue.Id - Ensure = 'Present' - Credential = $Credential - ApplicationId = $ApplicationId - TenantId = $TenantId - ApplicationSecret = $ApplicationSecret - CertificateThumbprint = $CertificateThumbprint - Managedidentity = $ManagedIdentity.IsPresent + AuthenticationBlockPeriodInMinutes = $getValue.AdditionalProperties.authenticationBlockPeriodInMinutes + AuthenticationMethod = $enumAuthenticationMethod + AuthenticationPeriodInSeconds = $getValue.AdditionalProperties.authenticationPeriodInSeconds + AuthenticationRetryDelayPeriodInSeconds = $getValue.AdditionalProperties.authenticationRetryDelayPeriodInSeconds + AuthenticationType = $enumAuthenticationType + CacheCredentials = $getValue.AdditionalProperties.cacheCredentials + DisableUserPromptForServerValidation = $getValue.AdditionalProperties.disableUserPromptForServerValidation + EapolStartPeriodInSeconds = $getValue.AdditionalProperties.eapolStartPeriodInSeconds + EapType = $enumEapType + Enforce8021X = $getValue.AdditionalProperties.enforce8021X + ForceFIPSCompliance = $getValue.AdditionalProperties.forceFIPSCompliance + InnerAuthenticationProtocolForEAPTTLS = $enumInnerAuthenticationProtocolForEAPTTLS + MaximumAuthenticationFailures = $getValue.AdditionalProperties.maximumAuthenticationFailures + MaximumEAPOLStartMessages = $getValue.AdditionalProperties.maximumEAPOLStartMessages + OuterIdentityPrivacyTemporaryValue = $getValue.AdditionalProperties.outerIdentityPrivacyTemporaryValue + PerformServerValidation = $getValue.AdditionalProperties.performServerValidation + RequireCryptographicBinding = $getValue.AdditionalProperties.requireCryptographicBinding + SecondaryAuthenticationMethod = $enumSecondaryAuthenticationMethod + TrustedServerCertificateNames = $getValue.AdditionalProperties.trustedServerCertificateNames + RootCertificatesForServerValidationIds = @($rootCertificatesForServerValidation.Id) + RootCertificatesForServerValidationDisplayNames = @($rootCertificatesForServerValidation.DisplayName) + IdentityCertificateForClientAuthenticationId = $identityCertificateForClientAuthentication.Id + IdentityCertificateForClientAuthenticationDisplayName = $identityCertificateForClientAuthentication.DisplayName + SecondaryIdentityCertificateForClientAuthenticationId = $secondaryIdentityCertificateForClientAuthentication.Id + SecondaryIdentityCertificateForClientAuthenticationDisplayName = $secondaryIdentityCertificateForClientAuthentication.DisplayName + RootCertificateForClientValidationId = $rootCertificateForClientValidation.Id + RootCertificateForClientValidationDisplayName = $rootCertificateForClientValidation.DisplayName + SecondaryRootCertificateForClientValidationId = $secondaryRootCertificateForClientValidation.Id + SecondaryRootCertificateForClientValidationDisplayName = $secondaryRootCertificateForClientValidation.DisplayName + Description = $getValue.Description + DisplayName = $getValue.DisplayName + Id = $getValue.Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent #endregion } $assignmentsValues = Get-MgBetaDeviceManagementDeviceConfigurationAssignment -DeviceConfigurationId $Id @@ -392,22 +423,42 @@ function Set-TargetResource [System.String[]] $RootCertificatesForServerValidationIds, + [Parameter()] + [System.String[]] + $RootCertificatesForServerValidationDisplayNames, + [Parameter()] [System.String] $IdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $IdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $SecondaryIdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $SecondaryIdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $RootCertificateForClientValidationId, + [Parameter()] + [System.String] + $RootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $SecondaryRootCertificateForClientValidationId, + [Parameter()] + [System.String] + $SecondaryRootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $Description, @@ -476,10 +527,15 @@ function Set-TargetResource Write-Verbose -Message "Creating an Intune Device Configuration Wired Network Policy for Windows10 with DisplayName {$DisplayName}" $BoundParameters.Remove('Assignments') | Out-Null $BoundParameters.Remove('RootCertificatesForServerValidationIds') | Out-Null + $BoundParameters.Remove('RootCertificatesForServerValidationDisplayNames') | Out-Null $BoundParameters.Remove('IdentityCertificateForClientAuthenticationId') | Out-Null + $BoundParameters.Remove('IdentityCertificateForClientAuthenticationDisplayName') | Out-Null $BoundParameters.Remove('SecondaryIdentityCertificateForClientAuthenticationId') | Out-Null + $BoundParameters.Remove('SecondaryIdentityCertificateForClientAuthenticationDisplayName') | Out-Null $BoundParameters.Remove('RootCertificateForClientValidationId') | Out-Null + $BoundParameters.Remove('RootCertificateForClientValidationDisplayName') | Out-Null $BoundParameters.Remove('SecondaryRootCertificateForClientValidationId') | Out-Null + $BoundParameters.Remove('SecondaryRootCertificateForClientValidationDisplayName') | Out-Null $CreateParameters = ([Hashtable]$BoundParameters).clone() $CreateParameters = Rename-M365DSCCimInstanceParameter -Properties $CreateParameters @@ -498,34 +554,62 @@ function Set-TargetResource if ($null -ne $RootCertificatesForServerValidationIds -and $RootCertificatesForServerValidationIds.count -gt 0 ) { $rootCertificatesForServerValidation = @() - foreach ($certId in $RootCertificatesForServerValidationIds) + for ($i = 0; $i -lt $RootCertificatesForServerValidationIds.Length; $i++) { - $rootCertificatesForServerValidation += "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$certId')" + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $RootCertificatesForServerValidationIds[$i] ` + -CertificateDisplayName $RootCertificatesForServerValidationDisplayNames[$i] ` + -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + $rootCertificatesForServerValidation += "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$checkedCertId')" } $CreateParameters.Add('rootCertificatesForServerValidation@odata.bind', $rootCertificatesForServerValidation) } if (-not [String]::IsNullOrWhiteSpace($IdentityCertificateForClientAuthenticationId)) { - $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$IdentityCertificateForClientAuthenticationId')" + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $IdentityCertificateForClientAuthenticationId ` + -CertificateDisplayName $IdentityCertificateForClientAuthenticationDisplayName ` + -OdataTypes @( ` + '#microsoft.graph.windows81SCEPCertificateProfile', ` + '#microsoft.graph.windows81TrustedRootCertificate', ` + '#microsoft.graph.windows10PkcsCertificateProfile' ` + ) + $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$checkedCertId')" $CreateParameters.Add('identityCertificateForClientAuthentication@odata.bind', $ref) } if (-not [String]::IsNullOrWhiteSpace($SecondaryIdentityCertificateForClientAuthenticationId)) { - $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$SecondaryIdentityCertificateForClientAuthenticationId')" + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $SecondaryIdentityCertificateForClientAuthenticationId ` + -CertificateDisplayName $SecondaryIdentityCertificateForClientAuthenticationDisplayName ` + -OdataTypes @( ` + '#microsoft.graph.windows81SCEPCertificateProfile', ` + '#microsoft.graph.windows81TrustedRootCertificate', ` + '#microsoft.graph.windows10PkcsCertificateProfile' ` + ) + $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$checkedCertId')" $CreateParameters.Add('secondaryIdentityCertificateForClientAuthentication@odata.bind', $ref) } if (-not [String]::IsNullOrWhiteSpace($RootCertificateForClientValidationId)) { - $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$RootCertificateForClientValidationId')" + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $RootCertificateForClientValidationId ` + -CertificateDisplayName $RootCertificateForClientValidationDisplayName ` + -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$checkedCertId')" $CreateParameters.Add('rootCertificateForClientValidation@odata.bind', $ref) } if (-not [String]::IsNullOrWhiteSpace($SecondaryRootCertificateForClientValidationId)) { - $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$SecondaryRootCertificateForClientValidationId')" + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $SecondaryRootCertificateForClientValidationId ` + -CertificateDisplayName $SecondaryRootCertificateForClientValidationDisplayName ` + -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + $ref = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$checkedCertId')" $CreateParameters.Add('secondaryRootCertificateForClientValidation@odata.bind', $ref) } @@ -550,10 +634,15 @@ function Set-TargetResource Write-Verbose -Message "Updating the Intune Device Configuration Wired Network Policy for Windows10 with Id {$($currentInstance.Id)}" $BoundParameters.Remove('Assignments') | Out-Null $BoundParameters.Remove('RootCertificatesForServerValidationIds') | Out-Null + $BoundParameters.Remove('RootCertificatesForServerValidationDisplayNames') | Out-Null $BoundParameters.Remove('IdentityCertificateForClientAuthenticationId') | Out-Null + $BoundParameters.Remove('IdentityCertificateForClientAuthenticationDisplayName') | Out-Null $BoundParameters.Remove('SecondaryIdentityCertificateForClientAuthenticationId') | Out-Null + $BoundParameters.Remove('SecondaryIdentityCertificateForClientAuthenticationDisplayName') | Out-Null $BoundParameters.Remove('RootCertificateForClientValidationId') | Out-Null + $BoundParameters.Remove('RootCertificateForClientValidationDisplayName') | Out-Null $BoundParameters.Remove('SecondaryRootCertificateForClientValidationId') | Out-Null + $BoundParameters.Remove('SecondaryRootCertificateForClientValidationDisplayName') | Out-Null $UpdateParameters = ([Hashtable]$BoundParameters).clone() $UpdateParameters = Rename-M365DSCCimInstanceParameter -Properties $UpdateParameters @@ -576,16 +665,25 @@ function Set-TargetResource $assignmentsHash = @() foreach ($assignment in $Assignments) { - $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment + $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $assignment } Update-DeviceConfigurationPolicyAssignment ` - -DeviceConfigurationPolicyId $currentInstance.id ` + -DeviceConfigurationPolicyId $currentInstance.Id ` -Targets $assignmentsHash ` -Repository 'deviceManagement/deviceConfigurations' #endregion if ($null -ne $RootCertificatesForServerValidationIds -and $RootCertificatesForServerValidationIds.count -gt 0 ) { + [Array]$rootCertificatesForServerValidationChecked = @() + for ($i = 0; $i -lt $RootCertificatesForServerValidationIds.Count; $i++) + { + $certId = $RootCertificatesForServerValidationIds[$i] + $certName = $RootCertificatesForServerValidationDisplayNames[$i] + $checkedCertId = Get-IntuneDeviceConfigurationCertificateId -CertificateId $certId -CertificateDisplayName $certName -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + $rootCertificatesForServerValidationChecked += $checkedCertId + } + $RootCertificatesForServerValidationIds = $rootCertificatesForServerValidationChecked $compareResult = Compare-Object -ReferenceObject $currentInstance.RootCertificatesForServerValidationIds ` -DifferenceObject $RootCertificatesForServerValidationIds @@ -594,14 +692,14 @@ function Set-TargetResource if ($certsToAdd.count -gt 0) { - Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $certsToAdd ` -CertificateName rootCertificatesForServerValidation } if ($certsToRemove.count -gt 0) { - Remove-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + Remove-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $certsToRemove ` -CertificateName rootCertificatesForServerValidation } @@ -611,9 +709,17 @@ function Set-TargetResource { if ($IdentityCertificateForClientAuthenticationId -ne $currentInstance.IdentityCertificateForClientAuthenticationId) { - Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + $IdentityCertificateForClientAuthenticationId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $IdentityCertificateForClientAuthenticationId ` + -CertificateDisplayName $IdentityCertificateForClientAuthenticationDisplayName ` + -OdataTypes @( ` + '#microsoft.graph.windows81SCEPCertificateProfile', ` + '#microsoft.graph.windows81TrustedRootCertificate', ` + '#microsoft.graph.windows10PkcsCertificateProfile' ` + ) + Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $IdentityCertificateForClientAuthenticationId ` - -CertificateName identityCertificateForClientAuthenticationId + -CertificateName identityCertificateForClientAuthentication } } @@ -621,9 +727,17 @@ function Set-TargetResource { if ($SecondaryIdentityCertificateForClientAuthenticationId -ne $currentInstance.SecondaryIdentityCertificateForClientAuthenticationId) { - Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + $SecondaryIdentityCertificateForClientAuthenticationId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $SecondaryIdentityCertificateForClientAuthenticationId ` + -CertificateDisplayName $SecondaryIdentityCertificateForClientAuthenticationDisplayName ` + -OdataTypes @( ` + '#microsoft.graph.windows81SCEPCertificateProfile', ` + '#microsoft.graph.windows81TrustedRootCertificate', ` + '#microsoft.graph.windows10PkcsCertificateProfile' ` + ) + Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $SecondaryIdentityCertificateForClientAuthenticationId ` - -CertificateName secondaryIdentityCertificateForClientAuthenticationId + -CertificateName secondaryIdentityCertificateForClientAuthentication } } @@ -631,9 +745,13 @@ function Set-TargetResource { if ($RootCertificateForClientValidationId -ne $currentInstance.RootCertificateForClientValidationId) { - Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + $RootCertificateForClientValidationId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $RootCertificateForClientValidationId ` + -CertificateDisplayName $RootCertificateForClientValidationDisplayName ` + -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $RootCertificateForClientValidationId ` - -CertificateName rootCertificateForClientValidationId + -CertificateName rootCertificateForClientValidation } } @@ -641,9 +759,13 @@ function Set-TargetResource { if ($SecondaryRootCertificateForClientValidationId -ne $currentInstance.SecondaryRootCertificateForClientValidationId) { - Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $Id ` + $SecondaryRootCertificateForClientValidationId = Get-IntuneDeviceConfigurationCertificateId ` + -CertificateId $SecondaryRootCertificateForClientValidationId ` + -CertificateDisplayName $SecondaryRootCertificateForClientValidationDisplayName ` + -OdataTypes @('#microsoft.graph.windows81TrustedRootCertificate') + Update-DeviceConfigurationPolicyCertificateId -DeviceConfigurationPolicyId $currentInstance.Id ` -CertificateIds $SecondaryRootCertificateForClientValidationId ` - -CertificateName secondaryRootCertificateForClientValidationId + -CertificateName secondaryRootCertificateForClientValidation } } } @@ -748,22 +870,42 @@ function Test-TargetResource [System.String[]] $RootCertificatesForServerValidationIds, + [Parameter()] + [System.String[]] + $RootCertificatesForServerValidationDisplayNames, + [Parameter()] [System.String] $IdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $IdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $SecondaryIdentityCertificateForClientAuthenticationId, + [Parameter()] + [System.String] + $SecondaryIdentityCertificateForClientAuthenticationDisplayName, + [Parameter()] [System.String] $RootCertificateForClientValidationId, + [Parameter()] + [System.String] + $RootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $SecondaryRootCertificateForClientValidationId, + [Parameter()] + [System.String] + $SecondaryRootCertificateForClientValidationDisplayName, + [Parameter()] [System.String] $Description, @@ -835,34 +977,35 @@ function Test-TargetResource } $testResult = $true - #Compare Cim instances - foreach ($key in $PSBoundParameters.Keys) - { - $source = $PSBoundParameters.$key - $target = $CurrentValues.$key - if ($source.getType().Name -like '*CimInstance*') - { - $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source - - $testResult = Compare-M365DSCComplexObject ` - -Source ($source) ` - -Target ($target) - - if (-Not $testResult) - { - $testResult = $false - break - } - - $ValuesToCheck.Remove($key) | Out-Null - } - } + $testResult = Compare-M365DSCIntunePolicyAssignment -Source $CurrentValues.Assignments -Target $Assignments $ValuesToCheck.remove('Id') | Out-Null $ValuesToCheck.Remove('Credential') | Out-Null $ValuesToCheck.Remove('ApplicationId') | Out-Null $ValuesToCheck.Remove('TenantId') | Out-Null $ValuesToCheck.Remove('ApplicationSecret') | Out-Null + $ValuesToCheck.Remove('Assignments') | Out-Null + + if ($null -ne $ValuesToCheck.RootCertificatesForServerValidationDisplayNames) + { + $ValuesToCheck.Remove('RootCertificatesForServerValidationIds') + } + if ($null -ne $ValuesToCheck.IdentityCertificateForClientAuthenticationDisplayName) + { + $ValuesToCheck.Remove('IdentityCertificateForClientAuthenticationId') + } + if ($null -ne $ValuesToCheck.SecondaryIdentityCertificateForClientAuthenticationDisplayName) + { + $ValuesToCheck.Remove('SecondaryIdentityCertificateForClientAuthenticationId') + } + if ($null -ne $ValuesToCheck.RootCertificateForClientValidationDisplayName) + { + $ValuesToCheck.Remove('RootCertificateForClientValidationId') + } + if ($null -ne $ValuesToCheck.SecondaryRootCertificateForClientValidationDisplayName) + { + $ValuesToCheck.Remove('SecondaryRootCertificateForClientValidationId') + } Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" @@ -967,7 +1110,7 @@ function Export-TargetResource TenantId = $TenantId ApplicationSecret = $ApplicationSecret CertificateThumbprint = $CertificateThumbprint - Managedidentity = $ManagedIdentity.IsPresent + ManagedIdentity = $ManagedIdentity.IsPresent } $Results = Get-TargetResource @Params @@ -1026,7 +1169,7 @@ function Export-TargetResource } } -function Get-DeviceConfigurationPolicyCertificateId +function Get-DeviceConfigurationPolicyCertificate { [CmdletBinding()] [OutputType([System.String], [System.String[]])] @@ -1045,14 +1188,15 @@ function Get-DeviceConfigurationPolicyCertificateId try { $result = Invoke-MgGraphRequest -Method Get -Uri $Uri 4>$null - return $(if ($result.id) - { - $result.id - } - else - { - $result.value.id - }) + + return $(if ($result.value) + { + $result.value + } + else + { + $result + }) } catch { @@ -1080,7 +1224,16 @@ function Update-DeviceConfigurationPolicyCertificateId $CertificateName ) - $Uri = " https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$DeviceConfigurationPolicyId')/microsoft.graph.windowsWiredNetworkConfiguration/$CertificateName/`$ref" + $Uri = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$DeviceConfigurationPolicyId')/microsoft.graph.windowsWiredNetworkConfiguration/$CertificateName/`$ref" + + if ($CertificateName -eq 'rootCertificatesForServerValidation') + { + $method = 'POST' + } + else + { + $method = 'PUT' + } foreach ($certificateId in $CertificateIds) { @@ -1088,7 +1241,7 @@ function Update-DeviceConfigurationPolicyCertificateId '@odata.id' = "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations('$certificateId')" } - Invoke-MgGraphRequest -Method POST -Uri $Uri -Body ($ref | ConvertTo-Json) -ErrorAction Stop 4>$null + Invoke-MgGraphRequest -Method $method -Uri $Uri -Body ($ref | ConvertTo-Json) -ErrorAction Stop 4>$null } } @@ -1118,4 +1271,55 @@ function Remove-DeviceConfigurationPolicyCertificateId } } +function Get-IntuneDeviceConfigurationCertificateId +{ + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [System.String] + $CertificateId, + + [Parameter(Mandatory = $true)] + [System.String] + $CertificateDisplayName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String[]] + $OdataTypes + ) + $Certificate = Get-MgBetaDeviceManagementDeviceConfiguration ` + -DeviceConfigurationId $CertificateId ` + -ErrorAction SilentlyContinue | ` + Where-Object -FilterScript { + $_.AdditionalProperties.'@odata.type' -in $OdataTypes + } + + if ($null -eq $Certificate) + { + Write-Verbose -Message "Could not find certificate with Id {$CertificateId}, searching by display name {$CertificateDisplayName}" + + $Certificate = Get-MgBetaDeviceManagementDeviceConfiguration ` + -Filter "DisplayName eq '$CertificateDisplayName'" ` + -ErrorAction SilentlyContinue | ` + Where-Object -FilterScript { + $_.AdditionalProperties.'@odata.type' -in $OdataTypes + } + + if ($null -eq $Certificate) + { + throw "Could not find certificate with Id {$CertificateId} or display name {$CertificateDisplayName}" + } + + $CertificateId = $Certificate.Id + Write-Verbose -Message "Found certificate with Id {$($CertificateId)} and DisplayName {$($Certificate.DisplayName)}" + } + else + { + Write-Verbose -Message "Found certificate with Id {$CertificateId}" + } + + return $CertificateId +} + Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.schema.mof index 83f16b867e..7f0182c73b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10/MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10.schema.mof @@ -32,10 +32,15 @@ class MSFT_IntuneDeviceConfigurationWiredNetworkPolicyWindows10 : OMI_BaseResour [Write, Description("Specify the secondary authentication method. Possible values are: certificate, usernameAndPassword, derivedCredential. Possible values are: certificate, usernameAndPassword, derivedCredential, unknownFutureValue."), ValueMap{"certificate","usernameAndPassword","derivedCredential","unknownFutureValue"}, Values{"certificate","usernameAndPassword","derivedCredential","unknownFutureValue"}] String SecondaryAuthenticationMethod; [Write, Description("Specify trusted server certificate names.")] String TrustedServerCertificateNames[]; [Write, Description("Specify root certificates for server validation. This collection can contain a maximum of 500 elements.")] String RootCertificatesForServerValidationIds[]; + [Write, Description("Specify root certificate display names for server validation. This collection can contain a maximum of 500 elements.")] String RootCertificatesForServerValidationDisplayNames[]; [Write, Description("Specify identity certificate for client authentication.")] String IdentityCertificateForClientAuthenticationId; + [Write, Description("Specify identity certificate display name for client authentication.")] String IdentityCertificateForClientAuthenticationDisplayName; [Write, Description("Specify root certificate for client validation")] String SecondaryIdentityCertificateForClientAuthenticationId; + [Write, Description("Specify root certificate display name for client validation")] String SecondaryIdentityCertificateForClientAuthenticationDisplayName; [Write, Description("Specify root certificate for client validation.")] String RootCertificateForClientValidationId; + [Write, Description("Specify root certificate display name for client validation.")] String RootCertificateForClientValidationDisplayName; [Write, Description("Specify secondary root certificate for client validation.")] String SecondaryRootCertificateForClientValidationId; + [Write, Description("Specify secondary root certificate display name for client validation.")] String SecondaryRootCertificateForClientValidationDisplayName; [Write, Description("Admin provided description of the Device Configuration.")] String Description; [Key, Description("Admin provided name of the device configuration.")] String DisplayName; [Write, Description("The unique identifier for an entity. Read-only.")] String Id; diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceConfigurationWiredNetworkPolicyWindows10.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceConfigurationWiredNetworkPolicyWindows10.Tests.ps1 index 1ffc2b72ed..552988d1d8 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceConfigurationWiredNetworkPolicyWindows10.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneDeviceConfigurationWiredNetworkPolicyWindows10.Tests.ps1 @@ -50,7 +50,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-MgBetaDeviceManagementDeviceConfigurationAssignment -MockWith { } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { } Mock -CommandName Update-DeviceConfigurationPolicyCertificateId -MockWith { @@ -59,42 +59,68 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Remove-DeviceConfigurationPolicyCertificateId -MockWith { } + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + } + } # Test contexts Context -Name 'The IntuneDeviceConfigurationWiredNetworkPolicyWindows10 should exist but it DOES NOT' -Fixture { BeforeAll { $testParams = @{ - AuthenticationBlockPeriodInMinutes = 25 - AuthenticationMethod = 'certificate' - AuthenticationPeriodInSeconds = 25 - AuthenticationRetryDelayPeriodInSeconds = 25 - AuthenticationType = 'none' - CacheCredentials = $True - Description = 'FakeStringValue' - DisableUserPromptForServerValidation = $True - DisplayName = 'FakeStringValue' - EapolStartPeriodInSeconds = 25 - EapType = 'eapTls' - Enforce8021X = $True - ForceFIPSCompliance = $True - Id = 'FakeStringValue' - InnerAuthenticationProtocolForEAPTTLS = 'unencryptedPassword' - MaximumAuthenticationFailures = 25 - MaximumEAPOLStartMessages = 25 - OuterIdentityPrivacyTemporaryValue = 'FakeStringValue' - PerformServerValidation = $True - RequireCryptographicBinding = $True - SecondaryAuthenticationMethod = 'certificate' - TrustedServerCertificateNames = @('FakeStringValue') - Ensure = 'Present' - Credential = $Credential - RootCertificatesForServerValidationIds = @('a485d322-13cd-43ef-beda-733f656f48ea') - SecondaryIdentityCertificateForClientAuthenticationId = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + AuthenticationBlockPeriodInMinutes = 25 + AuthenticationMethod = 'certificate' + AuthenticationPeriodInSeconds = 25 + AuthenticationRetryDelayPeriodInSeconds = 25 + AuthenticationType = 'none' + CacheCredentials = $True + Description = 'FakeStringValue' + DisableUserPromptForServerValidation = $True + DisplayName = 'FakeStringValue' + EapolStartPeriodInSeconds = 25 + EapType = 'eapTls' + Enforce8021X = $True + ForceFIPSCompliance = $True + Id = 'FakeStringValue' + InnerAuthenticationProtocolForEAPTTLS = 'unencryptedPassword' + MaximumAuthenticationFailures = 25 + MaximumEAPOLStartMessages = 25 + OuterIdentityPrivacyTemporaryValue = 'FakeStringValue' + PerformServerValidation = $True + RequireCryptographicBinding = $True + SecondaryAuthenticationMethod = 'certificate' + TrustedServerCertificateNames = @('FakeStringValue') + Ensure = 'Present' + Credential = $Credential + RootCertificatesForServerValidationIds = @('a485d322-13cd-43ef-beda-733f656f48ea') + RootCertificatesForServerValidationDisplayNames = @('RootCertificate') + SecondaryIdentityCertificateForClientAuthenticationId = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + SecondaryIdentityCertificateForClientAuthenticationDisplayName = 'ClientCertificate' } Mock -CommandName Get-MgBetaDeviceManagementDeviceConfiguration -MockWith { return $null } + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @(@{ + Id = 'a485d322-13cd-43ef-beda-733f656f48ea' + DisplayName = 'RootCertificate' + }) + } -ParameterFilter { $CertificateName -eq 'rootCertificatesForServerValidation' } + + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @{ + Id = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + DisplayName = 'ClientCertificate' + } + } -ParameterFilter { $CertificateName -eq 'secondaryIdentityCertificateForClientAuthentication' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return 'a485d322-13cd-43ef-beda-733f656f48ea' + } -ParameterFilter { $DisplayName -eq 'RootCertificate' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + } -ParameterFilter { $DisplayName -eq 'ClientCertificate' } } It 'Should return Values from the Get method' { (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' @@ -134,9 +160,11 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { SecondaryAuthenticationMethod = 'certificate' TrustedServerCertificateNames = @('FakeStringValue') Ensure = 'Absent' - Credential = $Credential - RootCertificatesForServerValidationIds = @('a485d322-13cd-43ef-beda-733f656f48ea') - SecondaryIdentityCertificateForClientAuthenticationId = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + Credential = $Credential + RootCertificatesForServerValidationIds = @('a485d322-13cd-43ef-beda-733f656f48ea') + RootCertificatesForServerValidationDisplayNames = @('RootCertificate') + SecondaryIdentityCertificateForClientAuthenticationId = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + SecondaryIdentityCertificateForClientAuthenticationDisplayName = 'ClientCertificate' } Mock -CommandName Get-MgBetaDeviceManagementDeviceConfiguration -MockWith { @@ -166,17 +194,30 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Description = 'FakeStringValue' DisplayName = 'FakeStringValue' Id = 'FakeStringValue' - } } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return @('a485d322-13cd-43ef-beda-733f656f48ea') + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @(@{ + Id = 'a485d322-13cd-43ef-beda-733f656f48ea' + DisplayName = 'RootCertificate' + }) } -ParameterFilter { $CertificateName -eq 'rootCertificatesForServerValidation' } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @{ + Id = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + DisplayName = 'ClientCertificate' + } } -ParameterFilter { $CertificateName -eq 'secondaryIdentityCertificateForClientAuthentication' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return 'a485d322-13cd-43ef-beda-733f656f48ea' + } -ParameterFilter { $DisplayName -eq 'RootCertificate' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + } -ParameterFilter { $DisplayName -eq 'ClientCertificate' } } It 'Should return Values from the Get method' { @@ -253,16 +294,21 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return @('a485d322-13cd-43ef-beda-733f656f48ea') + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @(@{ + Id = 'a485d322-13cd-43ef-beda-733f656f48ea' + DisplayName = 'RootCertificate' + }) } -ParameterFilter { $CertificateName -eq 'rootCertificatesForServerValidation' } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @{ + Id = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + DisplayName = 'ClientCertificate' + } } -ParameterFilter { $CertificateName -eq 'secondaryIdentityCertificateForClientAuthentication' } } - It 'Should return true from the Test method' { Test-TargetResource @testParams | Should -Be $true } @@ -296,7 +342,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Ensure = 'Present' Credential = $Credential RootCertificatesForServerValidationIds = @('a485d322-13cd-43ef-beda-733f656f48ea') + RootCertificatesForServerValidationDisplayNames = @('RootCertificate') SecondaryIdentityCertificateForClientAuthenticationId = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + SecondaryIdentityCertificateForClientAuthenticationDisplayName = 'ClientCertificate' } Mock -CommandName Get-MgBetaDeviceManagementDeviceConfiguration -MockWith { @@ -323,13 +371,27 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return @('a485d322-13cd-43ef-beda-733f656f48ea') + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @(@{ + Id = 'a485d322-13cd-43ef-beda-733f656f48ea' + DisplayName = 'RootCertificate' + }) } -ParameterFilter { $CertificateName -eq 'rootCertificatesForServerValidation' } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @{ + Id = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + DisplayName = 'ClientCertificate' + } } -ParameterFilter { $CertificateName -eq 'secondaryIdentityCertificateForClientAuthentication' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return 'a485d322-13cd-43ef-beda-733f656f48ea' + } -ParameterFilter { $DisplayName -eq 'RootCertificate' } + + Mock -CommandName Get-IntuneDeviceConfigurationCertificateId -MockWith { + return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + } -ParameterFilter { $DisplayName -eq 'ClientCertificate' } } It 'Should return Values from the Get method' { @@ -385,12 +447,18 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return @('a485d322-13cd-43ef-beda-733f656f48ea') + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @(@{ + Id = 'a485d322-13cd-43ef-beda-733f656f48ea' + DisplayName = 'RootCertificate' + }) } -ParameterFilter { $CertificateName -eq 'rootCertificatesForServerValidation' } - Mock -CommandName Get-DeviceConfigurationPolicyCertificateId -MockWith { - return '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + Mock -CommandName Get-DeviceConfigurationPolicyCertificate -MockWith { + return @{ + Id = '0b9aef2f-1671-4260-8eb9-3ab3138e176a' + DisplayName = 'ClientCertificate' + } } -ParameterFilter { $CertificateName -eq 'secondaryIdentityCertificateForClientAuthentication' } } It 'Should Reverse Engineer resource from the Export method' {