diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aaee5b929..4c12965902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for Microsoft365DSC +# UNRELEASED + +* EXORetentionPolicyTag + * Initial release. + # 1.25.205.1 * AADApplication diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.psm1 new file mode 100644 index 0000000000..2fcd79ac87 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.psm1 @@ -0,0 +1,450 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.String] + $Comment, + + [Parameter()] + [System.String] + $AgeLimitForRetention, + + [Parameter()] + [System.String] + $MessageClass, + + [Parameter()] + [System.Boolean] + $MustDisplayCommentEnabled, + + [Parameter()] + [System.String] + $RetentionAction, + + [Parameter()] + [System.Boolean] + $RetentionEnabled, + + [Parameter()] + [System.String] + $Type, + + [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 'ExchangeOnline' ` + -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 | Where-Object -FilterScript {$_.Identity -eq $Identity} + } + else + { + $instance = Get-RetentionPolicyTag -Identity $Identity -ErrorAction SilentlyContinue + } + if ($null -eq $instance) + { + return $nullResult + } + + Write-Verbose -Message "Found existing instace of retention policy tag {$Identity}" + $results = @{ + Identity = $instance.Identity + Comment = $instance.Comment + AgeLimitForRetention = $instance.AgeLimitForRetention + MessageClass = $instance.MessageClass + MustDisplayCommentEnabled = $instance.MustDisplayCommentEnabled + RetentionAction = $instance.RetentionAction + RetentionEnabled = $instance.RetentionEnabled + Type = $instance.Type + 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] + $Identity, + + [Parameter()] + [System.String] + $Comment, + + [Parameter()] + [System.String] + $AgeLimitForRetention, + + [Parameter()] + [System.String] + $MessageClass, + + [Parameter()] + [System.Boolean] + $MustDisplayCommentEnabled, + + [Parameter()] + [System.String] + $RetentionAction, + + [Parameter()] + [System.Boolean] + $RetentionEnabled, + + [Parameter()] + [System.String] + $Type, + + [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 + + # CREATE + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating new retention policy tag {$Identity}" + $setParameters.Add('Name', $Identity) + $setParameters.Remove("Identity") | Out-Null + New-RetentionPolicyTag @SetParameters + } + # UPDATE + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating retention policy tag {$Identity}" + $setParameters.Remove('Type') | Out-Null + Set-RetentionPolicyTag @SetParameters + } + # REMOVE + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing retention policy tag {$Identity}" + Remove-RetentionPolicyTag -Identity $Identity + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.String] + $Comment, + + [Parameter()] + [System.String] + $AgeLimitForRetention, + + [Parameter()] + [System.String] + $MessageClass, + + [Parameter()] + [System.Boolean] + $MustDisplayCommentEnabled, + + [Parameter()] + [System.String] + $RetentionAction, + + [Parameter()] + [System.Boolean] + $RetentionEnabled, + + [Parameter()] + [System.String] + $Type, + + [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 'ExchangeOnline' ` + -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 + [array] $Script:exportedInstances = Get-RetentionPolicyTag -ErrorAction Stop + + $i = 1 + $dscContent = '' + if ($Script:exportedInstances.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $Script:exportedInstances) + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + + $displayedKey = $config.Identity + Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline + $params = @{ + Identity = $config.Identity + 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_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.schema.mof new file mode 100644 index 0000000000..ed567d4c19 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/MSFT_EXORetentionPolicyTag.schema.mof @@ -0,0 +1,19 @@ +[ClassVersion("1.0.0.0"), FriendlyName("EXORetentionPolicyTag")] +class MSFT_EXORetentionPolicyTag : OMI_BaseResource +{ + [Key, Description("The Identity parameter specifies the name of the tag.")] String Identity; + [Write, Description("The Description parameter specifies a comment for the tag.")] String Comment; + [Write, Description("The AgeLimitForRetention parameter specifies the age at which retention is enforced on an item. The age limit corresponds to the number of days from the date the item was delivered, or the date an item was created if it wasn't delivered. If this parameter isn't present and the RetentionEnabled parameter is set to $true, an error is returned.")] String AgeLimitForRetention; + [Write, Description("The MessageClass parameter specifies the message type to which the tag applies. If not specified, the default value is set to *.")] String MessageClass; + [Write, Description("The MustDisplayCommentEnabled parameter specifies whether the comment can be hidden. The default value is $true.")] Boolean MustDisplayCommentEnabled; + [Write, Description("The RetentionAction parameter specifies the action for the retention policy.")] String RetentionAction; + [Write, Description("The RetentionEnabled parameter specifies whether the tag is enabled. When set to $false, the tag is disabled, and no retention action is taken on messages that have the tag applied.")] Boolean RetentionEnabled; + [Write, Description("The Type parameter specifies the type of retention tag being created.")] String Type; + [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_EXORetentionPolicyTag/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/readme.md new file mode 100644 index 0000000000..ce44ed01c3 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/readme.md @@ -0,0 +1,6 @@ + +# EXORetentionPolicyTag + +## Description + +Manage Exchange Online retention policy tags. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/settings.json new file mode 100644 index 0000000000..6fb28514e5 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORetentionPolicyTag/settings.json @@ -0,0 +1,34 @@ +{ + "resourceName": "EXORetentionPolicyTag", + "description": "Manage Exchange Online retention policy tags.", + "roles": { + "read": [ + "Global Reader" + ], + "update": [ + "Exchange Administrator" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [], + "update": [] + } + }, + "exchange": { + "requiredroles": [ + "Organization Management", + "Recipient Management" + ], + "requiredrolegroups": [ + "Organization Management", + "Help Desk" + ] + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.psm1 index 2177e77ac1..3b257440ee 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.psm1 @@ -205,6 +205,10 @@ function Get-TargetResource [System.Boolean] $DisableSurveyScreenshots, + [Parameter()] + [System.Boolean] + $UseSupportBingSearchByAllUsers, + [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -301,24 +305,24 @@ function Get-TargetResource DisableSkillsMatchInvitationReachout = $PPTenantSettings.powerPlatform.champions.disableSkillsMatchInvitationReachout #intelligence - DisableCopilotFeedback = $PPTenantSettings.powerPlatforms.intelligence.disableCopilotFeedback - EnableOpenAiBotPublishing = $PPTenantSettings.powerPlatforms.intelligence.enableOpenAiBotPublishing - DisableCopilotFeedbackMetadata = $PPTenantSettings.powerPlatforms.intelligence.disableCopilotFeedbackMetadata - DisableAiPrompts = $PPTenantSettings.powerPlatforms.intelligence.disableAiPrompts + DisableCopilotFeedback = $PPTenantSettings.powerPlatform.intelligence.disableCopilotFeedback + EnableOpenAiBotPublishing = $PPTenantSettings.powerPlatform.intelligence.enableOpenAiBotPublishing + DisableCopilotFeedbackMetadata = $PPTenantSettings.powerPlatform.intelligence.disableCopilotFeedbackMetadata + DisableAiPrompts = $PPTenantSettings.powerPlatform.intelligence.disableAiPrompts #modelExperimentation - EnableModelDataSharing = $PPTenantSettings.powerPlatforms.modelExperimentation.enableModelDataSharing - DisableDataLogging = $PPTenantSettings.powerPlatforms.modelExperimentation.disableDataLogging + EnableModelDataSharing = $PPTenantSettings.powerPlatform.modelExperimentation.enableModelDataSharing + DisableDataLogging = $PPTenantSettings.powerPlatform.modelExperimentation.disableDataLogging #catalogSettings - PowerCatalogAudienceSetting = $PPTenantSettings.powerPlatforms.catalogSettings.powerCatalogAudienceSetting + PowerCatalogAudienceSetting = $PPTenantSettings.powerPlatform.catalogSettings.powerCatalogAudienceSetting #userManagementSettings - EnableDeleteDisabledUserinAllEnvironments = $PPTenantSettings.powerPlatforms.userManagementSettings.enableDeleteDisabledUserinAllEnvironments + EnableDeleteDisabledUserinAllEnvironments = $PPTenantSettings.powerPlatform.userManagementSettings.enableDeleteDisabledUserinAllEnvironments #helpSupportSettings - DisableHelpSupportCopilot = $PPTenantSettings.powerPlatforms.helpSupportSettings.disableHelpSupportCopilot - UseSupportBingSearchByAllUsers = $PPTenantSettings.powerPlatforms.helpSupportSettings.useSupportBingSearchByAllUsers + DisableHelpSupportCopilot = $PPTenantSettings.powerPlatform.helpSupportSettings.disableHelpSupportCopilot + UseSupportBingSearchByAllUsers = $PPTenantSettings.powerPlatform.helpSupportSettings.useSupportBingSearchByAllUsers #Main WalkMeOptOut = $PPTenantSettings.walkMeOptOut @@ -557,6 +561,10 @@ function Set-TargetResource [System.Boolean] $DisableSurveyScreenshots, + [Parameter()] + [System.Boolean] + $UseSupportBingSearchByAllUsers, + [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -597,7 +605,9 @@ function Set-TargetResource $SetParameters = $PSBoundParameters $RequestBody = Get-M365DSCPowerPlatformTenantSettings -Parameters $SetParameters - Set-TenantSettings -RequestBody $RequestBody | Out-Null + Write-Verbose -Message (ConvertTo-Json $RequestBody -Depth 10) + + Set-TenantSettings -RequestBody $RequestBody -Verbose | Out-Null } function Test-TargetResource @@ -807,6 +817,10 @@ function Test-TargetResource [System.Boolean] $DisableSurveyScreenshots, + [Parameter()] + [System.Boolean] + $UseSupportBingSearchByAllUsers, + [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -972,23 +986,40 @@ function Get-M365DSCPowerPlatformTenantSettings ) $result = @{ + disableCapacityAllocationByEnvironmentAdmins = $Parameters.DisableCapacityAllocationByEnvironmentAdmins + disableSupportTicketsVisibleByAllUsers = $Parameters.DisableSupportTicketsVisibleByAllUsers walkMeOptOut = $Parameters.WalkMeOptOut - disableNPSCommentsReachout = $Parameters.DisableNPSCommentsReachout - disableNewsletterSendout = $Parameters.DisableNewsletterSendout + disableSurveyScreenshots = $Parameters.DisableSurveyScreenshots disableEnvironmentCreationByNonAdminUsers = $Parameters.DisableEnvironmentCreationByNonAdminUsers disablePortalsCreationByNonAdminUsers = $Parameters.DisablePortalsCreationByNonAdminUsers + disableNewsletterSendout = $Parameters.DisableNewsletterSendout + disableNPSCommentsReachout = $Parameters.DisableNPSCommentsReachout disableSurveyFeedback = $Parameters.DisableSurveyFeedback - disableSurveyScreenshots = $Parameters.DisableSurveyScreenshots disableTrialEnvironmentCreationByNonAdminUsers = $Parameters.DisableTrialEnvironmentCreationByNonAdminUsers - disableCapacityAllocationByEnvironmentAdmins = $Parameters.DisableCapacityAllocationByEnvironmentAdmins - disableSupportTicketsVisibleByAllUsers = $Parameters.DisableSupportTicketsVisibleByAllUsers powerPlatform = @{ - search = @{ - disableDocsSearch = $Parameters.DisableDocsSearch - disableCommunitySearch = $Parameters.DisableCommunitySearch - disableBingVideoSearch = $Parameters.DisableBingVideoSearch + powerAutomate = @{ + disableCopilotWithBing = $Parameters.DisableCopilotWithBing + } + catalogSettings = @{ + powerCatalogAudienceSetting = $Parameters.PowerCatalogAudienceSetting + } + governance = @{ + disableAdminDigest = $Parameters.DisableAdminDigest + disableDeveloperEnvironmentCreationByNonAdminUsers = $Parameters.DisableDeveloperEnvironmentCreationByNonAdminUsers + enableDefaultEnvironmentRouting = $Parameters.EnableDefaultEnvironmentRouting + policy = @{ + enableDesktopFlowDataPolicyManagement = [Boolean]::Parse($Parameters.EnableDesktopFlowDataPolicyManagement) + } + environmentRoutingAllMakers = $Parameters.EnvironmentRoutingAllMakers + } + environments = @{ + disablePreferredDataLocationForTeamsEnvironment = $Parameters.DisablePreferredDataLocationForTeamsEnvironment + } + helpSupportSettings = @{ + disableHelpSupportCopilot = $Parameters.DisableHelpSupportCopilot + useSupportBingSearchByAllUsers = $Parameters.UseSupportBingSearchByAllUsers } - teams = @{ + teamsIntegration = @{ shareWithColleaguesUserLimit = $Parameters.ShareWithColleaguesUserLimit } powerApps = @{ @@ -1003,25 +1034,27 @@ function Get-M365DSCPowerPlatformTenantSettings allowNewOrgChannelDefault = $Parameters.AllowNewOrgChannelDefault disableCopilot = $Parameters.DisableCopilot } - environments = @{ - disablePreferredDataLocationForTeamsEnvironment = $Parameters.DisablePreferredDataLocationForTeamsEnvironment + search = @{ + disableDocsSearch = $Parameters.DisableDocsSearch + disableCommunitySearch = $Parameters.DisableCommunitySearch + disableBingVideoSearch = $Parameters.DisableBingVideoSearch } - powerAutomate = @{ - disableCopilotWithBing = $Parameters.DisableCopilotWithBing + userManagementSettings = @{ + enableDeleteDisabledUserinAllEnvironments = $Parameters.EnableDeleteDisabledUserinAllEnvironments } - governance = @{ - disableAdminDigest = $Parameters.DisableAdminDigest - disableDeveloperEnvironmentCreationByNonAdminUsers = $Parameters.DisableDeveloperEnvironmentCreationByNonAdminUsers - enableDefaultEnvironmentRouting = $Parameters.EnableDefaultEnvironmentRouting - policy = @( - @{ - enableDesktopFlowDataPolicyManagement = $Parameters.EnableDesktopFlowDataPolicyManagement - } - ) - environmentRoutingAllMakers = $Parameters.EnvironmentRoutingAllMakers + powerPages = @{ + enableGenerativeAIFeaturesForSiteUsers = $Parameters.EnableGenerativeAIFeaturesForSiteUsers + enableExternalAuthenticationProvidersInPowerPages = $Parameters.EnableExternalAuthenticationProvidersInPowerPages } - teamsIntegration = @{ - shareWithColleaguesUserLimit = $Parameters.ShareWithColleaguesUserLimit + modelExperimentation = @{ + enableModelDataSharing = $Parameters.EnableModelDataSharing + disableDataLogging = $Parameters.DisableDataLogging + } + intelligence = @{ + disableCopilotFeedback = $Parameters.DisableCopilotFeedback + enableOpenAiBotPublishing = $Parameters.EnableOpenAiBotPublishing + disableCopilotFeedbackMetadata = $Parameters.DisableCopilotFeedbackMetadata + disableAiPrompts = $Parameters.DisableAiPrompts } licensing = @{ disableBillingPolicyCreationByNonAdminUsers = $Parameters.DisableBillingPolicyCreationByNonAdminUsers @@ -1030,34 +1063,11 @@ function Get-M365DSCPowerPlatformTenantSettings enableTenantLicensingReportForEnvironmentAdmins = $Parameters.EnableTenantLicensingReportForEnvironmentAdmins disableUseOfUnassignedAIBuilderCredits = $Parameters.DisableUseOfUnassignedAIBuilderCredits } - powerPages = @{ - enableGenerativeAIFeaturesForSiteUsers = $Parameters.EnableGenerativeAIFeaturesForSiteUsers - enableExternalAuthenticationProvidersInPowerPages = $Parameters.EnableExternalAuthenticationProvidersInPowerPages - } champions = @{ disableChampionsInvitationReachout = $Parameters.DisableChampionsInvitationReachout disableSkillsMatchInvitationReachout = $Parameters.DisableSkillsMatchInvitationReachout } - intelligence = @{ - disableCopilotFeedback = $Parameters.disableCopilotFeedback - enableOpenAiBotPublishing = $Parameters.enableOpenAiBotPublishing - disableCopilotFeedbackMetadata = $Parameters.disableCopilotFeedbackMetadata - disableAiPrompts = $Parameters.disableAiPrompts - } - modelExperimentation = @{ - enableModelDataSharing = $Parameters.enableModelDataSharing - disableDataLogging = $Parameters.disableDataLogging - } - catalogSettings = @{ - powerCatalogAudienceSetting = $Parameters.powerCatalogAudienceSetting - } - userManagementSettings = @{ - enableDeleteDisabledUserinAllEnvironments = $Parameters.enableDeleteDisabledUserinAllEnvironments - } - helpSupportSettings = @{ - disableHelpSupportCopilot = $Parameters.disableHelpSupportCopilot - useSupportBingSearchByAllUsers = $Parameters.useSupportBingSearchByAllUsers - } + gccCommercialSettings = @{} } } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.schema.mof index 52ddef519d..f61aef5147 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_PPTenantSettings/MSFT_PPTenantSettings.schema.mof @@ -39,6 +39,7 @@ class MSFT_PPTenantSettings : OMI_BaseResource [Write, Description("TBD")] Boolean DisableHelpSupportCopilot; [Write, Description("TBD")] Boolean DisableSurveyScreenshots; [Write, Description("When set to true this will disable the Walk Me guidance.")] boolean WalkMeOptOut; + [Write, Description("TBD")] boolean useSupportBingSearchByAllUsers; [Write, Description("When set to true this will disable the NPS Comments Reachout.")] boolean DisableNPSCommentsReachout; [Write, Description("When set to true this will disable the monthly newsletters.")] boolean DisableNewsletterSendout; [Write, Description("When set to true this will disable production environment creation by non-admin users.")] boolean DisableEnvironmentCreationByNonAdminUsers; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/1-Create.ps1 new file mode 100644 index 0000000000..59dc8825b6 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/1-Create.ps1 @@ -0,0 +1,39 @@ +<# +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 + { + EXORetentionPolicyTag "RetentionPolicyTag" + { + ApplicationId = $ApplicationId; + CertificateThumbprint = $CertificateThumbprint; + Comment = "This is my tag"; + Ensure = "Present"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + TenantId = $TenantId; + Type = "Personal"; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/2-Update.ps1 new file mode 100644 index 0000000000..750f3fa7dd --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/2-Update.ps1 @@ -0,0 +1,39 @@ +<# +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 + { + EXORetentionPolicyTag "RetentionPolicyTag" + { + ApplicationId = $ApplicationId; + CertificateThumbprint = $CertificateThumbprint; + Comment = "This is my modified tag"; #Drift + Ensure = "Present"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + TenantId = $TenantId; + Type = "Personal"; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/3-Remove.ps1 new file mode 100644 index 0000000000..6c28bda3c4 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORetentionPolicyTag/3-Remove.ps1 @@ -0,0 +1,39 @@ +<# +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 + { + EXORetentionPolicyTag "RetentionPolicyTag" + { + ApplicationId = $ApplicationId; + CertificateThumbprint = $CertificateThumbprint; + Comment = "This is my tag"; + Ensure = "Absent"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + TenantId = $TenantId; + Type = "Personal"; + } + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORetentionPolicyTag.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORetentionPolicyTag.Tests.ps1 new file mode 100644 index 0000000000..b58cf9a432 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORetentionPolicyTag.Tests.ps1 @@ -0,0 +1,229 @@ +[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 -CommandName New-RetentionPolicyTag -MockWith { + } + + Mock -CommandName Remove-RetentionPolicyTag -MockWith { + } + + Mock -CommandName Set-RetentionPolicyTag -MockWith { + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstance =$null + $Script:ExportMode = $false + } + # Test contexts + Context -Name "The instance should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + Comment = "This is my test"; + Ensure = "Present"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + Credential = $Credential; + } + + Mock -CommandName Get-RetentionPolicyTag -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 + } + + It 'Should create a new instance from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName New-RetentionPolicyTag -Exactly 1 + } + } + + Context -Name "The instance exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + Comment = "This is my test"; + Ensure = "Absent"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + Credential = $Credential; + } + + Mock -CommandName Get-RetentionPolicyTag -MockWith { + return @{ + Identity = "MyTag" + Name = "MyTag" + Comment = "This is my test"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + } + } + } + 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 remove the instance from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Remove-RetentionPolicyTag -Exactly 1 + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + Comment = "This is my test"; + Ensure = "Present"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + Credential = $Credential; + } + + Mock -CommandName Get-RetentionPolicyTag -MockWith { + return @{ + Identity = "MyTag" + Name = "MyTag" + Comment = "This is my test"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + } + } + } + + 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 = @{ + Comment = "This is my test"; + Ensure = "Present"; + Identity = "MyTag"; + MessageClass = "*"; + MustDisplayCommentEnabled = $False; + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + Credential = $Credential; + } + + Mock -CommandName Get-RetentionPolicyTag -MockWith { + return @{ + Identity = "MyTag" + Name = "MyTag" + Comment = "This is my test"; + MessageClass = "*"; + MustDisplayCommentEnabled = $true; #Drift + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + } + } + } + + 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 Set-RetentionPolicyTag -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Get-RetentionPolicyTag -MockWith { + return @{ + Identity = "MyTag" + Name = "MyTag" + Comment = "This is my test"; + MessageClass = "*"; + MustDisplayCommentEnabled = $true; #Drift + RetentionAction = "MoveToArchive"; + RetentionEnabled = $False; + Type = "Personal"; + } + } + } + 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/Tests/Unit/Microsoft365DSC/Microsoft365DSC.PPTenantSettings.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.PPTenantSettings.Tests.ps1 index 9454ac6b15..eb17590094 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.PPTenantSettings.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.PPTenantSettings.Tests.ps1 @@ -55,6 +55,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisableBingVideoSearch = $false DisableShareWithEveryone = $false EnableGuestsToMake = $false + EnableDesktopFlowDataPolicyManagement = $false ShareWithColleaguesUserLimit = 10000 Credential = $Credential } @@ -106,6 +107,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisableTrialEnvironmentCreationByNonAdminUsers = $testParams.DisableTrialEnvironmentCreationByNonAdminUsers DisableCapacityAllocationByEnvironmentAdmins = $testParams.DisableCapacityAllocationByEnvironmentAdmins DisableSupportTicketsVisibleByAllUsers = $testParams.DisableSupportTicketsVisibleByAllUsers + EnableDesktopFlowDataPolicyManagement = $false powerPlatform = @( @{ search = @{ diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index 4e9e9efb2c..fb456ea356 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -105998,3 +105998,180 @@ function Update-MgAdminSharepointSetting } #endregion + +function Get-RetentionPolicyTag +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $OptionalInMailbox, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeSystemTags, + + [Parameter()] + [System.Object] + $Mailbox, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object[]] + $Types + ) +} +function New-RetentionPolicyTag +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $AgeLimitForRetention, + + [Parameter()] + [System.String] + $MessageClass, + + [Parameter()] + [System.Boolean] + $MustDisplayCommentEnabled, + + [Parameter()] + [System.String] + $Name, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IsDefaultAutoGroupPolicyTag, + + [Parameter()] + [System.Object] + $LocalizedRetentionPolicyTagName, + + [Parameter()] + [System.Object] + $LocalizedComment, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IsDefaultModeratedRecipientsPolicyTag, + + [Parameter()] + [System.Object] + $RetentionAction, + + [Parameter()] + [System.String] + $Comment, + + [Parameter()] + [System.Guid] + $RetentionId, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Boolean] + $RetentionEnabled, + + [Parameter()] + [System.Object] + $Type, + + [Parameter()] + [System.Boolean] + $SystemTag + ) +} +function Remove-RetentionPolicyTag +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Object] + $Identity + ) +} +function Set-RetentionPolicyTag +{ + [CmdletBinding()] + param( + [Parameter()] + [System.String] + $MessageClass, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Boolean] + $MustDisplayCommentEnabled, + + [Parameter()] + [System.Object[]] + $OptionalInMailbox, + + [Parameter()] + [System.Object] + $Mailbox, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Force, + + [Parameter()] + [System.Object] + $LocalizedRetentionPolicyTagName, + + [Parameter()] + [System.Object] + $LegacyManagedFolder, + + [Parameter()] + [System.Object] + $AgeLimitForRetention, + + [Parameter()] + [System.Object] + $RetentionAction, + + [Parameter()] + [System.Object] + $LocalizedComment, + + [Parameter()] + [System.String] + $Comment, + + [Parameter()] + [System.Guid] + $RetentionId, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Boolean] + $RetentionEnabled, + + [Parameter()] + [System.Boolean] + $SystemTag, + + [Parameter()] + [System.String] + $Name + ) +}