diff --git a/CHANGELOG.md b/CHANGELOG.md index ccb904dc54..3aaee5b929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Change log for Microsoft365DSC +# 1.25.205.1 + +* AADApplication + * Refactored logic for CIM Instance evaluation in Test-TargetResource. +* AADConditionalAccessPolicy + * Changed the InsiderRiskTypes property to a string array. +* AADConnectorGroupApplicationProxy + * Fixes an issue where the Get-TargetResource was not able to retrieve + instances by names. + * Refactored logic for CIM Instance evaluation in Test-TargetResource. +* AADServicePrincipal + * Fixes comparison of assigned roles for null values. + FIXES [#5717](https://github.com/microsoft/Microsoft365DSC/issues/5717) +* CommerceSelfServicePurchase + * Initial release. +* SCPolicyConfig + * Fixes and issue where Get-TargetResource was returning an empty array + instead of a null value when no values were defined. +* SCRoleGroupMember + * Error handling if the Members parameter is omitted. +* MISC + * Changed the CIMInstance logic of various resources to us common logic. + * Added support for specifying a proxy in Update-M365DSCModule. +* DEPENDENCIES + * Updated MSCloudLoginAssistant to version 1.1.36. + # 1.25.129.3 * EXOMigrationEndpoint diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdminConsentRequestPolicy/MSFT_AADAdminConsentRequestPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdminConsentRequestPolicy/MSFT_AADAdminConsentRequestPolicy.psm1 index 77ebe8e3ec..81ef4cb4d9 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdminConsentRequestPolicy/MSFT_AADAdminConsentRequestPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAdminConsentRequestPolicy/MSFT_AADAdminConsentRequestPolicy.psm1 @@ -358,32 +358,45 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + $testTargetResource = $true Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - $testResult = $true - foreach ($reviewer in $Reviewers) + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) { - $currentEquivalent = $CurrentValues.Reviewers | Where-Object -FilterScript { $_.ReviewerId -eq $reviewer.ReviewerId -and $_.ReviewerType -eq $reviewer.ReviewerType } - if ($null -eq $currentEquivalent) - { - $testResult = $false - Write-Verbose -Message "Couldn't find current reviewer {$($reviewer.ReviewerId)}" - } + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-not $testResult) + { + Write-Verbose "TestResult returned False for $source" + $testTargetResource = $false + } + else + { + $ValuesToCheck.Remove($key) | Out-Null + } + } } - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $ValuesToCheck.Remove('Reviewers') | Out-Null - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 index f950fd7afb..446ac091a5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 @@ -455,11 +455,15 @@ function Get-TargetResource # singleSignOnSettings $singleSignOnValues = @{ - kerberosSignOnSettings = @{ + singleSignOnMode = $oppInfo.singleSignOnSettings.singleSignOnMode + } + if ($oppInfo.singleSignOnMode.kerberosSignOnSettings) + { + $kerberosSignOnSettings = @{ kerberosServicePrincipalName = $oppInfo.singleSignOnSettings.kerberosSignOnSettings.kerberosServicePrincipalName kerberosSignOnMappingAttributeType = $oppInfo.singleSignOnSettings.kerberosSignOnSettings.kerberosSignOnMappingAttributeType } - singleSignOnMode = $oppInfo.singleSignOnSettings.singleSignOnMode + $singleSignOnValues.Add('kerberosSignOnSettings', $kerberosSignOnSettings) } $onPremisesPublishingValue.Add('singleSignOnSettings', $singleSignOnValues) } @@ -1415,50 +1419,7 @@ function Test-TargetResource Write-Verbose -Message 'Testing configuration of AzureAD Application' $CurrentValues = Get-TargetResource @PSBoundParameters - - if ($CurrentValues.Permissions.Length -gt 0 -and $null -ne $CurrentValues.Permissions.Name -and ` - $null -ne $Permissions) - { - $differenceObject = $Permissions.Name - if ($null -eq $differenceObject) - { - $differenceObject = @() - } - $permissionsDiff = Compare-Object -ReferenceObject ($CurrentValues.Permissions.Name) -DifferenceObject $differenceObject - $driftedParams = @{} - if ($null -ne $permissionsDiff) - { - Write-Verbose -Message "Permissions differ: $($permissionsDiff | Out-String)" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventValue = "$($CurrentValues.Permissions.Name)" - $EventValue += "$($Permissions.Name)" - $driftedParams.Add('Permissions', $EventValue) - } - else - { - Write-Verbose -Message 'Permissions for Azure AD Application are the same' - } - } - else - { - $driftedParams = @{} - if ($Permissions.Length -gt 0) - { - Write-Verbose -Message 'No Permissions exist for the current Azure AD App, but permissions were specified for desired state' - Write-Verbose -Message "Test-TargetResource returned $false" - - $EventValue = "`$null" - $EventValue += "$($Permissions.Name)" - $driftedParams.Add('Permissions', $EventValue) - } - else - { - Write-Verbose -Message 'No Permissions exist for the current Azure AD App and no permissions were specified' - } - } - $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - $testTargetResource = $true #Compare Cim instances @@ -1466,7 +1427,7 @@ function Test-TargetResource { $source = $PSBoundParameters.$key $target = $CurrentValues.$key - if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*' -and $source -notlike '*Permission*') + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') { $testResult = Compare-M365DSCComplexObject ` -Source ($source) ` @@ -1489,7 +1450,6 @@ function Test-TargetResource $ValuesToCheck.Remove('ObjectId') | Out-Null $ValuesToCheck.Remove('AppId') | Out-Null - $ValuesToCheck.Remove('Permissions') | Out-Null $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` @@ -1598,9 +1558,29 @@ function Export-TargetResource { $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results + if ($Results.Permissions.Count -gt 0) { - $Results.Permissions = Get-M365DSCAzureADAppPermissionsAsString $Results.Permissions + $complexMapping = @( + @{ + Name = 'Permissions' + CimInstanceName = 'MSFT_AADApplicationPermission' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Permissions ` + -CIMInstanceName 'MSFT_AADApplicationPermission' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.Permissions = $complexTypeStringResult + } + else + { + $Results.Remove('Permissions') | Out-Null + } } if ($null -ne $Results.Api) @@ -1733,7 +1713,6 @@ function Export-TargetResource } } - if ($null -ne $Results.KeyCredentials) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` @@ -1793,16 +1772,20 @@ function Export-TargetResource if ($null -ne $Results.Permissions) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` - -ParameterName 'Permissions' + -ParameterName 'Permissions' ` + -IsCIMArray:$True } + if ($Results.OptionalClaims) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'OptionalClaims' -IsCIMArray:$False } + if ($Results.OnPremisesPublishing) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'OnPremisesPublishing' -IsCIMArray:$False } + if ($Results.AuthenticationBehaviors) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'AuthenticationBehaviors' -IsCIMArray:$False diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicy/MSFT_AADAuthenticationMethodPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicy/MSFT_AADAuthenticationMethodPolicy.psm1 index f7e9ea30e0..5fe37db211 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicy/MSFT_AADAuthenticationMethodPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicy/MSFT_AADAuthenticationMethodPolicy.psm1 @@ -508,6 +508,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -518,7 +519,7 @@ function Test-TargetResource { $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source - $testResult = Compare-M365DSCComplexObject ` + $testTargetResource = Compare-M365DSCComplexObject ` -Source ($source) ` -Target ($target) @@ -537,17 +538,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyAuthenticator/MSFT_AADAuthenticationMethodPolicyAuthenticator.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyAuthenticator/MSFT_AADAuthenticationMethodPolicyAuthenticator.psm1 index 22a9b92b6b..718c596575 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyAuthenticator/MSFT_AADAuthenticationMethodPolicyAuthenticator.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyAuthenticator/MSFT_AADAuthenticationMethodPolicyAuthenticator.psm1 @@ -789,6 +789,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -805,7 +806,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -818,17 +819,18 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyEmail/MSFT_AADAuthenticationMethodPolicyEmail.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyEmail/MSFT_AADAuthenticationMethodPolicyEmail.psm1 index 446b1aeda4..8a36cdb0d9 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyEmail/MSFT_AADAuthenticationMethodPolicyEmail.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyEmail/MSFT_AADAuthenticationMethodPolicyEmail.psm1 @@ -453,6 +453,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -469,7 +470,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -482,17 +483,18 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyExternal/MSFT_AADAuthenticationMethodPolicyExternal.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyExternal/MSFT_AADAuthenticationMethodPolicyExternal.psm1 index 3d165e0f60..23ce0be271 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyExternal/MSFT_AADAuthenticationMethodPolicyExternal.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyExternal/MSFT_AADAuthenticationMethodPolicyExternal.psm1 @@ -439,6 +439,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -455,7 +456,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -466,17 +467,18 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyFido2/MSFT_AADAuthenticationMethodPolicyFido2.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyFido2/MSFT_AADAuthenticationMethodPolicyFido2.psm1 index f7582a366b..00d2df7dfc 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyFido2/MSFT_AADAuthenticationMethodPolicyFido2.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyFido2/MSFT_AADAuthenticationMethodPolicyFido2.psm1 @@ -483,6 +483,7 @@ function Test-TargetResource $testResult = $true #Compare Cim instances + $testTargetResource = $true foreach ($key in $PSBoundParameters.Keys) { $source = $PSBoundParameters.$key @@ -497,7 +498,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -510,17 +511,18 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyHardware/MSFT_AADAuthenticationMethodPolicyHardware.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyHardware/MSFT_AADAuthenticationMethodPolicyHardware.psm1 index 723b4f0a83..1d85e1d98c 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyHardware/MSFT_AADAuthenticationMethodPolicyHardware.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyHardware/MSFT_AADAuthenticationMethodPolicyHardware.psm1 @@ -425,6 +425,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -441,7 +442,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -454,17 +455,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySms/MSFT_AADAuthenticationMethodPolicySms.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySms/MSFT_AADAuthenticationMethodPolicySms.psm1 index 188fdcc9b9..c1d4ed5197 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySms/MSFT_AADAuthenticationMethodPolicySms.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySms/MSFT_AADAuthenticationMethodPolicySms.psm1 @@ -429,6 +429,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -445,7 +446,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -458,17 +459,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySoftware/MSFT_AADAuthenticationMethodPolicySoftware.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySoftware/MSFT_AADAuthenticationMethodPolicySoftware.psm1 index 7d8bd7934c..07a0658607 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySoftware/MSFT_AADAuthenticationMethodPolicySoftware.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicySoftware/MSFT_AADAuthenticationMethodPolicySoftware.psm1 @@ -428,6 +428,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -444,7 +445,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -457,17 +458,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyTemporary/MSFT_AADAuthenticationMethodPolicyTemporary.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyTemporary/MSFT_AADAuthenticationMethodPolicyTemporary.psm1 index 1ad824f844..72881fe434 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyTemporary/MSFT_AADAuthenticationMethodPolicyTemporary.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyTemporary/MSFT_AADAuthenticationMethodPolicyTemporary.psm1 @@ -497,6 +497,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances Write-Verbose -Message 'Evaluating keys' @@ -514,7 +515,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -527,17 +528,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyVoice/MSFT_AADAuthenticationMethodPolicyVoice.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyVoice/MSFT_AADAuthenticationMethodPolicyVoice.psm1 index bde2d43b71..d77839ccfb 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyVoice/MSFT_AADAuthenticationMethodPolicyVoice.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyVoice/MSFT_AADAuthenticationMethodPolicyVoice.psm1 @@ -441,6 +441,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -457,7 +458,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -470,17 +471,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyX509/MSFT_AADAuthenticationMethodPolicyX509.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyX509/MSFT_AADAuthenticationMethodPolicyX509.psm1 index 46edf9edb9..c3b23dc7d0 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyX509/MSFT_AADAuthenticationMethodPolicyX509.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationMethodPolicyX509/MSFT_AADAuthenticationMethodPolicyX509.psm1 @@ -505,6 +505,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -521,7 +522,7 @@ function Test-TargetResource if (-Not $testResult) { - $testResult = $false + $testTargetResource = $false break } @@ -534,17 +535,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationRequirement/MSFT_AADAuthenticationRequirement.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationRequirement/MSFT_AADAuthenticationRequirement.psm1 index bcb1ce332d..8ab33aa514 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationRequirement/MSFT_AADAuthenticationRequirement.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationRequirement/MSFT_AADAuthenticationRequirement.psm1 @@ -243,21 +243,16 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() - $testResult = $true - $CurrentValues.remove('Id') | Out-Null $ValuesToCheck.remove('Id') | Out-Null Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) - { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys - } + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys Write-Verbose -Message "Test-TargetResource returned $testResult" diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationStrengthPolicy/MSFT_AADAuthenticationStrengthPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationStrengthPolicy/MSFT_AADAuthenticationStrengthPolicy.psm1 index 1f31b32475..b6574a5ca9 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationStrengthPolicy/MSFT_AADAuthenticationStrengthPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADAuthenticationStrengthPolicy/MSFT_AADAuthenticationStrengthPolicy.psm1 @@ -299,18 +299,14 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $ValuesToCheck.Remove('Id') | Out-Null - $testResult = $true Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) - { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys - } + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys Write-Verbose -Message "Test-TargetResource returned $testResult" diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADClaimsMappingPolicy/MSFT_AADClaimsMappingPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADClaimsMappingPolicy/MSFT_AADClaimsMappingPolicy.psm1 index 0e69584348..2929e98968 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADClaimsMappingPolicy/MSFT_AADClaimsMappingPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADClaimsMappingPolicy/MSFT_AADClaimsMappingPolicy.psm1 @@ -416,6 +416,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -430,6 +431,7 @@ function Test-TargetResource if (-not $testResult) { + $testTargetResource = $false break } @@ -443,17 +445,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.psm1 index 331a56ecc3..20c557d1a8 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.psm1 @@ -225,7 +225,7 @@ function Get-TargetResource [Parameter()] [ValidateSet('minor', 'moderate', 'elevated', 'unknownFutureValue')] - [System.String] + [System.String[]] $InsiderRiskLevels, #generic @@ -649,6 +649,12 @@ function Get-TargetResource } } + $InsiderRiskLevelsValue = $null + if (-not [System.String]::IsNullOrEmpty($Policy.Conditions.InsiderRiskLevels)) + { + $InsiderRiskLevelsValue = $Policy.Conditions.InsiderRiskLevels.Split(',') + } + $result = @{ DisplayName = $Policy.DisplayName Id = $Policy.Id @@ -727,7 +733,7 @@ function Get-TargetResource TransferMethods = [System.String]$Policy.Conditions.AuthenticationFlows.TransferMethods #Standard part TermsOfUse = $termOfUseName - InsiderRiskLevels = $Policy.Conditions.InsiderRiskLevels + InsiderRiskLevels = $InsiderRiskLevelsValue Ensure = 'Present' Credential = $Credential ApplicationSecret = $ApplicationSecret @@ -968,7 +974,7 @@ function Set-TargetResource [Parameter()] [ValidateSet('minor', 'moderate', 'elevated', 'unknownFutureValue')] - [System.String] + [System.String[]] $InsiderRiskLevels, #generic @@ -1687,7 +1693,7 @@ function Set-TargetResource if ([String]::IsNullOrEmpty($InsiderRiskLevels) -eq $false) { - $conditions.Add('insiderRiskLevels', $InsiderRiskLevels) + $conditions.Add('insiderRiskLevels', $($InsiderRiskLevels -join ',')) } Write-Verbose -Message 'Set-Targetresource: process risk levels and app types' @@ -2165,7 +2171,7 @@ function Test-TargetResource [Parameter()] [ValidateSet('minor', 'moderate', 'elevated', 'unknownFutureValue')] - [System.String] + [System.String[]] $InsiderRiskLevels, #generic @@ -2202,43 +2208,63 @@ function Test-TargetResource [System.String[]] $AccessTokens ) + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion Write-Verbose -Message 'Testing configuration of AzureAD CA Policies' $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $testResult = $true + $testTargetResource = $true - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) + { + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) - $ValuesToCheck = $PSBoundParameters - $ValuesToCheck.Remove('Id') | Out-Null + if (-not $testResult) + { + $testTargetResource = $false + break + } - # If no TransferMethod is specified, ignore it - # If a TransferMethod is specified, check if it is equal to the current value - # while ignoring the order of the values - if (-not $PSBoundParameters.ContainsKey('TransferMethods') -or - $null -eq (Compare-Object -ReferenceObject $TransferMethods.Split(',') -DifferenceObject $CurrentValues.TransferMethods.Split(','))) - { - $ValuesToCheck.Remove('TransferMethods') | Out-Null - $TestResult = $true - } - else - { - Write-Verbose -Message "TransferMethods are not equal: [$TransferMethods] - [$($CurrentValues.TransferMethods)]" - $TestResult = $false + $ValuesToCheck.Remove($key) | Out-Null + } } - if ($TestResult) - { - $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys - } + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck - Write-Verbose -Message "Test-TargetResource returned $TestResult" + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys - return $TestResult + if (-not $TestResult) + { + $testTargetResource = $false + } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.schema.mof index 556ec8f895..339c98e9b3 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConditionalAccessPolicy/MSFT_AADConditionalAccessPolicy.schema.mof @@ -51,7 +51,7 @@ class MSFT_AADConditionalAccessPolicy : OMI_BaseResource [Write, Description("Name of the associated authentication strength policy.")] String AuthenticationStrength; [Write, Description("Names of the associated authentication flow transfer methods. Possible values are '', 'deviceCodeFlow', 'authenticationTransfer', or 'deviceCodeFlow,authenticationTransfer'.")] String TransferMethods; [Write, Description("Authentication context class references.")] String AuthenticationContexts[]; - [Write, Description("Insider risk levels conditions."), ValueMap{"minor", "moderate", "elevated", "unknownFutureValue"}, Values{"minor", "moderate", "elevated", "unknownFutureValue"}] String InsiderRiskLevels; + [Write, Description("Insider risk levels conditions."), ValueMap{"minor", "moderate", "elevated", "unknownFutureValue"}, Values{"minor", "moderate", "elevated", "unknownFutureValue"}] String InsiderRiskLevels[]; [Write, Description("Specify if the Azure AD CA Policy should exist or not."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("Credentials for the Microsoft Graph delegated permissions."), EmbeddedInstance("MSFT_Credential")] string Credential; [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConnectorGroupApplicationProxy/MSFT_AADConnectorGroupApplicationProxy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConnectorGroupApplicationProxy/MSFT_AADConnectorGroupApplicationProxy.psm1 index ccbbbd5ffc..dd84363bb8 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADConnectorGroupApplicationProxy/MSFT_AADConnectorGroupApplicationProxy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADConnectorGroupApplicationProxy/MSFT_AADConnectorGroupApplicationProxy.psm1 @@ -83,7 +83,7 @@ function Get-TargetResource if ($null -eq $getValue -and -not [string]::IsNullOrEmpty($Id)) { Write-Verbose -Message "Could not find an Azure AD Connector Group Application Proxy with Name {$Name}" - if (-not [string]::IsNullOrEmpty($DisplayName)) + if (-not [string]::IsNullOrEmpty($Name)) { $getValue = Get-MgBetaOnPremisePublishingProfileConnectorGroup -OnPremisesPublishingProfileId 'applicationProxy' -Filter "Name eq '$Name'" -ErrorAction Stop } @@ -326,13 +326,10 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) - { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys - } + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys Write-Verbose -Message "Test-TargetResource returned $testResult" diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationDefault/MSFT_AADCrossTenantAccessPolicyConfigurationDefault.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationDefault/MSFT_AADCrossTenantAccessPolicyConfigurationDefault.psm1 index e4983b150a..5851e16ace 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationDefault/MSFT_AADCrossTenantAccessPolicyConfigurationDefault.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationDefault/MSFT_AADCrossTenantAccessPolicyConfigurationDefault.psm1 @@ -350,6 +350,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -367,7 +368,7 @@ function Test-TargetResource if (-Not $testResult) { Write-Verbose -Message "Difference found for $key" - $testResult = $false + $testTargetResource = $false break } @@ -378,17 +379,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationPartner/MSFT_AADCrossTenantAccessPolicyConfigurationPartner.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationPartner/MSFT_AADCrossTenantAccessPolicyConfigurationPartner.psm1 index 73af68b8ec..1c6ac48434 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationPartner/MSFT_AADCrossTenantAccessPolicyConfigurationPartner.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCrossTenantAccessPolicyConfigurationPartner/MSFT_AADCrossTenantAccessPolicyConfigurationPartner.psm1 @@ -385,6 +385,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() $testResult = $true + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -402,7 +403,7 @@ function Test-TargetResource if (-Not $testResult) { Write-Verbose -Message "Difference found for $key" - $testResult = $false + $testTargetResource = $false break } @@ -413,17 +414,17 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" - if ($testResult) + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + if (-not $TestResult) { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + $testTargetResource = $false } - - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCustomAuthenticationExtension/MSFT_AADCustomAuthenticationExtension.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCustomAuthenticationExtension/MSFT_AADCustomAuthenticationExtension.psm1 index 368dc4b401..6232ccaf5f 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADCustomAuthenticationExtension/MSFT_AADCustomAuthenticationExtension.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADCustomAuthenticationExtension/MSFT_AADCustomAuthenticationExtension.psm1 @@ -498,6 +498,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + $testTargetResource = $true #Compare Cim instances foreach ($key in $PSBoundParameters.Keys) @@ -530,9 +531,12 @@ function Test-TargetResource -DesiredValues $PSBoundParameters ` -ValuesToCheck $ValuesToCheck.Keys - Write-Verbose -Message "Test-TargetResource returned $testResult" - - return $testResult + if (-not $TestResult) + { + $testTargetResource = $false + } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 index eb80eb01e7..3adde8eeb7 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 @@ -1065,128 +1065,47 @@ function Test-TargetResource Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" - # Check Licenses - if (-not ($null -eq $AssignedLicenses -and $null -eq $CurrentValues.AssignedLicenses)) + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck.Remove('Id') | Out-Null + + $testTargetResource = $true + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) { - try + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') { - if ($null -ne $CurrentValues.AssignedLicenses -and $CurrentValues.AssignedLicenses.Length -gt 0 -and ` - ($PSBoundParameters.ContainsKey('AssignedLicenses') -and $null -eq $AssignedLicenses)) - { - Write-Verbose -Message "The group {$DisplayName} currently has licenses assigned but it shouldn't" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventMessage = "Assigned Licenses for Azure AD Group {$DisplayName} were not in the desired state.`r`nThe group should not have any licenses assigned but instead contained {$($CurrentValues.AssignedLicenses.SkuId -join ',')}" - Add-M365DSCEvent -Message $EventMessage -EntryType 'Warning' ` - -EventID 1 -Source $($MyInvocation.MyCommand.Source) + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) - return $false - } - elseif ($null -eq $CurrentValues.AssignedLicenses -and $null -ne $AssignedLicenses -and ` - $AssignedLicenses.Length -gt 0) + if (-not $testResult) { - Write-Verbose -Message "The group {$DisplayName} currently doesn't have licenses assigned but it should" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventMessage = "Assigned Licenses for Azure AD Group {$DisplayName} were not in the desired state.`r`nThe group doesn't not have any licenses assigned but should have {$($CurrentValues.AssignedLicenses.SkuId -join ',')}" - Add-M365DSCEvent -Message $EventMessage -EntryType 'Warning' ` - -EventID 1 -Source $($MyInvocation.MyCommand.Source) - - return $false - } - elseif ($CurrentValues.AssignedLicenses.Length -gt 0 -and $AssignedLicenses.Length -gt 0) - { - Write-Verbose -Message "Current assigned licenses and desired assigned licenses for group {$DisplayName} are not null and will be compared" - $licensesDiff = Compare-Object -ReferenceObject ($CurrentValues.AssignedLicenses.SkuId) -DifferenceObject ($AssignedLicenses.SkuId) - if ($null -ne $licensesDiff) - { - Write-Verbose -Message "AssignedLicenses differ for group {$DisplayName}: $($licensesDiff | Out-String)" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventMessage = "Assigned Licenses for Azure AD Group {$DisplayName} were not in the desired state.`r`nThey should contain {$($AssignedLicenses.SkuId -join ',')} but instead contained {$($CurrentValues.AssignedLicenses.SkuId -join ',')}" - Add-M365DSCEvent -Message $EventMessage -EntryType 'Warning' ` - -EventID 1 -Source $($MyInvocation.MyCommand.Source) - - return $false - } - else - { - Write-Verbose -Message "AssignedLicenses for Azure AD Group {$DisplayName} are the same, checking DisabledPlans" - } - - # Disabled Plans - #Compare DisabledPlans for each SkuId - all SkuId's are processed regardless of result - $result = $true - foreach ($assignedLicense in $AssignedLicenses) - { - Write-Verbose "Compare DisabledPlans for SkuId $($assignedLicense.SkuId) in group {$DisplayName}" - $currentLicense = $CurrentValues.AssignedLicenses | Where-Object -FilterScript { $_.SkuId -eq $assignedLicense.SkuId } - if ($assignedLicense.DisabledPlans.Count -ne 0 -or $currentLicense.DisabledPlans.Count -ne 0) - { - try - { - $licensesDiff = Compare-Object -ReferenceObject $assignedLicense.DisabledPlans -DifferenceObject $currentLicense.DisabledPlans - if ($null -ne $licensesDiff) - { - Write-Verbose -Message "DisabledPlans for SkuId $($assignedLicense.SkuId) differ: $($licensesDiff | Out-String)" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventMessage = "Disabled Plans for Azure AD Group Licenses {$DisplayName} SkuId $($assignedLicense.SkuId) were not in the desired state.`r`n" + ` - "They should contain {$($assignedLicense.DisabledPlans -join ',')} but instead contained {$($currentLicense.DisabledPlans -join ',')}" - Add-M365DSCEvent -Message $EventMessage -EntryType 'Warning' ` - -EventID 1 -Source $($MyInvocation.MyCommand.Source) - - $result = $false - } - else - { - Write-Verbose -Message "DisabledPlans for SkuId $($assignedLicense.SkuId) are the same" - } - } - catch - { - Write-Verbose -Message "Test-TargetResource returned `$false (DisabledPlans: $($_.Exception.Message))" - $result = $false - } - } - } - if ($true -ne $result) - { - return $result - } - } - elseif ($PSBoundParameters.ContainsKey('AssignedLicenses')) - { - Write-Verbose -Message "The group {$DisplayName} currently has licenses assigned but it shouldn't have" - Write-Verbose -Message "Test-TargetResource returned $false" - $EventMessage = "Assigned Licenses for Azure AD Group {$DisplayName} were not in the desired state.`r`nThe group has licenses assigned but shouldn't have {$($CurrentValues.AssignedLicenses.SkuId)}" - Add-M365DSCEvent -Message $EventMessage -EntryType 'Warning' ` - -EventID 1 -Source $($MyInvocation.MyCommand.Source) - - return $false + Write-Verbose "TestResult returned False for $source" + $testTargetResource = $false } else { - Write-Verbose -Message "Both the current and desired assigned licenses lists for group {$DisplayName} are empty or not specified." + $ValuesToCheck.Remove($key) | Out-Null } } - catch - { - Write-Verbose -Message "Error evaluating the AssignedLicenses for group {$DisplayName}: $_" - Write-Verbose -Message "Test-TargetResource returned $false" - return $false - } } - $ValuesToCheck = $PSBoundParameters - $ValuesToCheck.Remove('Id') | Out-Null - $ValuesToCheck.Remove('GroupTypes') | Out-Null - $ValuesToCheck.Remove('AssignedLicenses') | Out-Null - $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` -DesiredValues $PSBoundParameters ` -ValuesToCheck $ValuesToCheck.Keys - Write-Verbose -Message "Test-TargetResource returned $TestResult" + if (-not $TestResult) + { + $testTargetResource = $false + } + + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" - return $TestResult + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.psm1 index d911ffb734..1ab23ab5eb 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension/MSFT_AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.psm1 @@ -389,6 +389,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + $testTargetResource = $true Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" @@ -405,23 +406,30 @@ function Test-TargetResource if (-not $testResult) { - break + Write-Verbose "TestResult returned False for $source" + $testTargetResource = $false + } + else + { + $ValuesToCheck.Remove($key) | Out-Null } - - $ValuesToCheck.Remove($key) | Out-Null } } - if ($testResult) - { - $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys - } - Write-Verbose -Message "Test-TargetResource returned $testResult" + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys - return $testResult + if (-not $TestResult) + { + $testTargetResource = $false + } + Write-Verbose -Message "Test-TargetResource returned $testTargetResource" + return $testTargetResource } function Export-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADServicePrincipal/MSFT_AADServicePrincipal.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADServicePrincipal/MSFT_AADServicePrincipal.psm1 index e4d0baf0a7..56b00a3eee 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADServicePrincipal/MSFT_AADServicePrincipal.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADServicePrincipal/MSFT_AADServicePrincipal.psm1 @@ -609,6 +609,15 @@ function Set-TargetResource [Array]$currentPrincipals = $currentAADServicePrincipal.AppRoleAssignedTo.Identity [Array]$desiredPrincipals = $AppRoleAssignedTo.Identity + if ($null -eq $currentPrincipals) + { + $currentPrincipals = @() + } + if ($null -eq $desiredPrincipals) + { + $desiredPrincipals = @() + } + [Array]$differences = Compare-Object -ReferenceObject $currentPrincipals -DifferenceObject $desiredPrincipals [Array]$membersToAdd = $differences | Where-Object -FilterScript { $_.SideIndicator -eq '=>' } [Array]$membersToRemove = $differences | Where-Object -FilterScript { $_.SideIndicator -eq '<=' } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.psm1 new file mode 100644 index 0000000000..4e3bde1a8d --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.psm1 @@ -0,0 +1,381 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ProductId, + + [Parameter(Mandatory = $true)] + [System.String] + $ProductName, + + [Parameter()] + [ValidateSet('Enabled', 'Disabled', 'OnlyTrialsWithoutPaymentMethod')] + [System.String] + $PolicyValue, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + New-M365DSCConnection -Workload 'Licensing' ` + -InboundParameters $PSBoundParameters | Out-Null + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + try + { + if ($null -ne $Script:exportedInstances -and $Script:ExportMode) + { + $instance = $Script:exportedInstances.items | Where-Object -FilterScript {$_.ProductId -eq $ProductId} + } + else + { + $uri = (Get-MSCloudLoginConnectionProfile -Workload 'Licensing').HostUrl + "/v1/policies/AllowSelfServicePurchase/products/$($ProductId)" + $instance = Invoke-M365DSCLicensingWebRequest -Uri $uri -Method 'GET' + } + + if ($null -eq $instance) + { + return $nullResult + } + + $results = @{ + ProductId = $instance.ProductId + ProductName = $instance.ProductName + PolicyValue = $instance.PolicyValue + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + return [System.Collections.Hashtable] $results + } + catch + { + Write-Verbose -Message $_ + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ProductId, + + [Parameter(Mandatory = $true)] + [System.String] + $ProductName, + + [Parameter()] + [System.String] + [ValidateSet('Enabled', 'Disabled', 'OnlyTrialsWithoutPaymentMethod')] + $PolicyValue, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentInstance = Get-TargetResource @PSBoundParameters + $setParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + if ($Ensure -eq 'Absent') + { + throw "Ensure cannot be absent. This resource can only update existing Self Service Purchase Policies." + } + + $uri = (Get-MSCloudLoginConnectionProfile -Workload 'Licensing').HostUrl + "/v1/policies/AllowSelfServicePurchase/products/$($ProductId)" + $body = @{ + policyValue = $PolicyValue + } + Write-Verbose -Message "Updating Policy for {$ProductName} to value {$PolicyValue}" + Invoke-M365DSCLicensingWebRequest -Uri $uri -Method 'PUT' -Body $body | Out-Null +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ProductId, + + [Parameter(Mandatory = $true)] + [System.String] + $ProductName, + + [Parameter()] + [System.String] + [ValidateSet('Enabled', 'Disabled', 'OnlyTrialsWithoutPaymentMethod')] + $PolicyValue, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'Licensing' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + $Script:ExportMode = $true + $uri = (Get-MSCloudLoginConnectionProfile -Workload 'Licensing').HostUrl + '/v1/policies/AllowSelfServicePurchase/products' + [array] $Script:exportedInstances = Invoke-M365DSCLicensingWebRequest -Uri $uri -Method 'GET' + + $i = 1 + $dscContent = '' + if ($Script:exportedInstances.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $Script:exportedInstances.items) + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + + $displayedKey = $config.ProductName + Write-Host " |---[$i/$($Script:exportedInstances.items.Count)] $displayedKey" -NoNewline + $params = @{ + ProductId = $config.productId + ProductName = $config.productName + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.schema.mof new file mode 100644 index 0000000000..ff3351516e --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/MSFT_CommerceSelfServicePurchase.schema.mof @@ -0,0 +1,15 @@ +[ClassVersion("1.0.0.0"), FriendlyName("CommerceSelfServicePurchase")] +class MSFT_CommerceSelfServicePurchase : OMI_BaseResource +{ + [Key, Description("Unique ID of the product.")] String ProductId; + [Write, Description("Name of the product")] String ProductName; + [Write, Description("Can be Enabled or Disabled."), ValueMap{"Enabled","Disabled", "OnlyTrialsWithoutPaymentMethod"}, Values{"Enabled","Disabled", "OnlyTrialsWithoutPaymentMethod"}] String PolicyValue; + + [Write, Description("Present ensures the instance exists, absent ensures it is removed."), ValueMap{"Absent","Present"}, Values{"Absent","Present"}] string Ensure; + [Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; + [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; + [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; + [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; + [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; + [Write, Description("Access token used for authentication.")] String AccessTokens[]; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/readme.md new file mode 100644 index 0000000000..d5244037e0 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/readme.md @@ -0,0 +1,6 @@ + +# CommerceSelfServicePurchase + +## Description + +Manages the Self Purchase policies in commerce. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/settings.json new file mode 100644 index 0000000000..e79b4e3f34 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_CommerceSelfServicePurchase/settings.json @@ -0,0 +1,25 @@ +{ + "resourceName": "CommerceSelfServicePurchase", + "description": "Manages the Self Purchase policies in commerce.", + "roles": {}, + "permissions": { + "aeb86249-8ea3-49e2-900b-54cc8e308f85": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [ + { + "name": "Policy.Read.AllowSelfServicePurchase" + } + ], + "update": [ + { + "name": "Policy.ReadWrite.AllowSelfServicePurchase" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 index 4724190c7a..50be26fa9f 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 @@ -954,10 +954,21 @@ function Export-TargetResource $Results.Remove('ValidOperatingSystemBuildRanges') | Out-Null } } - if ($Results.Assignments) + if ($null -ne $Results.Assignments) { - $complexTypeStringResult = Get-M365DSCAssignmentsAsString -Params $Results.Assignments - if ($complexTypeStringResult) + $complexMapping = @( + @{ + Name = 'Assignments' + CimInstanceName = 'MSFT_DeviceManagementConfigurationPolicyAssignments' + sRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Assignments ` + -CIMInstanceName 'MSFT_DeviceManagementConfigurationPolicyAssignments' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) { $Results.Assignments = $complexTypeStringResult } @@ -971,10 +982,12 @@ function Export-TargetResource -ModulePath $PSScriptRoot ` -Results $Results ` -Credential $Credential + if ($Results.ValidOperatingSystemBuildRanges) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'ValidOperatingSystemBuildRanges' } + if ($Results.Assignments) { $isCIMArray = $false @@ -982,7 +995,9 @@ function Export-TargetResource { $isCIMArray = $true } - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$isCIMArray + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'Assignments' ` + -IsCIMArray:$isCIMArray } $dscContent += $currentDSCBlock diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyiOS/MSFT_IntuneDeviceConfigurationPolicyiOS.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyiOS/MSFT_IntuneDeviceConfigurationPolicyiOS.psm1 index 49e066acc4..7dd7765973 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyiOS/MSFT_IntuneDeviceConfigurationPolicyiOS.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyiOS/MSFT_IntuneDeviceConfigurationPolicyiOS.psm1 @@ -3126,7 +3126,7 @@ function Export-TargetResource $Results.Remove('CompliantAppsList') | Out-Null } } - if ($Results.MediaContentRatingAustralia) + if ($Results.MediaContentRatingAustralia.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingAustralia -CIMInstanceName MicrosoftGraphmediacontentratingaustralia if ($complexTypeStringResult) @@ -3138,7 +3138,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingAustralia') | Out-Null } } - if ($Results.MediaContentRatingCanada) + else + { + $Results.Remove('MediaContentRatingAustralia') | Out-Null + } + if ($Results.MediaContentRatingCanada.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingCanada -CIMInstanceName MicrosoftGraphmediacontentratingcanada if ($complexTypeStringResult) @@ -3150,7 +3154,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingCanada') | Out-Null } } - if ($Results.MediaContentRatingFrance) + else + { + $Results.Remove('MediaContentRatingCanada') | Out-Null + } + if ($Results.MediaContentRatingFrance.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingFrance -CIMInstanceName MicrosoftGraphmediacontentratingfrance if ($complexTypeStringResult) @@ -3162,7 +3170,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingFrance') | Out-Null } } - if ($Results.MediaContentRatingGermany) + else + { + $Results.Remove('MediaContentRatingFrance') | Out-Null + } + if ($Results.MediaContentRatingGermany.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingGermany -CIMInstanceName MicrosoftGraphmediacontentratinggermany if ($complexTypeStringResult) @@ -3174,7 +3186,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingGermany') | Out-Null } } - if ($Results.MediaContentRatingIreland) + else + { + $Results.Remove('MediaContentRatingGermany') | Out-Null + } + if ($Results.MediaContentRatingIreland.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingIreland -CIMInstanceName MicrosoftGraphmediacontentratingireland if ($complexTypeStringResult) @@ -3186,7 +3202,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingIreland') | Out-Null } } - if ($Results.MediaContentRatingJapan) + else + { + $Results.Remove('MediaContentRatingIreland') | Out-Null + } + if ($Results.MediaContentRatingJapan.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingJapan -CIMInstanceName MicrosoftGraphmediacontentratingjapan if ($complexTypeStringResult) @@ -3198,7 +3218,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingJapan') | Out-Null } } - if ($Results.MediaContentRatingNewZealand) + else + { + $Results.Remove('MediaContentRatingJapan') | Out-Null + } + if ($Results.MediaContentRatingNewZealand.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingNewZealand -CIMInstanceName MicrosoftGraphmediacontentratingnewzealand if ($complexTypeStringResult) @@ -3210,7 +3234,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingNewZealand') | Out-Null } } - if ($Results.MediaContentRatingUnitedKingdom) + else + { + $Results.Remove('MediaContentRatingNewZealand') | Out-Null + } + if ($Results.MediaContentRatingUnitedKingdom.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingUnitedKingdom -CIMInstanceName MicrosoftGraphmediacontentratingunitedkingdom if ($complexTypeStringResult) @@ -3222,7 +3250,11 @@ function Export-TargetResource $Results.Remove('MediaContentRatingUnitedKingdom') | Out-Null } } - if ($Results.MediaContentRatingUnitedStates) + else + { + $Results.Remove('MediaContentRatingUnitedKingdom') | Out-Null + } + if ($Results.MediaContentRatingUnitedStates.Count -gt 0) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.MediaContentRatingUnitedStates -CIMInstanceName MicrosoftGraphmediacontentratingunitedstates if ($complexTypeStringResult) @@ -3234,6 +3266,10 @@ function Export-TargetResource $Results.Remove('MediaContentRatingUnitedStates') | Out-Null } } + else + { + $Results.Remove('MediaContentRatingUnitedStates') | Out-Null + } if ($Results.NetworkUsageRules) { $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.NetworkUsageRules -CIMInstanceName MicrosoftGraphiosnetworkusagerule diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantIsolationSettings/MSFT_PPTenantIsolationSettings.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantIsolationSettings/MSFT_PPTenantIsolationSettings.psm1 index baab2973c4..9c814828a6 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantIsolationSettings/MSFT_PPTenantIsolationSettings.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantIsolationSettings/MSFT_PPTenantIsolationSettings.psm1 @@ -673,9 +673,28 @@ function Export-TargetResource if ($Results -is [System.Collections.Hashtable] -and $Results.Count -gt 1) { - if ($Results.Rules.Count -gt 0) + if ($null -ne $Results.Rules) { - $Results.Rules = Get-M365DSCTenantIsolationRule $Results.Rules + $complexMapping = @( + @{ + Name = 'Rules' + CimInstanceName = 'MSFT_PPTenantRule' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Rules ` + -CIMInstanceName 'MSFT_PPTenantRule' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.Rules = $complexTypeStringResult + } + else + { + $Results.Remove('Rules') | Out-Null + } } $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results @@ -688,7 +707,8 @@ function Export-TargetResource if ($null -ne $Results.Rules) { $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` - -ParameterName 'Rules' + -ParameterName 'Rules' ` + -IsCIMArray:$True } $dscContent += $currentDSCBlock diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SCLabelPolicy/MSFT_SCLabelPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SCLabelPolicy/MSFT_SCLabelPolicy.psm1 index 8251861bbc..cfa1b4179d 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SCLabelPolicy/MSFT_SCLabelPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SCLabelPolicy/MSFT_SCLabelPolicy.psm1 @@ -856,7 +856,26 @@ function Export-TargetResource if ($null -ne $Results.AdvancedSettings) { - $Results.AdvancedSettings = ConvertTo-AdvancedSettingsString -AdvancedSettings $Results.AdvancedSettings + $complexMapping = @( + @{ + Name = 'AdvancedSettings' + CimInstanceName = 'MSFT_SCLabelSetting' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.AdvancedSettings ` + -CIMInstanceName 'MSFT_SCLabelSetting' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.AdvancedSettings = $complexTypeStringResult + } + else + { + $Results.Remove('AdvancedSettings') | Out-Null + } } $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` @@ -868,7 +887,9 @@ function Export-TargetResource -Credential $Credential if ($null -ne $Results.AdvancedSettings) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'AdvancedSettings' + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'AdvancedSettings' ` + -IsCIMArray:$True } Write-Host $Global:M365DSCEmojiGreenCheckMark diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SCPolicyConfig/MSFT_SCPolicyConfig.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SCPolicyConfig/MSFT_SCPolicyConfig.psm1 index 44dcc01cb4..73129306fd 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SCPolicyConfig/MSFT_SCPolicyConfig.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SCPolicyConfig/MSFT_SCPolicyConfig.psm1 @@ -440,7 +440,7 @@ function Get-TargetResource $DlpNetworkShareGroupsValue += $entry } - $QuarantineParametersValue = @() + $QuarantineParametersValue = $null if ($null -ne ($EndpointDlpGlobalSettingsValue | Where-Object { $_.Setting -eq 'QuarantineParameters' })) { $quarantineInfo = [Array]($EndpointDlpGlobalSettingsValue | Where-Object { $_.Setting -eq 'QuarantineParameters' }).Value diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SCRoleGroupMember/MSFT_SCRoleGroupMember.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SCRoleGroupMember/MSFT_SCRoleGroupMember.psm1 index 64e0ac78e1..bf15678b89 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SCRoleGroupMember/MSFT_SCRoleGroupMember.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SCRoleGroupMember/MSFT_SCRoleGroupMember.psm1 @@ -90,12 +90,21 @@ function Get-TargetResource } # Get RoleGroup Members if RoleGroup exists. - $roleGroupMember = Get-RoleGroupMember -Identity $Name | Select-Object Name + $roleGroupMembers = Get-RoleGroupMember -Identity $Name | Select-Object Name + + if ($roleGroupMembers.Length -eq 0) + { + $roleGroupMembersValue = @() + } + else + { + $roleGroupMembersValue = $roleGroupMembers.Name + } $result = @{ Name = $RoleGroup.Name Description = $RoleGroup.Description - Members = $roleGroupMember.Name + Members = $roleGroupMembersValue Ensure = 'Present' Credential = $Credential ApplicationId = $ApplicationId @@ -193,10 +202,23 @@ function Set-TargetResource -InboundParameters $PSBoundParameters # CASE: Role Group has different member values than the desired ones - if ($Ensure -eq 'Present' -and $currentRoleGroupConfig.Ensure -eq 'Present' -and $null -ne (Compare-Object -ReferenceObject $($currentRoleGroupConfig.Members) -DifferenceObject $Members)) + $MembersValue = $Members + if ([System.String]::IsNullOrEmpty($Members)) + { + $MembersValue = @() + } + + $currentMembersValue = $currentRoleGroupConfig.Members + if ([System.String]::IsNullOrEmpty($currentRoleGroupConfig.Members)) + { + $currentMembersValue = @() + } + + $differences = Compare-Object -ReferenceObject $currentMembersValue -DifferenceObject $MembersValue + + if ($Ensure -eq 'Present' -and $currentRoleGroupConfig.Ensure -eq 'Present' -and $null -ne $differences) { Write-Verbose -Message "Role Group '$($Name)' exists, but members need updating." - $differences = Compare-Object -ReferenceObject $($currentRoleGroupConfig.Members) -DifferenceObject $Members foreach ($difference in $differences) { if ($difference.SideIndicator -eq '=>') @@ -294,6 +316,7 @@ function Test-TargetResource Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" $ValuesToCheck = $PSBoundParameters + $ValuesToCheck.Remove('Description') | Out-Null $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SCSensitivityLabel/MSFT_SCSensitivityLabel.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SCSensitivityLabel/MSFT_SCSensitivityLabel.psm1 index 7a1f174e2c..f612a1a7ac 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SCSensitivityLabel/MSFT_SCSensitivityLabel.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SCSensitivityLabel/MSFT_SCSensitivityLabel.psm1 @@ -1598,17 +1598,96 @@ function Export-TargetResource if ($null -ne $Results.AdvancedSettings) { - $Results.AdvancedSettings = ConvertTo-AdvancedSettingsString -AdvancedSettings $Results.AdvancedSettings + $complexMapping = @( + @{ + Name = 'AdvancedSettings' + CimInstanceName = 'MSFT_SCLabelSetting' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.AdvancedSettings ` + -CIMInstanceName 'MSFT_SCLabelSetting' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.AdvancedSettings = $complexTypeStringResult + } + else + { + $Results.Remove('AdvancedSettings') | Out-Null + } } if ($null -ne $Results.LocaleSettings) { - $Results.LocaleSettings = ConvertTo-LocaleSettingsString -LocaleSettings $Results.LocaleSettings + $complexMapping = @( + @{ + Name = 'LocaleSettings' + CimInstanceName = 'MSFT_SCLabelLocaleSettings' + IsRequired = $False + } + @{ + Name = 'LabelSettings' + CimInstanceName = 'MSFT_SCLabelSetting' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.LocaleSettings ` + -CIMInstanceName 'MSFT_SCLabelLocaleSettings' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.LocaleSettings = $complexTypeStringResult + } + else + { + $Results.Remove('LocaleSettings') | Out-Null + } } + if ($null -ne $Results.AutoLabelingSettings) { - $Results.AutoLabelingSettings = ConvertTo-AutoLabelingSettingsString -AutoLabelingSettings $Results.AutoLabelingSettings + $complexMapping = @( + @{ + Name = 'AutoLabelingSettings' + CimInstanceName = 'MSFT_SCSLAutoLabelingSettings' + IsRequired = $False + } + @{ + Name = 'Groups' + CimInstanceName = 'MSFT_SCSLSensitiveInformationGroup' + IsRequired = $False + } + @{ + Name = 'SensitiveInformationType' + CimInstanceName = 'MSFT_SCSLSensitiveInformationType' + IsRequired = $False + } + @{ + Name = 'TrainableClassifier' + CimInstanceName = 'MSFT_SCSLTrainableClassifiers' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.AutoLabelingSettings ` + -CIMInstanceName 'MSFT_SCSLAutoLabelingSettings' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.AutoLabelingSettings = $complexTypeStringResult + } + else + { + $Results.Remove('AutoLabelingSettings') | Out-Null + } } + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` @@ -1616,17 +1695,24 @@ function Export-TargetResource -ModulePath $PSScriptRoot ` -Results $Results ` -Credential $Credential + if ($null -ne $Results.AdvancedSettings) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'AdvancedSettings' + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'AdvancedSettings' ` + -IsCIMArray:$True } if ($null -ne $Results.LocaleSettings) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'LocaleSettings' + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'LocaleSettings' ` + -IsCIMArray:$True } if ($null -ne $Results.AutoLabelingSettings) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'AutoLabelingSettings' + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'AutoLabelingSettings' ` + -IsCIMArray:$True } Write-Host $Global:M365DSCEmojiGreenCheckMark diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOTheme/MSFT_SPOTheme.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOTheme/MSFT_SPOTheme.psm1 index 5e4066479f..41683bf973 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOTheme/MSFT_SPOTheme.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOTheme/MSFT_SPOTheme.psm1 @@ -432,7 +432,29 @@ function Export-TargetResource $Results = Get-TargetResource @Params $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results - $Results.Palette = ConvertTo-SPOThemePalettePropertyString $Results.Palette + if ($null -ne $Results.Palette) + { + $complexMapping = @( + @{ + Name = 'OptionalClaims' + CimInstanceName = 'MSFT_SPOThemePaletteProperty' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Palette ` + -CIMInstanceName 'MSFT_SPOThemePaletteProperty' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.Palette = $complexTypeStringResult + } + else + { + $Results.Remove('Palette') | Out-Null + } + } $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` -ConnectionMode $ConnectionMode ` -ModulePath $PSScriptRoot ` diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 index 06c347aa47..d491711ba1 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 @@ -353,7 +353,30 @@ function Export-TargetResource $Global:M365DSCExportResourceInstancesCount++ } - $Results.Properties = ConvertTo-M365DSCSPOUserProfilePropertyInstanceString -Properties $Results.Properties + if ($null -ne $Results.Properties) + { + $complexMapping = @( + @{ + Name = 'Properties' + CimInstanceName = 'MSFT_SPOUserProfilePropertyInstance' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.Properties ` + -CIMInstanceName 'MSFT_SPOUserProfilePropertyInstance' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.Properties = $complexTypeStringResult + } + else + { + $Results.Remove('Properties') | Out-Null + } + } + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` -Results $Results $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` @@ -363,7 +386,9 @@ function Export-TargetResource -Credential $Credential if ($null -ne $Results.Properties) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Properties' + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'Properties' ` + -IsCIMArray:$True } $dscContent += $currentDSCBlock Save-M365DSCPartialExport -Content $currentDSCBlock ` diff --git a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 index b8b8009b49..75ba341060 100644 --- a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 +++ b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 @@ -122,7 +122,7 @@ }, @{ ModuleName = "MSCloudLoginAssistant" - RequiredVersion = "1.1.35" + RequiredVersion = "1.1.36" }, @{ ModuleName = 'PnP.PowerShell' diff --git a/Modules/Microsoft365DSC/Examples/Resources/CommerceSelfServicePurchase/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/CommerceSelfServicePurchase/2-Update.ps1 new file mode 100644 index 0000000000..527caf2fd9 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/CommerceSelfServicePurchase/2-Update.ps1 @@ -0,0 +1,35 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + CommerceSelfServicePurchase "Power Apps per user" + { + ApplicationId = $ApplicationId; + CertificateThumbprint = $CertificateThumbprint; + Ensure = "Present"; + PolicyValue = "Enabled"; + ProductId = "CFQ7TTC0LH2H"; + ProductName = "Power Apps per user"; + TenantId = $TenantId; + } + } +} diff --git a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 index 2ca6216f5a..9bf591d877 100644 --- a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 +++ b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 @@ -3,7 +3,7 @@ # # Generated by: Microsoft Corporation # -# Generated on: 2025-01-31 +# Generated on: 2025-02-05 @{ @@ -11,7 +11,7 @@ # RootModule = '' # Version number of this module. - ModuleVersion = '1.25.129.3' + ModuleVersion = '1.25.205.1' # Supported PSEditions # CompatiblePSEditions = @() @@ -84,6 +84,7 @@ 'Modules/WorkloadHelpers/M365DSCAzureDevOPSHelper.psm1', 'Modules/WorkloadHelpers/M365DSCDefenderHelper.psm1', 'Modules/WorkloadHelpers/M365DSCFabricHelper.psm1', + 'Modules/WorkloadHelpers/M365DSCLicensingHelper.psm1', 'Modules/M365DSCConfigurationHelper.psm1' ) @@ -147,16 +148,28 @@ IconUri = 'https://github.com/microsoft/Microsoft365DSC/blob/Dev/Modules/Microsoft365DSC/Dependencies/Images/Logo.png?raw=true' # ReleaseNotes of this module - ReleaseNotes = '* EXOMigrationEndpoint - * Added support for EntpointType value of ExchangeRemoteMove. -* M365DSCRuleEvaluation - * Changed logic to evaluate cases where the rule results in no results. -* SPDLPComplianceRule - * Fix for the SensitiveInfoType ID cleaning logic in Get-TargetResource. + ReleaseNotes = '* AADConditionalAccessPolicy + * Changed the InsiderRiskTypes property to a string array. +* AADConnectorGroupApplicationProxy + * Fixes an issue where the Get-TargetResource was not able to retrieve + instances by names. +* AADGroup + * Refactored logic for CIM Instance evaluation in Test-TargetResource. +* AADServicePrincipal + * Fixes comparison of assigned roles for null values. + FIXES [#5717](https://github.com/microsoft/Microsoft365DSC/issues/5717) +* CommerceSelfServicePurchase + * Initial release. +* SCPolicyConfig + * Fixes and issue where Get-TargetResource was returning an empty array + instead of a null value when no values were defined. +* SCRoleGroupMember + * Error handling if the Members parameter is omitted. +* MISC + * Changed the CIMInstance logic of various resources to us common logic. + * Added support for specifying a proxy in Update-M365DSCModule. * DEPENDENCIES - * Updated Microsoft.PowerApps.Administration.PowerShell to version 2.0.205. - * Updated MicrosoftTeams to version 6.8.0. - * Updated MSCloudLoginAssistant to version 1.1.35.' + * Updated MSCloudLoginAssistant to version 1.1.36.' # Flag to indicate whether the module requires explicit user acceptance for install/update # RequireLicenseAcceptance = $false diff --git a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 index 4f82942a31..538080fda8 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 @@ -659,19 +659,49 @@ function Compare-M365DSCComplexObject foreach ($item in $Source) { + $foundMatch = $false foreach ($targetItem in $Target) { - $compareResult = Compare-M365DSCComplexObject ` - -Source $item ` - -Target $targetItem + if (-not $foundMatch) + { + $compareResult = Compare-M365DSCComplexObject ` + -Source $item ` + -Target $targetItem + + if ($compareResult) + { + $foundMatch = $true + } + } + } + + if (-not $foundMatch) + { + Write-Verbose -Message 'Configuration drift - The complex array items are not identical' + return $false + } + } - if ($compareResult) + # Do the opposite check + foreach ($item in $target) + { + $foundMatch = $false + foreach ($targetItem in $Source) + { + if (-not $foundMatch) { - break + $compareResult = Compare-M365DSCComplexObject ` + -Source $item ` + -Target $targetItem + + if ($compareResult) + { + $foundMatch = $true + } } } - if (-not $compareResult) + if (-not $foundMatch) { Write-Verbose -Message 'Configuration drift - The complex array items are not identical' return $false @@ -720,121 +750,130 @@ function Compare-M365DSCComplexObject foreach ($key in $keys) { - #Matching possible key names between Source and Target - $sourceValue = $Source.$key - - # Some classes might contain default properties that have the same name as the key, - # so we need to check if the key is present in the target object --> Hashtable <-> IsReadOnly property - if ($key -in $targetKeys) + if (($target.GetType().Name -eq 'Hashtable' -and $target.ContainsKey($key)) -or ` + ($target.GetType().Name -eq 'CIMInstance' -and $null -ne $target.$key)) { - $targetValue = $Target.$key - } - else - { - $targetValue = $null - } + #Matching possible key names between Source and Target + $sourceValue = $Source.$key - #One of the item is null and not the other - if (($Source.$key.Length -eq 0) -xor ($targetValue.Length -eq 0)) - { - if ($null -eq $Source.$key) + # Some classes might contain default properties that have the same name as the key, + # so we need to check if the key is present in the target object --> Hashtable <-> IsReadOnly property + if ($key -in $targetKeys) { - $sourceValue = 'null' + $targetValue = $Target.$key } - - if ($null -eq $targetValue) + else { - $targetValue = 'null' + $targetValue = $null } - Write-Verbose -Message "Configuration drift - key: $key" - Write-Verbose -Message "Source {$sourceValue}" - Write-Verbose -Message "Target {$targetValue}" - return $false - } - - #Both keys aren't null or empty - if (($null -ne $Source.$key) -and ($null -ne $Target.$key)) - { - if ($Source.$key.GetType().FullName -like '*CimInstance*' -or $Source.$key.GetType().FullName -like '*hashtable*') + #One of the item is null and not the other + if (($Source.$key.Length -eq 0) -xor ($targetValue.Length -eq 0)) { - if ($Source.$key.GetType().FullName -like '*CimInstance' -and ( - $Source.$key.CimClass.CimClassName -eq 'MSFT_DeviceManagementConfigurationPolicyAssignments' -or - $Source.$key.CimClass.CimClassName -like 'MSFT_DeviceManagementMobileAppAssignment' -or - $Source.$key.CimClass.CimClassName -like 'MSFT_Intune*Assignments' - )) + if ($null -eq $Source.$key) { - $compareResult = Compare-M365DSCIntunePolicyAssignment ` - -Source @($Source.$key) ` - -Target @($Target.$key) - } - else - { - #Recursive call for complex object - $compareResult = Compare-M365DSCComplexObject ` - -Source $Source.$key ` - -Target $Target.$key + $sourceValue = 'null' } - if (-not $compareResult) + if ($null -eq $targetValue) { - Write-Verbose -Message "Configuration drift - complex object key: $key" - Write-Verbose -Message "Source {$sourceValue}" - Write-Verbose -Message "Target {$targetValue}" - return $false + $targetValue = 'null' } + + Write-Verbose -Message "Configuration drift - key: $key" + Write-Verbose -Message "Source {$sourceValue}" + Write-Verbose -Message "Target {$targetValue}" + return $false } - else - { - #Simple object comparison - $referenceObject = $Target.$key - $differenceObject = $Source.$key - #Identifying date from the current values - $targetType = ($Target.$key.GetType()).Name - if ($targetType -like '*Date*') + #Both keys aren't null or empty + if (($null -ne $Source.$key) -and ($null -ne $Target.$key)) + { + if ($Source.$key.GetType().FullName -like '*CimInstance*' -or $Source.$key.GetType().FullName -like '*hashtable*' -or ` + $Source.$key.GetType().Name -eq 'Object[]') { - $compareResult = $true - $sourceDate = [DateTime]$Source.$key - if ($sourceDate -ne $targetType) + if ($Source.$key.GetType().FullName -like '*CimInstance' -and ( + $Source.$key.CimClass.CimClassName -eq 'MSFT_DeviceManagementConfigurationPolicyAssignments' -or + $Source.$key.CimClass.CimClassName -like 'MSFT_DeviceManagementMobileAppAssignment' -or + $Source.$key.CimClass.CimClassName -like 'MSFT_Intune*Assignments' + )) + { + $compareResult = Compare-M365DSCIntunePolicyAssignment ` + -Source @($Source.$key) ` + -Target @($Target.$key) + } + else { - $compareResult = $null + #Recursive call for complex object + $compareResult = Compare-M365DSCComplexObject ` + -Source $Source.$key ` + -Target $Target.$key + } + + if (-not $compareResult) + { + Write-Verbose -Message "Configuration drift - complex object key: $key" + Write-Verbose -Message "Source {$sourceValue}" + Write-Verbose -Message "Target {$targetValue}" + return $false } } - elseif ($targetType -eq 'String') + else { - # Align line breaks - if (-not [System.String]::IsNullOrEmpty($referenceObject)) + #Simple object comparison + $referenceObject = $Target.$key + $differenceObject = $Source.$key + + #Identifying date from the current values + $targetType = ($Target.$key.GetType()).Name + if ($targetType -like '*Date*') { - $referenceObject = $referenceObject.Replace("`r`n", "`n") + $compareResult = $true + $sourceDate = [DateTime]$Source.$key + if ($sourceDate -ne $targetType) + { + $compareResult = $null + } } + elseif ($targetType -eq 'String') + { + # Align line breaks + if (-not [System.String]::IsNullOrEmpty($referenceObject)) + { + $referenceObject = $referenceObject.Replace("`r`n", "`n") + } + + if (-not [System.String]::IsNullOrEmpty($differenceObject)) + { + $differenceObject = $differenceObject.Replace("`r`n", "`n") + } - if (-not [System.String]::IsNullOrEmpty($differenceObject)) + $compareResult = $true + $ordinalComparison = [System.String]::Equals($referenceObject, $differenceObject, [System.StringComparison]::Ordinal) + if (-not $ordinalComparison) + { + $compareResult = $false + } + elseif ($ordinalComparison) + { + $compareResult = $null + } + } + else { - $differenceObject = $differenceObject.Replace("`r`n", "`n") + $compareResult = Compare-Object ` + -ReferenceObject ($referenceObject) ` + -DifferenceObject ($differenceObject) } - $compareResult = $true - $ordinalComparison = [System.String]::Equals($referenceObject, $differenceObject, [System.StringComparison]::Ordinal) - if ($ordinalComparison) + if ($null -ne $compareResult -and $compareResult.Length -gt 0) { - $compareResult = $null + Write-Verbose -Message "Configuration drift - simple object key: $key" + Write-Verbose -Message "Source {$sourceValue}" + Write-Verbose -Message "Target {$targetValue}" + return $false } } - else - { - $compareResult = Compare-Object ` - -ReferenceObject ($referenceObject) ` - -DifferenceObject ($differenceObject) - } - - if ($null -ne $compareResult) - { - Write-Verbose -Message "Configuration drift - simple object key: $key" - Write-Verbose -Message "Source {$sourceValue}" - Write-Verbose -Message "Target {$targetValue}" - return $false - } } } } diff --git a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 index 5d201c08be..a1e21f45cc 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 @@ -667,7 +667,7 @@ function Test-M365DSCParameterState $propertyName = $existingDrift.Keys[0] $value = $existingDrift."$propertyName" $start = $value.IndexOf('') - $currentValue = $value.Substring(0, $start).Replace('', '') + $currentValue = $value.Substring(0, $start).Replace('', '') $desiredValue = $value.Substring($start+15, ($value.Length)-($start+15)).Replace('', '').Replace('', '') $DriftObject.DriftInfo.Add($propertyName, @{ PropertyName = $propertyName @@ -1881,7 +1881,7 @@ function New-M365DSCConnection param ( [Parameter(Mandatory = $true)] - [ValidateSet('AdminAPI', 'Azure', 'AzureDevOPS', 'DefenderForEndPoint', 'ExchangeOnline', 'Fabric', 'Intune', ` + [ValidateSet('AdminAPI', 'Azure', 'AzureDevOPS', 'DefenderForEndPoint', 'ExchangeOnline', 'Fabric', 'Intune', 'Licensing', ` 'SecurityComplianceCenter', 'PnP', 'PowerPlatforms', ` 'MicrosoftTeams', 'MicrosoftGraph', 'SharePointOnlineREST', 'Tasks', 'AdminAPI')] [System.String] @@ -3256,9 +3256,14 @@ function Update-M365DSCDependencies [Parameter()] [Switch] $ValidateOnly, + [Parameter()] [ValidateSet("CurrentUser", "AllUsers")] - $Scope = "AllUsers" + $Scope = "AllUsers", + + [Parameter()] + [System.String] + $Proxy ) try @@ -3273,6 +3278,12 @@ function Update-M365DSCDependencies $returnValue = @() + $params = @{} + if (-not [System.String]::IsNullOrEmpty($Proxy)) + { + $params.Add('Proxy', $Proxy) + } + foreach ($dependency in $dependencies) { Write-Progress -Activity 'Scanning dependencies' -PercentComplete ($i / $dependencies.Count * 100) @@ -3328,7 +3339,7 @@ function Update-M365DSCDependencies Remove-Module 'Microsoft.Graph.Authentication' -Force -ErrorAction SilentlyContinue } Remove-Module $dependency.ModuleName -Force -ErrorAction SilentlyContinue - Install-Module $dependency.ModuleName -RequiredVersion $dependency.RequiredVersion -AllowClobber -Force -Scope "$Scope" + Install-Module $dependency.ModuleName -RequiredVersion $dependency.RequiredVersion -AllowClobber -Force -Scope "$Scope" @Params } } @@ -4788,11 +4799,22 @@ function Update-M365DSCModule param( [Parameter()] [ValidateSet("CurrentUser", "AllUsers")] - $Scope = "AllUsers" + $Scope = "AllUsers", + + [Parameter()] + [System.String] + $Proxy ) + + $params = @{} + + if (-not [System.String]::IsNullOrEmpty($proxy)) + { + $params.Add('Proxy', $Proxy) + } try { - Update-Module -Name 'Microsoft365DSC' -ErrorAction Stop + Update-Module -Name 'Microsoft365DSC' @Params -ErrorAction Stop } catch { @@ -4821,7 +4843,7 @@ function Update-M365DSCModule -Source $($MyInvocation.MyCommand.Source) throw $_ } - Update-M365DSCDependencies -Scope $Scope + Update-M365DSCDependencies -Scope $Scope -Proxy $Proxy Uninstall-M365DSCOutdatedDependencies } diff --git a/Modules/Microsoft365DSC/Modules/WorkloadHelpers/M365DSCLicensingHelper.psm1 b/Modules/Microsoft365DSC/Modules/WorkloadHelpers/M365DSCLicensingHelper.psm1 new file mode 100644 index 0000000000..0f3d582353 --- /dev/null +++ b/Modules/Microsoft365DSC/Modules/WorkloadHelpers/M365DSCLicensingHelper.psm1 @@ -0,0 +1,37 @@ +function Invoke-M365DSCLicensingWebRequest +{ + [OutputType([PSCustomObject])] + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [System.String] + $Uri, + + [Parameter()] + [System.String] + $Method = 'GET', + + [Parameter()] + [System.Collections.Hashtable] + $Body + ) + + $headers = @{ + Authorization = (Get-MSCloudLoginConnectionProfile -Workload 'Licensing').AccessToken + } + + $bodyValue = $null + if (-not [System.String]::IsNullOrEmpty($Body)) + { + $bodyValue = ConvertTo-Json $Body -Depth 10 -Compress + } + + $response = Invoke-WebRequest -Method $Method ` + -Uri $Uri ` + -Headers $headers ` + -Body $bodyValue ` + -ContentType 'application/json' ` + -UseBasicParsing + $result = ConvertFrom-Json $response.Content + return $result +} diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index 5f6af0a306..0b2e35b51d 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -3543,7 +3543,7 @@ "Option": "Write" }, { - "CIMType": "String", + "CIMType": "String[]", "Name": "InsiderRiskLevels", "Option": "Write" }, @@ -11180,6 +11180,61 @@ } ] }, + { + "ClassName": "MSFT_CommerceSelfServicePurchase", + "Parameters": [ + { + "CIMType": "String", + "Name": "ProductId", + "Option": "Key" + }, + { + "CIMType": "String", + "Name": "ProductName", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "PolicyValue", + "Option": "Write" + }, + { + "CIMType": "string", + "Name": "Ensure", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_DefenderDeviceAuthenticatedScanDefinitionAuthenticationParams", "Parameters": [ diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAdminConsentRequestPolicy.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAdminConsentRequestPolicy.Tests.ps1 index 8c913408a9..ffdc8e6f41 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAdminConsentRequestPolicy.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAdminConsentRequestPolicy.Tests.ps1 @@ -65,7 +65,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -157,7 +157,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { IsEnabled = $true NotifyReviewers = $False; RemindersEnabled = $True; - RequestDurationInDays = 30; + RequestDurationInDays = 29; #drift Reviewers = @( @{ Query = "/v1.0/users/e362df2b-8f61-4e5a-9e5e-c6069f3ed2ee" diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyEmail.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyEmail.Tests.ps1 index 28aa707b8c..c589de3da5 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyEmail.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyEmail.Tests.ps1 @@ -40,7 +40,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -257,7 +257,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } ) Id = "Email" - State = "enabled" + State = "disabled" #drift } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyHardware.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyHardware.Tests.ps1 index 0e851d7849..038e750eed 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyHardware.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyHardware.Tests.ps1 @@ -40,7 +40,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -250,7 +250,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } ) Id = "HardwareOath" - State = "enabled" + State = "disabled" #drift } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySms.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySms.Tests.ps1 index 4f17ec150d..a74168d1f9 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySms.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySms.Tests.ps1 @@ -40,7 +40,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -250,7 +250,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } ) Id = "Sms" - State = "enabled" + State = "disabled" #drift } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySoftware.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySoftware.Tests.ps1 index a3cb95ca17..8ce780ab86 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySoftware.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicySoftware.Tests.ps1 @@ -40,7 +40,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -250,7 +250,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } ) Id = "SoftwareOath" - State = "enabled" + State = "disabled" #drift } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyX509.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyX509.Tests.ps1 index a717fc5802..c66f82f913 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyX509.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADAuthenticationMethodPolicyX509.Tests.ps1 @@ -40,7 +40,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts @@ -361,7 +361,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } ) Id = "X509Certificate" - State = "enabled" + State = "disabled" #drift } } } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADClaimsMappingPolicy.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADClaimsMappingPolicy.Tests.ps1 index a462d49748..4b0dc9bbd7 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADClaimsMappingPolicy.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADClaimsMappingPolicy.Tests.ps1 @@ -49,7 +49,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADCrossTenantAccessPolicyConfigurationDefault.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADCrossTenantAccessPolicyConfigurationDefault.Tests.ps1 index 762fca96ae..a2fd67819d 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADCrossTenantAccessPolicyConfigurationDefault.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADCrossTenantAccessPolicyConfigurationDefault.Tests.ps1 @@ -50,7 +50,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance =$null $Script:ExportMode = $false } # Test contexts diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.Tests.ps1 index cf2811f30c..a82cc21fc1 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADIdentityGovernanceLifecycleWorkflowCustomTaskExtension.Tests.ps1 @@ -51,7 +51,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } - $Script:exportedInstances =$null + $Script:exportedInstance = $null $Script:ExportMode = $false } # Test contexts diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.CommerceSelfServicePurchase.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.CommerceSelfServicePurchase.Tests.ps1 new file mode 100644 index 0000000000..4ed6ad62f0 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.CommerceSelfServicePurchase.Tests.ps1 @@ -0,0 +1,152 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + BeforeAll { + + $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force + $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) + + Mock -CommandName Confirm-M365DSCDependencies -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + # Test contexts + Context -Name "The instance should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + PolicyValue = "Enabled"; + ProductId = "CFQ7TTC0LH2H"; + ProductName = "Power Apps per user"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Invoke-M365DSCLicensingWebRequest -MockWith { + return $null + } + } + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + PolicyValue = "Enabled"; + ProductId = "CFQ7TTC0LH2H"; + ProductName = "Power Apps per user"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Invoke-M365DSCLicensingWebRequest -MockWith { + return @{ + policyValue = "Enabled" + productId = "CFQ7TTC0LH2H"; + productName = "Power Apps per user"; + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + PolicyValue = "Enabled"; + ProductId = "CFQ7TTC0LH2H"; + ProductName = "Power Apps per user"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Invoke-M365DSCLicensingWebRequest -MockWith { + return @{ + policyValue = "Disabled" # Drift + productId = "CFQ7TTC0LH2H"; + productName = "Power Apps per user"; + } + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Invoke-M365DSCLicensingWebRequest -Exactly 2 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Invoke-M365DSCLicensingWebRequest -MockWith { + return @{ + items = @( + @{ + policyValue = "Enabled" + productId = "CFQ7TTC0LH2H"; + productName = "Power Apps per user"; + } + ) + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/docs/docs/resources/azure-ad/AADConditionalAccessPolicy.md b/docs/docs/resources/azure-ad/AADConditionalAccessPolicy.md index 489253d06c..4767b232df 100644 --- a/docs/docs/resources/azure-ad/AADConditionalAccessPolicy.md +++ b/docs/docs/resources/azure-ad/AADConditionalAccessPolicy.md @@ -54,7 +54,7 @@ | **AuthenticationStrength** | Write | String | Name of the associated authentication strength policy. | | | **TransferMethods** | Write | String | Names of the associated authentication flow transfer methods. Possible values are '', 'deviceCodeFlow', 'authenticationTransfer', or 'deviceCodeFlow,authenticationTransfer'. | | | **AuthenticationContexts** | Write | StringArray[] | Authentication context class references. | | -| **InsiderRiskLevels** | Write | String | Insider risk levels conditions. | `minor`, `moderate`, `elevated`, `unknownFutureValue` | +| **InsiderRiskLevels** | Write | StringArray[] | Insider risk levels conditions. | `minor`, `moderate`, `elevated`, `unknownFutureValue` | | **Ensure** | Write | String | Specify if the Azure AD CA Policy should exist or not. | `Present`, `Absent` | | **Credential** | Write | PSCredential | Credentials for the Microsoft Graph delegated permissions. | | | **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | diff --git a/docs/docs/resources/azure/CommerceSelfServicePurchase.md b/docs/docs/resources/azure/CommerceSelfServicePurchase.md new file mode 100644 index 0000000000..dab6e24bb7 --- /dev/null +++ b/docs/docs/resources/azure/CommerceSelfServicePurchase.md @@ -0,0 +1,64 @@ +# CommerceSelfServicePurchase + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **ProductId** | Key | String | Unique ID of the product. | | +| **ProductName** | Write | String | Name of the product | | +| **PolicyValue** | Write | String | Can be Enabled or Disabled. | `Enabled`, `Disabled`, `OnlyTrialsWithoutPaymentMethod` | +| **Ensure** | Write | String | Present ensures the instance exists, absent ensures it is removed. | `Absent`, `Present` | +| **Credential** | Write | PSCredential | Credentials of the workload's Admin | | +| **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | +| **TenantId** | Write | String | Id of the Azure Active Directory tenant used for authentication. | | +| **CertificateThumbprint** | Write | String | Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication. | | +| **ManagedIdentity** | Write | Boolean | Managed ID being used for authentication. | | +| **AccessTokens** | Write | StringArray[] | Access token used for authentication. | | + + +## Description + +Manages the Self Purchase policies in commerce. + +## Permissions + +## Examples + +### Example 1 + +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. + +```powershell +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + CommerceSelfServicePurchase "Power Apps per user" + { + ApplicationId = $ApplicationId; + CertificateThumbprint = $CertificateThumbprint; + Ensure = "Present"; + PolicyValue = "Enabled"; + ProductId = "CFQ7TTC0LH2H"; + ProductName = "Power Apps per user"; + TenantId = $TenantId; + } + } +} +``` + diff --git a/docs/docs/resources/exchange/EXOMigrationEndpoint.md b/docs/docs/resources/exchange/EXOMigrationEndpoint.md index e8a3134503..f5f867aba2 100644 --- a/docs/docs/resources/exchange/EXOMigrationEndpoint.md +++ b/docs/docs/resources/exchange/EXOMigrationEndpoint.md @@ -9,7 +9,7 @@ | **AppID** | Write | String | The Application ID used for authentication. | | | **AppSecretKeyVaultUrl** | Write | String | The URL of the Key Vault that stores the application secret. | | | **Authentication** | Write | String | The authentication method for the migration endpoint. | | -| **EndpointType** | Write | String | The type of migration endpoint. | `IMAP` | +| **EndpointType** | Write | String | The type of migration endpoint. | `IMAP`, `ExchangeRemoteMove` | | **ExchangeServer** | Write | String | The Exchange Server address for the migration endpoint. | | | **MailboxPermission** | Write | String | The mailbox permission for the migration endpoint. | | | **MaxConcurrentIncrementalSyncs** | Write | String | The maximum number of concurrent incremental syncs. | | diff --git a/docs/docs/user-guide/cmdlets/Update-M365DSCDependencies.md b/docs/docs/user-guide/cmdlets/Update-M365DSCDependencies.md index 131a830e7c..478294c44e 100644 --- a/docs/docs/user-guide/cmdlets/Update-M365DSCDependencies.md +++ b/docs/docs/user-guide/cmdlets/Update-M365DSCDependencies.md @@ -15,6 +15,7 @@ This function does not generate any output. | Force | False | SwitchParameter | | | Specifies that all dependencies should be forcefully imported again. | | ValidateOnly | False | SwitchParameter | | | Specifies that the function should only return the dependencies that are not installed. | | Scope | False | Object | AllUsers | CurrentUser, AllUsers | Specifies the scope of the update of the module. The default value is AllUsers(needs to run as elevated user). | +| Proxy | False | String | | | | ## Examples diff --git a/docs/docs/user-guide/cmdlets/Update-M365DSCModule.md b/docs/docs/user-guide/cmdlets/Update-M365DSCModule.md index eeb0918741..ccedba9b41 100644 --- a/docs/docs/user-guide/cmdlets/Update-M365DSCModule.md +++ b/docs/docs/user-guide/cmdlets/Update-M365DSCModule.md @@ -13,6 +13,7 @@ This function does not generate any output. | Parameter | Required | DataType | Default Value | Allowed Values | Description | | --- | --- | --- | --- | --- | --- | | Scope | False | Object | AllUsers | CurrentUser, AllUsers | Specifies the scope of the update of the module. The default value is AllUsers(needs to run as elevated user). | +| Proxy | False | String | | | | ## Examples