diff --git a/.github/workflows/Global - Integration - AAD.yml b/.github/workflows/Global - Integration - AAD.yml index 7f681f74d9..df54194a4b 100644 --- a/.github/workflows/Global - Integration - AAD.yml +++ b/.github/workflows/Global - Integration - AAD.yml @@ -6,6 +6,8 @@ jobs: # The type of runner that the job will run on runs-on: windows-latest + permissions: write-all + # Only when run from the main repo if: github.repository == 'microsoft/Microsoft365DSC' diff --git a/.github/workflows/Global - Integration - EXO.yml b/.github/workflows/Global - Integration - EXO.yml index 4957ccddcd..76b0ce03bc 100644 --- a/.github/workflows/Global - Integration - EXO.yml +++ b/.github/workflows/Global - Integration - EXO.yml @@ -6,6 +6,8 @@ jobs: # The type of runner that the job will run on runs-on: windows-latest + permissions: write-all + # Only when run from the main repo if: github.repository == 'microsoft/Microsoft365DSC' diff --git a/.github/workflows/Global - Integration - INTUNE.yml b/.github/workflows/Global - Integration - INTUNE.yml index 89b45a7056..1582b1b061 100644 --- a/.github/workflows/Global - Integration - INTUNE.yml +++ b/.github/workflows/Global - Integration - INTUNE.yml @@ -6,6 +6,8 @@ jobs: # The type of runner that the job will run on runs-on: windows-latest + permissions: write-all + # Only when run from the main repo if: github.repository == 'microsoft/Microsoft365DSC' diff --git a/.github/workflows/PublishGitHubPages.yml b/.github/workflows/PublishGitHubPages.yml index f0cee1a374..bf85a3d7be 100644 --- a/.github/workflows/PublishGitHubPages.yml +++ b/.github/workflows/PublishGitHubPages.yml @@ -8,6 +8,8 @@ jobs: GenerateResource: runs-on: windows-latest + permissions: write-all + # Only when run from the main repo if: github.repository == 'microsoft/Microsoft365DSC' diff --git a/.github/workflows/Unit Tests.yml b/.github/workflows/Unit Tests.yml index 103e67b01c..a636b3093d 100644 --- a/.github/workflows/Unit Tests.yml +++ b/.github/workflows/Unit Tests.yml @@ -7,6 +7,8 @@ jobs: # The type of runner that the job will run on runs-on: windows-latest + permissions: write-all + # Only when run from the main repo if: github.repository == 'microsoft/Microsoft365DSC' diff --git a/CHANGELOG.md b/CHANGELOG.md index af75d9bbd4..b04ca09a5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,65 @@ # Change log for Microsoft365DSC +# UNRELEASED + +* AADRoleEligibilityScheduleRequest + * Fixed an issue where an error was thrown if no requests were found instead + of simply returning the Null object. +* EXOMobileDeviceMailboxPolicy + * Fixes an issue where an empty MinPasswordLength value was always passed down + to the update logic flow. +* IntuneAppConfigurationPolicy + * Added parameter Id to avoid having to retrieve the same policy multiple + times + * Fixed tests in Test-TargetResource to ensure the resource reports its + correct state + FIXES [#3542](https://github.com/microsoft/Microsoft365DSC/issues/3542) +* IntuneDeviceAndAppManagementAssignmentFilter + * Fixed Test-TargetResource to ensure that resource reports its correct state + FIXES [#3959](https://github.com/microsoft/Microsoft365DSC/issues/3959) +* IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10 + * Fixed Test-TargetResource by removing Id from being tested and also used + correct filter while retrieving the policy otherwise it could not be found + FIXES [#3964](https://github.com/microsoft/Microsoft365DSC/issues/3964) +* IntuneDeviceConfigurationPolicyAndroidWorkProfile + * Fix typo in variable which made it export incorrectly and report that + resource was not in correct state due to testing an incorrect value + FIXES [#3972](https://github.com/microsoft/Microsoft365DSC/issues/3972) +* DEPENDENCIES + * Updated DSCParser to version 1.4.0.2. + * Updated Microsoft.Graph dependencies to version 2.13.1. + * Updated MSCloudLoginAssistant to version 1.1.13. +* MISC + * M365DSCReport + * Fix nested change detection for CIMInstances + * Fix IntuneDeviceEnrolllmentPlatformRestriction comparison in report + FIXES [#4291](https://github.com/microsoft/Microsoft365DSC/issues/4291) + +# 1.24.207.2 + +* TeamsAppSetupPolicy + * Changed the logic to retrieve arrays of Ids in the Get method. +* MISC + * Drift Logging + * Now includes the full list of parameters for the current values. + * Telemetry + * Added a new M365DSCTelemetryEventId parameter to track duplication of events. + +# 1.24.207.1 + +* IntuneDeviceEnrollmentPlatformRestriction + * Added Priority parameter + FIXES [#4081](https://github.com/microsoft/Microsoft365DSC/issues/4081) +* SCDLPComplianceRule + * Properly escapes fancy quotes in the Get method. +* TeamsMeetingPolicy + * Ignore the AllowUserToJoinExternalMeeting parameterfor drift evaluation + since it doesn't do anything based on official documentation. +* DEPENDENCIES + * Updated Microsoft.PowerApps.Administration.PowerShell to version 2.0.180. + * Updated MSCloudLoginAssistant to version 1.1.11 + * Updated ReverseDSC to version 2.0.0.19 + # 1.24.131.2 * TeamsMeetingPolicy @@ -27,9 +87,27 @@ wasn't properly returned. * EXOSafeLinksPolicy * Deprecated the UseTranslatedNotificationText property +* IntuneDeviceConfigurationPolicyAndroidOpenSourceProject, + IntuneExploitProtectionPolicyWindows10SettingCatalog, IntuneRoleAssignment, + IntuneRoleDefinition, IntuneSettingCatalogASRRulesPolicyWindows10, + IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator, + IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner, + IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile, + IntuneWifiConfigurationPolicyAndroidForWork, + IntuneWifiConfigurationPolicyAndroidOpenSourceProject, + IntuneWifiConfigurationPolicyIOS, IntuneWifiConfigurationPolicyMacOS, + IntuneWifiConfigurationPolicyWindows10, TeamsCallParkPolicy + * Fix condition in Test-TargetResource when resource is absent + FIXES [#3897](https://github.com/microsoft/Microsoft365DSC/issues/3897) + FIXES [#4256](https://github.com/microsoft/Microsoft365DSC/issues/4256) +* TeamsFilesPolicy + * Add default value ('Present') to parameter Ensure * TeamsEmergencyCallRoutingPolicy * Fix deletion of resource FIXES [#4261](https://github.com/microsoft/Microsoft365DSC/issues/4261) +* TeamsUserCallingSettings + * Added support for Certificate Authentication + FIXES [#3180](https://github.com/microsoft/Microsoft365DSC/issues/3180) * TEAMS * Added support for ManagedIdentity Authentication across Teams resources. * DEPENDENCIES @@ -58,7 +136,7 @@ * Remove the logic path to create a new instance in favor of the update flow. * AADConditionalAccessPolicy * Fix issue when not all parameters are specified - FIXES [[#4202](https://github.com/microsoft/Microsoft365DSC/issues/4202)] + FIXES [#4202](https://github.com/microsoft/Microsoft365DSC/issues/4202) * AADCrossTenantAccessPolicy * Removed the ability to specify a value of Absent for the Ensure property. * AADCrossTenantAccessPolicyCOnfigurationDefault @@ -77,7 +155,7 @@ * DEPRECATED Resource. * SCAutoSensitivityLabelRule * Correct export indentation, which caused an issue with report conversion to JSON. - FIXES [[#4240](https://github.com/microsoft/Microsoft365DSC/issues/4240)] + FIXES [#4240](https://github.com/microsoft/Microsoft365DSC/issues/4240) * SPOSharingSettings * Fixed an Issue where the MySiteSharingCapability could be returned as an empty string instead of a null value from the Get method. @@ -94,6 +172,9 @@ * TeamsCallParkPolicy * Fix condition in Test-TargetResource when resource is absent FIXES [#4210](https://github.com/microsoft/Microsoft365DSC/issues/4210) +* TeamsCallQueue + * Optimize performances by doing 1 request instead of n+1 + FIXES [[#4192](https://github.com/microsoft/Microsoft365DSC/issues/4192)] * TeamsComplianceRecordingPolicy * Fix condition in Test-TargetResource when resource is absent FIXES [#4212](https://github.com/microsoft/Microsoft365DSC/issues/4212) @@ -303,6 +384,10 @@ * IntuneAntivirusPolicyWindows10SettingCatalog * Fix condition in Test-TargetResource to check if resource was removed or not FIXES [#3958](https://github.com/microsoft/Microsoft365DSC/issues/3958) +* IntuneSettingCatalogASRRulesPolicyWindows10 + * Fixed Schema Validation + * Fixed Import with unknown ID of Policy and Assignments by using DisplayName + FIXES [#3961](https://github.com/microsoft/Microsoft365DSC/issues/3961) * IntuneWindowsUpdateForBusinessRingUpdateProfileWindows10 * Fix typo in assignment cmdlet FIXES [#3996](https://github.com/microsoft/Microsoft365DSC/issues/3996) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 index a0b411cc71..c000517482 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroup/MSFT_AADGroup.psm1 @@ -1075,10 +1075,36 @@ function Export-TargetResource All = [switch]$true ErrorAction = 'Stop' } - if ($Filter -like "*endsWith*") { + + # Define the list of attributes + $attributesToCheck = @( + "description", + "displayName", + "hasMembersWithLicenseErrors", + "mail", + "mailNickname", + "onPremisesSecurityIdentifier", + "onPremisesSyncEnabled", + "preferredLanguage" + ) + + # Initialize a flag to indicate whether any attribute matches the condition + $matchConditionFound = $false + + # Check each attribute in the list + foreach ($attribute in $attributesToCheck) { + if ($Filter -like "*$attribute eq null*") { + $matchConditionFound = $true + break + } + } + + # If any attribute matches, add parameters to $ExportParameters + if ($matchConditionFound -or $Filter -like "*endsWith*") { $ExportParameters.Add('CountVariable', 'count') $ExportParameters.Add('ConsistencyLevel', 'eventual') } + [array] $Script:exportedGroups = Get-MgGroup @ExportParameters $Script:exportedGroups = $Script:exportedGroups | Where-Object -FilterScript { -not ($_.MailEnabled -and ($null -eq $_.GroupTypes -or $_.GroupTypes.Length -eq 0)) -and ` diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADRoleEligibilityScheduleRequest/MSFT_AADRoleEligibilityScheduleRequest.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADRoleEligibilityScheduleRequest/MSFT_AADRoleEligibilityScheduleRequest.psm1 index f7becb8603..c5266516d2 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADRoleEligibilityScheduleRequest/MSFT_AADRoleEligibilityScheduleRequest.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADRoleEligibilityScheduleRequest/MSFT_AADRoleEligibilityScheduleRequest.psm1 @@ -182,16 +182,20 @@ $schedule = Get-MgBetaRoleManagementDirectoryRoleEligibilitySchedule -Filter "PrincipalId eq '$PrincipalId' and RoleDefinitionId eq '$RoleDefinitionId'" [Array]$request = Get-MgBetaRoleManagementDirectoryRoleEligibilityScheduleRequest -Filter "PrincipalId eq '$PrincipalId' and RoleDefinitionId eq '$RoleDefinitionId'" | Sort-Object -Property CompletedDateTime -Descending -` $request = $request[0] +` + if ($request.Length -gt 1) + { + $request = $request[0] + } } } else { $ObjectGuid = [System.Guid]::empty if ($PrincipalType -eq 'User') - { + { Write-Verbose -Message "Retrieving principal {$Principal} of type {$PrincipalType}" - + if ([System.Guid]::TryParse($Principal,[System.Management.Automation.PSReference]$ObjectGuid)) { $PrincipalIdValue = Get-MgUser -UserId $Principal -ErrorAction SilentlyContinue diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXODataClassification/MSFT_EXODataClassification.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXODataClassification/MSFT_EXODataClassification.psm1 index 6b03e06a7d..2754f2074f 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXODataClassification/MSFT_EXODataClassification.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXODataClassification/MSFT_EXODataClassification.psm1 @@ -426,7 +426,7 @@ function Export-TargetResource { $Script:ExportMode = $true #region resource generator code - [array] $Script:exportedInstances = Get-DataClassification -ErrorAction Stop + [array] $Script:exportedInstances = Get-DataClassification -ErrorAction SilentlyContinue $dscContent = [System.Text.StringBuilder]::new() if ($Script:exportedInstances.Length -eq 0) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMobileDeviceMailboxPolicy/MSFT_EXOMobileDeviceMailboxPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMobileDeviceMailboxPolicy/MSFT_EXOMobileDeviceMailboxPolicy.psm1 index 870613162f..1b4cb79f54 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMobileDeviceMailboxPolicy/MSFT_EXOMobileDeviceMailboxPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMobileDeviceMailboxPolicy/MSFT_EXOMobileDeviceMailboxPolicy.psm1 @@ -739,6 +739,7 @@ function Set-TargetResource if ([System.String]::IsNullOrEmpty($MinPasswordLength)) { $NewMobileDeviceMailboxPolicyParams.Remove('MinPasswordLength') | Out-Null + $SetMobileDeviceMailboxPolicyParams.Remove('MinPasswordLength') | Out-Null } # CASE: Mobile Device Mailbox Policy doesn't exist but should; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/MSFT_EXORecipientPermission.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/MSFT_EXORecipientPermission.psm1 new file mode 100644 index 0000000000..06759e50af --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/MSFT_EXORecipientPermission.psm1 @@ -0,0 +1,474 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $Trustee, + + [Parameter()] + [ValidateSet('SendAs')] + [System.String[]] + $AccessRights = 'SendAs', + + [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()] + [System.String] + $CertificatePath, + + [Parameter()] + [System.Management.Automation.PSCredential] + $CertificatePassword, + + [Parameter()] + [Switch] + $ManagedIdentity + ) + + Write-Verbose -Message "Getting configuration of Office 365 Recipient permission $Identity" + if ($Script:ExportMode) + { + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters ` + -SkipModuleReload $true + } + else + { + $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 + + $nullReturn = $PSBoundParameters + $nullReturn.Ensure = 'Absent' + + try + { + + if ($null -ne $Script:recipientPermissions -and $Script:ExportMode) + { + $recipientPermission = $Script:recipientPermissions | Where-Object -FilterScript { + $_.Identity -eq $Identity -and $_.Trustee -eq $Trustee -and $_.AccessRights -eq $AccessRights + } + } + else + { + $recipientPermission = Get-RecipientPermission -Identity $Identity -Trustee $Trustee -AccessRights $AccessRights -ErrorAction Stop + } + + if ($null -eq $recipientPermission) + { + Write-Verbose -Message "The specified Recipient Permission doesn't exist." + return $nullReturn + } + + #endregion + + $result = @{ + Identity = $Identity + Trustee = $recipientPermission.Trustee + AccessRights = $recipientPermission.AccessRights + + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + CertificateThumbprint = $CertificateThumbprint + CertificatePath = $CertificatePath + CertificatePassword = $CertificatePassword + Managedidentity = $ManagedIdentity.IsPresent + TenantId = $TenantId + } + + Write-Verbose -Message "Found an existing instance of Recipient permissions '$($DisplayName)'" + return $result + } + catch + { + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullReturn + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $Trustee, + + [Parameter()] + [ValidateSet('SendAs')] + [System.String[]] + $AccessRights = 'SendAs', + + [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()] + [System.String] + $CertificatePath, + + [Parameter()] + [System.Management.Automation.PSCredential] + $CertificatePassword, + + [Parameter()] + [Switch] + $ManagedIdentity + ) + + Write-Verbose -Message "Setting Mail Contact configuration for $Name" + + $currentState = Get-TargetResource @PSBoundParameters + + if ($Global:CurrentModeIsExport) + { + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters ` + -SkipModuleReload $true + } + else + { + $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 + + $parameters = $PSBoundParameters + $parameters.Remove('Credential') | Out-Null + $parameters.Remove('ApplicationId') | Out-Null + $parameters.Remove('TenantId') | Out-Null + $parameters.Remove('CertificateThumbprint') | Out-Null + $parameters.Remove('CertificatePath') | Out-Null + $parameters.Remove('CertificatePassword') | Out-Null + $parameters.Remove('ManagedIdentity') | Out-Null + $parameters.Remove('Ensure') | Out-Null + $parameters.AccessRights = $AccessRights #Parameters with default values are not part PSBoundParameters + + # Receipient Permission doesn't exist but it should + if ($Ensure -eq 'Present' -and $currentState.Ensure -eq 'Absent') + { + Write-Verbose -Message "The Receipient Permission for '$Trustee' with Access Rights '$($AccessRights -join ', ')' on mailbox '$Identity' does not exist but it should. Adding it." + Add-RecipientPermission @parameters -Confirm:$false + } + # Receipient Permission exists but shouldn't + elseif ($Ensure -eq 'Absent' -and $currentState.Ensure -eq 'Present') + { + Write-Verbose -Message "Receipient Permission for '$Trustee' with Access Rights '$($AccessRights -join ', ')' on mailbox '$Identity' exists but shouldn't. Removing it." + Remove-RecipientPermission @parameters -Confirm:$false + } + elseif ($Ensure -eq 'Present' -and $currentState.Ensure -eq 'Present') + { + Write-Verbose -Message "Receipient Permission for '$Trustee' with Access Rights '$($AccessRights -join ', ')' on mailbox '$Identity' exists." + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $Trustee, + + [Parameter()] + [ValidateSet('SendAs')] + [System.String[]] + $AccessRights = 'SendAs', + + [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()] + [System.String] + $CertificatePath, + + [Parameter()] + [System.Management.Automation.PSCredential] + $CertificatePassword, + + [Parameter()] + [Switch] + $ManagedIdentity + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + $param = $PSBoundParameters + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName -replace 'MSFT_', '' + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $param + Add-M365DSCTelemetryEvent -Data $data + #endregion + + Write-Verbose -Message "Testing configuration of Office 365 Recipient permissions $DisplayName" + + $currentValues = Get-TargetResource @param + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $currentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $param)" + + $testResult = Test-M365DSCParameterState -CurrentValues $currentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $param ` + -ValuesToCheck Ensure, Identity, Trustee, AccessRights + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $Identity, + + [Parameter()] + [System.String] + $Trustee, + + [Parameter()] + [ValidateSet('SendAs')] + [System.String[]] + $AccessRights = 'SendAs', + + [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()] + [System.String] + $CertificatePath, + + [Parameter()] + [System.Management.Automation.PSCredential] + $CertificatePassword, + + [Parameter()] + [Switch] + $ManagedIdentity + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters ` + -SkipModuleReload $true + + #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:recipientPermissions = Get-RecipientPermission -ResultSize Unlimited + + $dscContent = '' + $i = 1 + if ($recipientPermissions.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($recipientPermission in $recipientPermissions) + { + Write-Host " |---[$i/$($recipientPermissions.Length)] $($recipientPermission.Identity)" -NoNewline + + $params = @{ + Identity = $recipientPermission.Identity + Trustee = $recipientPermission.Trustee + AccessRights = $recipientPermission.AccessRights + + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + CertificatePassword = $CertificatePassword + Managedidentity = $ManagedIdentity.IsPresent + CertificatePath = $CertificatePath + } + + $Results = Get-TargetResource @Params + + if ($Results -is [System.Collections.Hashtable] -and $Results.Count -gt 1) + { + $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 + + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host $Global:M365DSCEmojiRedX + } + + $i++ + + } + 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_EXORecipientPermission/MSFT_EXORecipientPermission.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/MSFT_EXORecipientPermission.schema.mof new file mode 100644 index 0000000000..6efdab4c07 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/MSFT_EXORecipientPermission.schema.mof @@ -0,0 +1,16 @@ +[ClassVersion("1.0.0.0"), FriendlyName("EXORecipientPermission")] +class MSFT_EXORecipientPermission : OMI_BaseResource +{ + [Key, Description("The mailbox the permission should be given on.")] String Identity; + [Key, Description("The account to give the permission to.")] String Trustee; + [Write, Description("The access rights granted to the account. Only 'SendAs' is supported.")] String AccessRights[]; + + [Write, Description("Present ensures the group exists, absent ensures it is removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Write, Description("Credentials of the Exchange Global 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("Username can be made up to anything but password will be used for CertificatePassword"), EmbeddedInstance("MSFT_Credential")] String CertificatePassword; + [Write, Description("Path to certificate used in service principal usually a PFX file.")] String CertificatePath; + [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/readme.md new file mode 100644 index 0000000000..611e51a3f4 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/readme.md @@ -0,0 +1,5 @@ +# EXORecipientPermission + +## Description + +This resource allows users to retrieve Office 365 Recipient Permissions. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/settings.json new file mode 100644 index 0000000000..4506c76525 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXORecipientPermission/settings.json @@ -0,0 +1,53 @@ +{ + "resourceName": "EXORecipientPermission", + "description": "", + "roles": { + "read": [ + "Global Reader" + ], + "update": [ + "Exchange Administrator" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [], + "update": [] + } + }, + "exchange": { + "requiredroles": [ + "Mail Enabled Public Folders", + "MyName", + "Public Folders", + "Compliance Admin", + "User Options", + "Message Tracking", + "View-Only Recipients", + "Role Management", + "Legal Hold", + "Audit Logs", + "Retention Management", + "Distribution Groups", + "Move Mailboxes", + "Information Rights Management", + "Mail Recipient Creation", + "Reset Password", + "View-Only Audit Logs", + "Mail Recipients", + "Mailbox Search", + "UM Mailboxes", + "Security Group Creation and Membership", + "Mailbox Import Export", + "MyMailboxDelegation", + "MyDisplayName" + ], + "requiredrolegroups": "Organization Management" + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.psm1 index 2352b5643f..d8575c1170 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.psm1 @@ -4,6 +4,10 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( + [Parameter()] + [System.String] + $Id, + [Parameter(Mandatory = $true)] [System.String] $DisplayName, @@ -50,7 +54,7 @@ function Get-TargetResource $ManagedIdentity ) - Write-Verbose -Message "Getting configuration of Intune App Configuration Policy {$DisplayName}" + Write-Verbose -Message "Getting configuration of Intune App Configuration Policy with Id {$Id}" $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` -InboundParameters $PSBoundParameters @@ -72,17 +76,39 @@ function Get-TargetResource $nullResult.Ensure = 'Absent' try { - $configPolicy = Get-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -Filter "displayName eq '$DisplayName'" ` - -ErrorAction Stop + + try { + $configPolicy = Get-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -TargetedManagedAppConfigurationId $Id ` + -ErrorAction Stop + } + catch { + $configPolicy = $null + } if ($null -eq $configPolicy) { - Write-Verbose -Message "No App Configuration Policy with displayName {$DisplayName} was found" - return $nullResult + Write-Verbose -Message "Could not find an Intune App Configuration Policy with Id {$Id}, searching by DisplayName {$DisplayName}" + + try + { + $configPolicy = Get-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -Filter "displayName eq '$DisplayName'" ` + -ErrorAction Stop + } + catch + { + $configPolicy = $null + } + + if ($null -eq $configPolicy) + { + Write-Verbose -Message "No App Configuration Policy with DisplayName {$DisplayName} was found" + return $nullResult + } } - Write-Verbose -Message "Found App Configuration Policy with displayName {$DisplayName}" + Write-Verbose -Message "Found App Configuration Policy with Id {$($configPolicy.Id)} and DisplayName {$($configPolicy.DisplayName)}" $returnHashtable = @{ + Id = $configPolicy.Id DisplayName = $configPolicy.DisplayName Description = $configPolicy.Description CustomSettings = $configPolicy.customSettings @@ -129,6 +155,10 @@ function Set-TargetResource [CmdletBinding()] param ( + [Parameter()] + [System.String] + $Id, + [Parameter(Mandatory = $true)] [System.String] $DisplayName, @@ -217,7 +247,7 @@ function Set-TargetResource if ($policy.id) { - Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $policy.id ` + Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $policy.id ` -Targets $assignmentsHash ` -Repository 'deviceAppManagement/targetedManagedAppConfigurations' } @@ -226,10 +256,9 @@ function Set-TargetResource elseif ($Ensure -eq 'Present' -and $currentconfigPolicy.Ensure -eq 'Present') { Write-Verbose -Message "Updating Intune App Configuration Policy {$DisplayName}" - $configPolicy = Get-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -Filter "displayName eq '$DisplayName'" $updateParams = @{ - targetedManagedAppConfigurationId = $configPolicy.Id + targetedManagedAppConfigurationId = $currentconfigPolicy.Id displayName = $DisplayName description = $Description } @@ -245,15 +274,14 @@ function Set-TargetResource { $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment } - Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $configPolicy.id ` + Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $currentconfigPolicy.Id ` -Targets $assignmentsHash ` -Repository 'deviceAppManagement/targetedManagedAppConfigurations' } elseif ($Ensure -eq 'Absent' -and $currentconfigPolicy.Ensure -eq 'Present') { Write-Verbose -Message "Removing Intune App Configuration Policy {$DisplayName}" - $configPolicy = Get-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -Filter "displayName eq '$DisplayName'" - Remove-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -TargetedManagedAppConfigurationId $configPolicy.id + Remove-MgBetaDeviceAppManagementTargetedManagedAppConfiguration -TargetedManagedAppConfigurationId $currentconfigPolicy.Id } } @@ -263,6 +291,10 @@ function Test-TargetResource [OutputType([System.Boolean])] param ( + [Parameter()] + [System.String] + $Id, + [Parameter(Mandatory = $true)] [System.String] $DisplayName, @@ -308,6 +340,7 @@ function Test-TargetResource [Switch] $ManagedIdentity ) + #Ensure the proper dependencies are installed in the current environment. Confirm-M365DSCDependencies @@ -322,99 +355,78 @@ function Test-TargetResource Write-Verbose -Message "Testing configuration of Intune App Configuration Policy {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + $ValuesToCheck.Remove('Id') | Out-Null - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" - - if ($null -ne $CurrentValues.CustomSettings -and $CurrentValues.CustomSettings.Length -gt 0 -and $null -ne $CustomSettings) + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { - $value = Test-M365DSCAppConfigurationPolicyCustomSetting -Current $CurrentValues.CustomSettings -Desired $CustomSettings - if ($value -eq $false) - { - return $false - } + Write-Verbose -Message "Test-TargetResource returned $false" + return $false } - else + if ($CurrentValues.Ensure -eq 'Absent' -and $PSBoundParameters.Ensure -eq 'Absent') { - if (($null -eq $CurrentValues.CustomSettings -and $null -ne $CustomSettings) -or - ($null -ne $CurrentValues.CustomSettings -and $null -eq $CustomSettings)) - { - return $false - } + Write-Verbose -Message "Test-TargetResource returned $true" + return $true } - - $ValuesToCheck = $PSBoundParameters - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null - $ValuesToCheck.Remove('CustomSettings') | Out-Null - - #region Assignments $testResult = $true - if ((-not $CurrentValues.Assignments) -xor (-not $ValuesToCheck.Assignments)) - { - Write-Verbose -Message 'Configuration drift: one the assignment is null' - return $false - } - - if ($CurrentValues.Assignments) + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) { - if ($CurrentValues.Assignments.count -ne $ValuesToCheck.Assignments.count) + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($source.getType().Name -like '*CimInstance*') { - Write-Verbose -Message "Configuration drift: Number of assignment has changed - current {$($CurrentValues.Assignments.count)} target {$($ValuesToCheck.Assignments.count)}" - return $false - } - foreach ($assignment in $CurrentValues.Assignments) - { - #GroupId Assignment - if (-not [String]::IsNullOrEmpty($assignment.groupId)) - { - $source = [Array]$ValuesToCheck.Assignments | Where-Object -FilterScript { $_.groupId -eq $assignment.groupId } - if (-not $source) - { - Write-Verbose -Message "Configuration drift: groupId {$($assignment.groupId)} not found" - $testResult = $false - break - } - $sourceHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $source - $testResult = Compare-M365DSCComplexObject -Source $sourceHash -Target $assignment - } - #AllDevices/AllUsers assignment - else + $source = Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $source + + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if ($key -eq "Assignments") { - $source = [Array]$ValuesToCheck.Assignments | Where-Object -FilterScript { $_.dataType -eq $assignment.dataType } - if (-not $source) + $testResult = $source.count -eq $target.count + if (-Not $testResult) { break } + foreach ($assignment in $source) { - Write-Verbose -Message "Configuration drift: {$($assignment.dataType)} not found" - $testResult = $false - break + if ($assignment.dataType -like '*GroupAssignmentTarget') + { + $testResult = $null -ne ($target | Where-Object {$_.dataType -eq $assignment.DataType -and $_.groupId -eq $assignment.groupId}) + #Using assignment groupDisplayName only if the groupId is not found in the directory otherwise groupId should be the key + if (-not $testResult) + { + $groupNotFound = $null -eq (Get-MgGroup -GroupId ($assignment.groupId) -ErrorAction SilentlyContinue) + } + if (-not $testResult -and $groupNotFound) + { + $testResult = $null -ne ($target | Where-Object {$_.dataType -eq $assignment.DataType -and $_.groupDisplayName -eq $assignment.groupDisplayName}) + } + } + else + { + $testResult = $null -ne ($target | Where-Object {$_.dataType -eq $assignment.DataType}) + } + if (-Not $testResult) { break } } - $sourceHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $source - $testResult = Compare-M365DSCComplexObject -Source $sourceHash -Target $assignment - } - - if (-not $testResult) - { - $testResult = $false - break + if (-Not $testResult) { break } } + if (-Not $testResult) { break } + $ValuesToCheck.Remove($key) | Out-Null } } - if (-not $testResult) - { - return $false - } - $ValuesToCheck.Remove('Assignments') | Out-Null - #endregion + 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 + if ($TestResult) + { + $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + } Write-Verbose -Message "Test-TargetResource returned $TestResult" @@ -487,6 +499,7 @@ function Export-TargetResource { Write-Host " |---[$i/$($configPolicies.Count)] $($configPolicy.displayName)" -NoNewline $params = @{ + Id = $configPolicy.Id DisplayName = $configPolicy.displayName Ensure = 'Present' Credential = $Credential @@ -568,46 +581,6 @@ function Export-TargetResource } } -function Test-M365DSCAppConfigurationPolicyCustomSetting -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param( - [parameter(Mandatory = $true)] - [System.Object[]] - $Current, - - [parameter(Mandatory = $true)] - [System.Object[]] - $Desired - ) - if ($Current.Length -ne $Desired.Length) - { - return $false - } - - foreach ($desiredSetting in $Desired) - { - $found = $false - foreach ($currentSetting in $Current) - { - if ($currentSetting.Name -eq $desiredSetting.Name) - { - if ($currentSetting.Value -ne $desiredSetting.Value) - { - return $false - } - $found = $true - } - } - if (-not $found) - { - return $false - } - } - return $true -} - function Get-M365DSCIntuneAppConfigurationPolicyCustomSettingsAsString { [CmdletBinding()] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.schema.mof index 6f6d637942..afa2e1ce50 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppConfigurationPolicy/MSFT_IntuneAppConfigurationPolicy.schema.mof @@ -19,6 +19,7 @@ class MSFT_IntuneAppConfigurationPolicyCustomSetting [ClassVersion("1.0.0.0"), FriendlyName("IntuneAppConfigurationPolicy")] class MSFT_IntuneAppConfigurationPolicy : OMI_BaseResource { + [Write, Description("Key of the entity. Read-Only.")] String Id; [Key, Description("Display name of the app configuration policy.")] String DisplayName; [Write, Description("Description of the app configuration policy.")] String Description; [Write, Description("Assignments of the Intune Policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceAndAppManagementAssignmentFilter/MSFT_IntuneDeviceAndAppManagementAssignmentFilter.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceAndAppManagementAssignmentFilter/MSFT_IntuneDeviceAndAppManagementAssignmentFilter.psm1 index fe0f04941d..1c043b3278 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceAndAppManagementAssignmentFilter/MSFT_IntuneDeviceAndAppManagementAssignmentFilter.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceAndAppManagementAssignmentFilter/MSFT_IntuneDeviceAndAppManagementAssignmentFilter.psm1 @@ -310,21 +310,32 @@ function Test-TargetResource Write-Verbose -Message "Testing configuration of assignment filter {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + $ValuesToCheck.Remove('Identity') | Out-Null - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) + { + Write-Verbose -Message "Test-TargetResource returned $false" + return $false + } + if ($CurrentValues.Ensure -eq 'Absent' -and $PSBoundParameters.Ensure -eq 'Absent') + { + Write-Verbose -Message "Test-TargetResource returned $true" + return $true + } + $testResult = $true - $ValuesToCheck = $PSBoundParameters - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null - $ValuesToCheck.Remove('Identity') | Out-Null + 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 + if ($TestResult) + { + $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_IntuneDeviceCompliancePolicyAndroid/MSFT_IntuneDeviceCompliancePolicyAndroid.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroid/MSFT_IntuneDeviceCompliancePolicyAndroid.psm1 index 6b3353da1a..39d61be227 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroid/MSFT_IntuneDeviceCompliancePolicyAndroid.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroid/MSFT_IntuneDeviceCompliancePolicyAndroid.psm1 @@ -182,7 +182,7 @@ function Get-TargetResource try { $devicePolicy = Get-MgBetaDeviceManagementDeviceCompliancePolicy ` - -ErrorAction Stop | Where-Object ` + -ErrorAction SilentlyContinue | Where-Object ` -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.androidCompliancePolicy' -and ` $_.displayName -eq $($DisplayName) } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile.psm1 index da9d328933..256d43baf4 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile/MSFT_IntuneDeviceCompliancePolicyAndroidWorkProfile.psm1 @@ -172,7 +172,7 @@ function Get-TargetResource try { $devicePolicy = Get-MgBetaDeviceManagementDeviceCompliancePolicy ` - -ErrorAction Stop | Where-Object ` + -ErrorAction SilentlyContinue | Where-Object ` -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.androidWorkProfileCompliancePolicy' -and ` $_.displayName -eq $($DisplayName) } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 index 61399e6146..0e78c8b97a 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyWindows10/MSFT_IntuneDeviceCompliancePolicyWindows10.psm1 @@ -197,7 +197,7 @@ function Get-TargetResource try { $devicePolicy = Get-MgBetaDeviceManagementDeviceCompliancePolicy ` - -ErrorAction Stop | Where-Object ` + -ErrorAction SilentlyContinue | Where-Object ` -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10CompliancePolicy' -and ` $_.displayName -eq $($DisplayName) } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyiOs/MSFT_IntuneDeviceCompliancePolicyiOs.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyiOs/MSFT_IntuneDeviceCompliancePolicyiOs.psm1 index 4e5ccc567a..d9fe71c7a5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyiOs/MSFT_IntuneDeviceCompliancePolicyiOs.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceCompliancePolicyiOs/MSFT_IntuneDeviceCompliancePolicyiOs.psm1 @@ -146,7 +146,7 @@ function Get-TargetResource try { $devicePolicy = Get-MgBetaDeviceManagementDeviceCompliancePolicy ` - -ErrorAction Stop | Where-Object ` + -ErrorAction SilentlyContinue | Where-Object ` -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.iosCompliancePolicy' -and ` $_.displayName -eq $($DisplayName) } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10.psm1 index abd502c21c..63532eaf41 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10/MSFT_IntuneDeviceConfigurationNetworkBoundaryPolicyWindows10.psm1 @@ -92,8 +92,8 @@ function Get-TargetResource { $getValue = Get-MgBetaDeviceManagementDeviceConfiguration ` -Filter "DisplayName eq '$DisplayName'" ` - -ErrorAction SilentlyContinue | Where-Object -FilterScript { ` - $_.AdditionalProperties -eq '#microsoft.graph.windows10NetworkBoundaryConfiguration' ` + -ErrorAction SilentlyContinue | Where-Object -FilterScript { + $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10NetworkBoundaryConfiguration' } } } @@ -269,15 +269,7 @@ function Set-TargetResource #endregion $currentInstance = Get-TargetResource @PSBoundParameters - - $PSBoundParameters.Remove('Ensure') | Out-Null - $PSBoundParameters.Remove('Credential') | Out-Null - $PSBoundParameters.Remove('ApplicationId') | Out-Null - $PSBoundParameters.Remove('ApplicationSecret') | Out-Null - $PSBoundParameters.Remove('TenantId') | Out-Null - $PSBoundParameters.Remove('CertificateThumbprint') | Out-Null - $PSBoundParameters.Remove('ManagedIdentity') | Out-Null - $PSBoundParameters.Remove('Verbose') | Out-Null + $PSBoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { @@ -434,6 +426,8 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + $ValuesToCheck.Remove('Id') | Out-Null if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { @@ -465,11 +459,6 @@ function Test-TargetResource } } - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" @@ -538,8 +527,8 @@ function Export-TargetResource [array]$getValue = Get-MgBetaDeviceManagementDeviceConfiguration ` -All ` -ErrorAction Stop | Where-Object ` - -FilterScript { ` - $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10NetworkBoundaryConfiguration' ` + -FilterScript { + $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.windows10NetworkBoundaryConfiguration' } #endregion diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject.psm1 index d98004d87a..72f8b9ab6e 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneDeviceConfigurationPolicyAndroidOpenSourceProject.psm1 @@ -589,7 +589,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile.psm1 index 7a3020057a..66ee61a4f1 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile/MSFT_IntuneDeviceConfigurationPolicyAndroidWorkProfile.psm1 @@ -285,7 +285,7 @@ function Get-TargetResource RequiredPasswordComplexity = $policy.AdditionalProperties.requiredPasswordComplexity WorkProfileAllowAppInstallsFromUnknownSources = $policy.AdditionalProperties.workProfileAllowAppInstallsFromUnknownSources WorkProfileDataSharingType = $policy.AdditionalProperties.workProfileDataSharingType - WorkProfileBlockNotificationsWhileDeviceLocked = $policy.AdditionalProperties.WorkProfileBlockNotificationsWhileDeviceLocked + WorkProfileBlockNotificationsWhileDeviceLocked = $policy.AdditionalProperties.workProfileBlockNotificationsWhileDeviceLocked WorkProfileBlockAddingAccounts = $policy.AdditionalProperties.workProfileBlockAddingAccounts WorkProfileBluetoothEnableContactSharing = $policy.AdditionalProperties.workProfileBluetoothEnableContactSharing WorkProfileBlockScreenCapture = $policy.AdditionalProperties.workProfileBlockScreenCapture @@ -644,8 +644,8 @@ function Set-TargetResource { Write-Verbose -Message "Updating existing Device Configuration Policy {$DisplayName}" $configDevicePolicy = Get-MgBetaDeviceManagementDeviceConfiguration -Filter "DisplayName eq '$Displayname'" -ErrorAction SilentlyContinue | Where-Object ` - -FilterScript { ` - $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.androidWorkProfileGeneralDeviceConfiguration' ` + -FilterScript { + $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.androidWorkProfileGeneralDeviceConfiguration' } $PSBoundParameters.Remove('DisplayName') | Out-Null @@ -673,7 +673,7 @@ function Set-TargetResource { Write-Verbose -Message "Removing Device Configuration Policy {$DisplayName}" $configDevicePolicy = Get-MgBetaDeviceManagementDeviceConfiguration -Filter "DisplayName eq '$Displayname'" -ErrorAction SilentlyContinue | Where-Object ` - -FilterScript { ` + -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.androidWorkProfileGeneralDeviceConfiguration' ` } @@ -929,24 +929,17 @@ function Test-TargetResource Write-Verbose -Message "Testing configuration of Device Configuration Policy {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters - - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" - - $ValuesToCheck = $PSBoundParameters - $ValuesToCheck.Remove('Credential') | Out-Null - $ValuesToCheck.Remove('ApplicationId') | Out-Null - $ValuesToCheck.Remove('TenantId') | Out-Null - $ValuesToCheck.Remove('ApplicationSecret') | Out-Null + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false } - #region Assignments $testResult = $true + #region Assignments if ((-not $CurrentValues.Assignments) -xor (-not $ValuesToCheck.Assignments)) { Write-Verbose -Message 'Configuration drift: one the assignment is null' @@ -1004,10 +997,16 @@ function Test-TargetResource $ValuesToCheck.Remove('Assignments') | Out-Null #endregion - $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` - -Source $($MyInvocation.MyCommand.Source) ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck $ValuesToCheck.Keys + 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 + } Write-Verbose -Message "Test-TargetResource returned $TestResult" diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.psm1 index 7214303fba..b6f2f20f3d 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.psm1 @@ -57,6 +57,10 @@ function Get-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, + [Parameter()] + [System.Int32] + $Priority, + [Parameter()] [System.String] [ValidateSet('Absent', 'Present')] @@ -107,7 +111,12 @@ function Get-TargetResource try { - $config = Get-MgBetaDeviceManagementDeviceEnrollmentConfiguration -DeviceEnrollmentConfigurationId $Identity -ErrorAction silentlyContinue + try { + $config = Get-MgBetaDeviceManagementDeviceEnrollmentConfiguration -DeviceEnrollmentConfigurationId $Identity -ErrorAction Stop + } + catch { + $config = $null + } if ($null -eq $config) { @@ -127,6 +136,7 @@ function Get-TargetResource DisplayName = $config.DisplayName Description = $config.Description DeviceEnrollmentConfigurationType = $config.DeviceEnrollmentConfigurationType.toString() + Priority = $config.Priority Ensure = 'Present' Credential = $Credential ApplicationId = $ApplicationId @@ -229,6 +239,10 @@ function Set-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, + [Parameter()] + [System.Int32] + $Priority, + [Parameter()] [System.String] [ValidateSet('Absent', 'Present')] @@ -258,6 +272,7 @@ function Set-TargetResource [Switch] $ManagedIdentity ) + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` -InboundParameters $PSBoundParameters @@ -276,6 +291,12 @@ function Set-TargetResource $currentCategory = Get-TargetResource @PSBoundParameters $PSBoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters $PSBoundParameters.Remove('Identity') | Out-Null + $PriorityPresent = $false + if ($PSBoundParameters.Keys.Contains('Priority')) + { + $PriorityPresent = $true + $PSBoundParameters.Remove('Priority') | Out-Null + } if ($Ensure -eq 'Present' -and $currentCategory.Ensure -eq 'Absent') { @@ -332,10 +353,19 @@ function Set-TargetResource $assignmentsHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignments Update-DeviceConfigurationPolicyAssignment ` - -DeviceConfigurationPolicyId $policy.id ` + -DeviceConfigurationPolicyId $policy.Id ` -Targets $assignmentsHash ` -Repository 'deviceManagement/deviceEnrollmentConfigurations' } + + if ($PriorityPresent -and $Priority -ne $policy.Priority) + { + $Uri = "/beta/deviceManagement/deviceEnrollmentConfigurations/{0}/setPriority" -f $policy.Id + $Body = @{ + priority = $Priority + } + Invoke-MgGraphRequest -Method POST -Uri $Uri -Body $Body + } } } elseif ($Ensure -eq 'Present' -and $currentCategory.Ensure -eq 'Present') @@ -380,29 +410,36 @@ function Set-TargetResource #Write-Verbose ($PSBoundParameters | ConvertTo-Json -Depth 20) Update-MgBetaDeviceManagementDeviceEnrollmentConfiguration ` -BodyParameter ([hashtable]$PSBoundParameters) ` - -DeviceEnrollmentConfigurationId $Identity + -DeviceEnrollmentConfigurationId $currentCategory.Identity #Assignments from DefaultPolicy are not editable and will raise an alert - if ($Identity -notlike '*_DefaultPlatformRestrictions') + if ($currentCategory.Identity -notlike '*_DefaultPlatformRestrictions') { if ($null -ne $Assignments -and $Assignments -ne @()) { $assignmentsHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignments Update-DeviceConfigurationPolicyAssignment ` - -DeviceConfigurationPolicyId $Identity ` - -Targets $assignmentsHash ` - -Repository 'deviceManagement/deviceEnrollmentConfigurations' + -DeviceConfigurationPolicyId $currentCategory.Identity ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/deviceEnrollmentConfigurations' + } + + if ($PriorityPresent -and $Priority -ne $currentCategory.Priority) + { + $Uri = "/beta/deviceManagement/deviceEnrollmentConfigurations/{0}/setPriority" -f $currentCategory.Identity + $Body = @{ + priority = $Priority + } + Invoke-MgGraphRequest -Method POST -Uri $Uri -Body $Body } } } elseif ($Ensure -eq 'Absent' -and $currentCategory.Ensure -eq 'Present') { Write-Verbose -Message "Removing Device Enrollment Platform Restriction {$DisplayName}" - $config = Get-MgBetaDeviceManagementDeviceEnrollmentConfiguration -Filter "displayName eq '$DisplayName'" ` - | Where-Object -FilterScript { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.deviceEnrollmentPlatformRestrictionsConfiguration' } - Remove-MgBetaDeviceManagementDeviceEnrollmentConfiguration -DeviceEnrollmentConfigurationId $config.id + Remove-MgBetaDeviceManagementDeviceEnrollmentConfiguration -DeviceEnrollmentConfigurationId $currentCategory.Identity } } @@ -465,6 +502,10 @@ function Test-TargetResource [Microsoft.Management.Infrastructure.CimInstance[]] $Assignments, + [Parameter()] + [System.Int32] + $Priority, + [Parameter()] [System.String] [ValidateSet('Absent', 'Present')] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.schema.mof index 673102cc1e..86c13038c2 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneDeviceEnrollmentPlatformRestriction/MSFT_IntuneDeviceEnrollmentPlatformRestriction.schema.mof @@ -36,6 +36,7 @@ class MSFT_IntuneDeviceEnrollmentPlatformRestriction : OMI_BaseResource [Write, Description("Mac restrictions based on platform, platform operating system version, and device ownership."), EmbeddedInstance("MSFT_DeviceEnrollmentPlatformRestriction")] string MacRestriction; [Write, Description("Mac OS restrictions based on platform, platform operating system version, and device ownership."), EmbeddedInstance("MSFT_DeviceEnrollmentPlatformRestriction")] string MacOSRestriction; [Write, Description("Assignments of the policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] string Assignments[]; + [Write, Description("Priority is used when a user exists in multiple groups that are assigned enrollment configuration. Users are subject only to the configuration with the lowest priority value. Inherited from deviceEnrollmentConfiguration.")] UInt32 Priority; [Write, Description("Present ensures the restriction exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; [Write, Description("Credentials of the Intune Admin"), 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_IntuneExploitProtectionPolicyWindows10SettingCatalog/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog.psm1 index 8811c5d473..45cfe819b4 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog/MSFT_IntuneExploitProtectionPolicyWindows10SettingCatalog.psm1 @@ -430,7 +430,7 @@ function Test-TargetResource $ValuesToCheck.Remove('ApplicationSecret') | Out-Null $ValuesToCheck.Remove('Identity') | Out-Null - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message 'The policy was not found' return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleAssignment/MSFT_IntuneRoleAssignment.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleAssignment/MSFT_IntuneRoleAssignment.psm1 index 058a2e58d7..5cd954e832 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleAssignment/MSFT_IntuneRoleAssignment.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleAssignment/MSFT_IntuneRoleAssignment.psm1 @@ -559,7 +559,7 @@ function Test-TargetResource } $PSBoundParameters.Set_Item('ResourceScopes', $ResourceScopes) - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleDefinition/MSFT_IntuneRoleDefinition.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleDefinition/MSFT_IntuneRoleDefinition.psm1 index 2c0ee65b94..51e23548ee 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleDefinition/MSFT_IntuneRoleDefinition.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneRoleDefinition/MSFT_IntuneRoleDefinition.psm1 @@ -403,7 +403,7 @@ function Test-TargetResource $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10.psm1 index 5fff32e897..4be3e15f1b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10/MSFT_IntuneSettingCatalogASRRulesPolicyWindows10.psm1 @@ -188,7 +188,12 @@ function Get-TargetResource if ($null -eq $policy) { Write-Verbose -Message "No Endpoint Protection Attack Surface Protection rules Policy {$Identity} was found" - $policy = Get-MgBetaDeviceManagementConfigurationPolicy | Where-Object -FilterScript { $_.Name -eq "$DisplayName" -and $_.templateReference.TemplateId -eq "$templateReferenceId" } -ErrorAction silentlyContinue + $policy = Get-MgBetaDeviceManagementConfigurationPolicy | Where-Object -FilterScript { $_.Name -eq "$DisplayName" -and $_.templateReference.TemplateId -eq "$templateReferenceId" } + + if ($policy.Count -gt 1) + { + throw "Multiple Endpoint Protection Attack Surface Protection rules Policies with DisplayName '{$DisplayName}' were found!" + } } if ($null -eq $policy) @@ -239,18 +244,14 @@ function Get-TargetResource } } - $returnAssignments = @() - $returnAssignments += Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $policy.Id - $assignmentResult = @() - foreach ($assignmentEntry in $returnAssignments) + $returnAssignments = Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $policy.Id + if ($returnAssignments.Count -gt 0) { - $assignmentValue = @{ - dataType = $assignmentEntry.Target.AdditionalProperties.'@odata.type' - deviceAndAppManagementAssignmentFilterType = $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterType.toString() - deviceAndAppManagementAssignmentFilterId = $assignmentEntry.Target.DeviceAndAppManagementAssignmentFilterId - groupId = $assignmentEntry.Target.AdditionalProperties.groupId - } - $assignmentResult += $assignmentValue + $assignmentResult = ConvertFrom-IntunePolicyAssignment -Assignments $returnAssignments + } + else + { + $assignmentResult = @() } $returnHashtable.Add('Assignments', $assignmentResult) @@ -490,8 +491,9 @@ function Set-TargetResource } if ($policy.id) { + $intuneAssignments = [Hashtable[]] (ConvertTo-IntunePolicyAssignment -Assignments $assignmentsHash) Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $policy.id ` - -Targets $assignmentsHash + -Targets ([Array]($intuneAssignments.target)) } #endregion } @@ -509,7 +511,7 @@ function Set-TargetResource #write-verbose -message ($settings|convertto-json -Depth 20) Update-IntuneDeviceConfigurationPolicy ` - -DeviceConfigurationPolicyId $Identity ` + -DeviceConfigurationPolicyId $currentPolicy.Identity ` -Name $DisplayName ` -Description $Description ` -TemplateReferenceId $templateReferenceId ` @@ -523,8 +525,9 @@ function Set-TargetResource { $assignmentsHash += Get-M365DSCDRGComplexTypeToHashtable -ComplexObject $Assignment } - Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $Identity ` - -Targets $assignmentsHash + $intuneAssignments = [Hashtable[]] (ConvertTo-IntunePolicyAssignment -Assignments $assignmentsHash) + Update-DeviceConfigurationPolicyAssignment -DeviceConfigurationPolicyId $currentPolicy.Identity ` + -Targets ([Array]($intuneAssignments.target)) #endregion } elseif ($Ensure -eq 'Absent' -and $currentPolicy.Ensure -eq 'Present') @@ -716,7 +719,7 @@ function Test-TargetResource $ValuesToCheck.Remove('TenantId') | Out-Null $ValuesToCheck.Remove('ApplicationSecret') | Out-Null - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message 'The policy was not found' return $false @@ -752,6 +755,19 @@ function Test-TargetResource $sourceHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $source $testResult = Compare-M365DSCComplexObject -Source $sourceHash -Target $assignment } + #GroupDisplayName Assignment + if (-not [String]::IsNullOrEmpty($assignment.groupDisplayName)) + { + $source = [Array]$ValuesToCheck.Assignments | Where-Object -FilterScript { $_.groupDisplayName -eq $assignment.groupDisplayName } + if (-not $source) + { + Write-Verbose -Message "Configuration drift: groupDisplayName {$($assignment.groupDisplayName)} not found" + $testResult = $false + break + } + $sourceHash = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $source + $testResult = Compare-M365DSCComplexObject -Source $sourceHash -Target $assignment + } #AllDevices/AllUsers assignment else { diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator.psm1 index 550848afb0..063e280aa2 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator/MSFT_IntuneWiFiConfigurationPolicyAndroidDeviceAdministrator.psm1 @@ -474,7 +474,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner.psm1 index e76afffc7c..18122fecbc 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseDeviceOwner.psm1 @@ -565,7 +565,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile.psm1 index a053896d55..1c43c44ddd 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile/MSFT_IntuneWifiConfigurationPolicyAndroidEnterpriseWorkProfile.psm1 @@ -472,7 +472,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidForWork/MSFT_IntuneWifiConfigurationPolicyAndroidForWork.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidForWork/MSFT_IntuneWifiConfigurationPolicyAndroidForWork.psm1 index 65f8ed0088..f662b18c5e 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidForWork/MSFT_IntuneWifiConfigurationPolicyAndroidForWork.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidForWork/MSFT_IntuneWifiConfigurationPolicyAndroidForWork.psm1 @@ -471,7 +471,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject.psm1 index 70ed28d0bf..35f605ec13 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject/MSFT_IntuneWifiConfigurationPolicyAndroidOpenSourceProject.psm1 @@ -497,7 +497,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyIOS/MSFT_IntuneWifiConfigurationPolicyIOS.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyIOS/MSFT_IntuneWifiConfigurationPolicyIOS.psm1 index e710718398..fa1376d8fa 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyIOS/MSFT_IntuneWifiConfigurationPolicyIOS.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyIOS/MSFT_IntuneWifiConfigurationPolicyIOS.psm1 @@ -551,7 +551,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyMacOS/MSFT_IntuneWifiConfigurationPolicyMacOS.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyMacOS/MSFT_IntuneWifiConfigurationPolicyMacOS.psm1 index d1bf3f164c..fa8ad74a13 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyMacOS/MSFT_IntuneWifiConfigurationPolicyMacOS.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyMacOS/MSFT_IntuneWifiConfigurationPolicyMacOS.psm1 @@ -538,7 +538,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyWindows10/MSFT_IntuneWifiConfigurationPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyWindows10/MSFT_IntuneWifiConfigurationPolicyWindows10.psm1 index 62701eca3b..2dc45c9668 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyWindows10/MSFT_IntuneWifiConfigurationPolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneWifiConfigurationPolicyWindows10/MSFT_IntuneWifiConfigurationPolicyWindows10.psm1 @@ -581,7 +581,7 @@ function Test-TargetResource $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SCDLPComplianceRule/MSFT_SCDLPComplianceRule.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SCDLPComplianceRule/MSFT_SCDLPComplianceRule.psm1 index 603ba9521a..d2f4d0c29f 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SCDLPComplianceRule/MSFT_SCDLPComplianceRule.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SCDLPComplianceRule/MSFT_SCDLPComplianceRule.psm1 @@ -389,6 +389,7 @@ function Get-TargetResource $ExceptIfContentExtensionMatchesWords = $PolicyRule.ExceptIfContentExtensionMatchesWords.Replace(' ', '').Split(',') } + $fancyDoubleQuotes = "[\u201C\u201D]" $result = @{ Ensure = 'Present' Name = $PolicyRule.Name diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 index 05951e4304..4874ead6f7 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_SPOUserProfileProperty/MSFT_SPOUserProfileProperty.psm1 @@ -326,21 +326,24 @@ function Export-TargetResource if ($Results -is [System.Collections.Hashtable] -and $Results.Count -gt 1) { - $Results.Properties = ConvertTo-M365DSCSPOUserProfilePropertyInstanceString -Properties $Results.Properties - $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` - -Results $Results - $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` - -ConnectionMode $ConnectionMode ` - -ModulePath $PSScriptRoot ` - -Results $Results ` - -Credential $Credential - if ($null -ne $Results.Properties) + if ($Results.Properties) { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Properties' + $Results.Properties = ConvertTo-M365DSCSPOUserProfilePropertyInstanceString -Properties $Results.Properties + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + if ($null -ne $Results.Properties) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Properties' + } + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName } - $dscContent += $currentDSCBlock - Save-M365DSCPartialExport -Content $currentDSCBlock ` - -FileName $Global:PartialExportFileName Write-Host $Global:M365DSCEmojiGreenCheckMark } diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallParkPolicy/MSFT_TeamsCallParkPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallParkPolicy/MSFT_TeamsCallParkPolicy.psm1 index 1106286ec6..ed6ad7db1e 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallParkPolicy/MSFT_TeamsCallParkPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallParkPolicy/MSFT_TeamsCallParkPolicy.psm1 @@ -308,7 +308,7 @@ function Test-TargetResource $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() $ValuesToCheck.Remove('Identity') | Out-Null - if ($CurrentValues.Ensure -eq 'Absent') + if ($CurrentValues.Ensure -ne $PSBoundParameters.Ensure) { Write-Verbose -Message "Test-TargetResource returned $false" return $false diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallQueue/MSFT_TeamsCallQueue.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallQueue/MSFT_TeamsCallQueue.psm1 index d3f8b19d33..bedf6c253f 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallQueue/MSFT_TeamsCallQueue.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsCallQueue/MSFT_TeamsCallQueue.psm1 @@ -910,7 +910,12 @@ function Export-TargetResource { $i = 1 $Script:ExportMode = $true - [array] $Script:exportedInstances = Get-CsCallQueue -ErrorAction Stop + $Script:MaxSize = 1000 + [array] $Script:exportedInstances = Get-CsCallQueue -ErrorAction Stop -First $Script:MaxSize + if ($Script:exportedInstances.Count -eq $Script:MaxSize){ + Write-Verbose -Message "WARNING: CsCallQueue isn't exporting all of them, you reach the max size." + } + $dscContent = [System.Text.StringBuilder]::New() Write-Host "`r`n" -NoNewline foreach ($instance in $exportedInstances) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsFilesPolicy/MSFT_TeamsFilesPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsFilesPolicy/MSFT_TeamsFilesPolicy.psm1 index 539e4f4ee5..ec3d0c3539 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsFilesPolicy/MSFT_TeamsFilesPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsFilesPolicy/MSFT_TeamsFilesPolicy.psm1 @@ -21,7 +21,7 @@ function Get-TargetResource [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] - $Ensure, + $Ensure = 'Present', [Parameter()] [System.Management.Automation.PSCredential] @@ -117,7 +117,7 @@ function Set-TargetResource [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] - $Ensure, + $Ensure = 'Present', [Parameter()] [System.Management.Automation.PSCredential] @@ -234,7 +234,7 @@ function Test-TargetResource [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] - $Ensure, + $Ensure = 'Present', [Parameter()] [System.Management.Automation.PSCredential] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsMeetingPolicy/MSFT_TeamsMeetingPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsMeetingPolicy/MSFT_TeamsMeetingPolicy.psm1 index 494656a498..a3cf1bedbb 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsMeetingPolicy/MSFT_TeamsMeetingPolicy.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsMeetingPolicy/MSFT_TeamsMeetingPolicy.psm1 @@ -1118,6 +1118,9 @@ function Test-TargetResource # The AllowIPVideo is temporarly not working, therefore we won't check the value. $ValuesToCheck.Remove('AllowIPVideo') | Out-Null + # The AllowUserToJoinExternalMeeting doesn't do anything based on official documentation + $ValuesToCheck.Remove('AllowUserToJoinExternalMeeting') | Out-Null + $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` -DesiredValues $PSBoundParameters ` diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.psm1 index 040d5b62b2..c9cc4664d5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.psm1 @@ -61,9 +61,25 @@ function Get-TargetResource [System.String] $Ensure = 'Present', - [Parameter(Mandatory = $true)] + [Parameter()] [System.Management.Automation.PSCredential] - $Credential + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity ) Write-Verbose -Message "Getting the Teams Calling Policy $($Identity)" @@ -111,6 +127,10 @@ function Get-TargetResource ForwardingTarget = $instance.ForwardingTarget Ensure = 'Present' Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent } } catch @@ -187,9 +207,25 @@ function Set-TargetResource [System.String] $Ensure = 'Present', - [Parameter(Mandatory = $true)] + [Parameter()] [System.Management.Automation.PSCredential] - $Credential + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity ) Write-Verbose -Message 'Setting Teams User Calling Settings' @@ -297,9 +333,25 @@ function Test-TargetResource [System.String] $Ensure = 'Present', - [Parameter(Mandatory = $true)] + [Parameter()] [System.Management.Automation.PSCredential] - $Credential + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity ) #Ensure the proper dependencies are installed in the current environment. Confirm-M365DSCDependencies @@ -339,9 +391,25 @@ function Export-TargetResource [OutputType([System.String])] param ( - [Parameter(Mandatory = $true)] + [Parameter()] [System.Management.Automation.PSCredential] - $Credential + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity ) $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftTeams' ` -InboundParameters $PSBoundParameters @@ -371,9 +439,13 @@ function Export-TargetResource { Write-Host " |---[$i/$($allUsers.Length)] $($user.UserPrincipalName)" -NoNewline $params = @{ - Identity = $user.UserPrincipalName - Ensure = 'Present' - Credential = $Credential + Identity = $user.UserPrincipalName + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent } $Results = Get-TargetResource @Params diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.schema.mof index 86a7b83d7b..a3a372cde5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_TeamsUserCallingSettings/MSFT_TeamsUserCallingSettings.schema.mof @@ -14,6 +14,9 @@ class MSFT_TeamsUserCallingSettings : OMI_BaseResource [Write, Description("The forwarding target type. Supported values are Voicemail, SingleTarget, MyDelegates and Group. Voicemail is only supported for Immediate forwarding."), ValueMap{"Group","MyDelegates","SingleTarget","Voicemail"}, Values{"Group","MyDelegates","SingleTarget","Voicemail"}] String ForwardingTargetType; [Write, Description("The forwarding target. Supported types of values are ObjectId's, SIP addresses and phone numbers. For phone numbers we support the following types of formats: E.164 (+12065551234 or +1206555000;ext=1234) or non-E.164 like 1234.")] String ForwardingTarget; [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Required, Description("Credentials of the Teams Global Admin."), EmbeddedInstance("MSFT_Credential")] String Credential; + [Write, Description("Credentials of the Teams Global Admin."), EmbeddedInstance("MSFT_Credential")] String Credential; + [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; + [Write, Description("Name of the Azure Active Directory tenant used for authentication. Format contoso.onmicrosoft.com")] 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; }; diff --git a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 index 9cc63defeb..437b3cc54f 100644 --- a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 +++ b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 @@ -2,7 +2,7 @@ Dependencies = @( @{ ModuleName = 'DSCParser' - RequiredVersion = '1.4.0.1' + RequiredVersion = '1.4.0.2' }, @{ ModuleName = 'ExchangeOnlineManagement' @@ -10,75 +10,75 @@ }, @{ ModuleName = 'Microsoft.Graph.Applications' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Authentication' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.DeviceManagement' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Devices.CorporateManagement' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.DeviceManagement.Administration' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.DeviceManagement.Enrollment' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Identity.DirectoryManagement' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Identity.Governance' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Identity.SignIns' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Reports' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.Teams' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.DeviceManagement.Administration' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Beta.DirectoryObjects' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Groups' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Planner' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Users' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.Graph.Users.Actions' - RequiredVersion = '2.12.0' + RequiredVersion = '2.13.1' }, @{ ModuleName = 'Microsoft.PowerApps.Administration.PowerShell' - RequiredVersion = '2.0.178' + RequiredVersion = '2.0.180' }, @{ ModuleName = 'MicrosoftTeams' @@ -86,7 +86,7 @@ }, @{ ModuleName = "MSCloudLoginAssistant" - RequiredVersion = "1.1.10" + RequiredVersion = "1.1.13" }, @{ ModuleName = 'PnP.PowerShell' @@ -94,7 +94,7 @@ }, @{ ModuleName = 'ReverseDSC' - RequiredVersion = '2.0.0.18' + RequiredVersion = '2.0.0.19' } ) } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxPlan/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxPlan/2-Update.ps1 index 998d3222d6..280e394098 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxPlan/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxPlan/2-Update.ps1 @@ -17,11 +17,11 @@ Configuration Example EXOMailboxPlan 'ConfigureMailboxPlan' { Ensure = "Present"; - Identity = "Integration Plan"; - IssueWarningQuota = "98 GB (105,226,698,752 bytes)"; + Identity = "ExchangeOnlineEssentials"; + IssueWarningQuota = "15 GB (16,106,127,360 bytes)"; MaxReceiveSize = "25 MB (26,214,400 bytes)"; MaxSendSize = "25 MB (26,214,400 bytes)"; - ProhibitSendQuota = "99 GB (106,300,440,576 bytes)"; + ProhibitSendQuota = "15 GB (16,106,127,360 bytes)"; ProhibitSendReceiveQuota = "15 GB (16,106,127,360 bytes)"; # Updated Property RetainDeletedItemsFor = "14.00:00:00"; RoleAssignmentPolicy = "Default Role Assignment Policy"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxSettings/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxSettings/2-Update.ps1 index 91d0da31c2..7d1ec97214 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxSettings/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxSettings/2-Update.ps1 @@ -18,7 +18,7 @@ Configuration Example { EXOMailboxSettings 'OttawaTeamMailboxSettings' { - DisplayName = 'Ottawa Employees' + DisplayName = 'Conf Room Adams' TimeZone = 'Eastern Standard Time' Locale = 'en-US' # Updated Property Ensure = 'Present' diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/1-Create.ps1 index d59a79deae..01477e3204 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/1-Create.ps1 @@ -19,7 +19,7 @@ Configuration Example EXOOfflineAddressBook 'ConfigureOfflineAddressBook' { Name = "Integration Address Book" - AddressLists = @('\Offline Global Address List') + AddressLists = @('\All Users') DiffRetentionPeriod = "30" IsDefault = $true Ensure = "Present" diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/2-Update.ps1 index 3a05445e78..0fe9391578 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOOfflineAddressBook/2-Update.ps1 @@ -19,7 +19,7 @@ Configuration Example EXOOfflineAddressBook 'ConfigureOfflineAddressBook' { Name = "Integration Address Book" - AddressLists = @('\Offline Global Address List') + AddressLists = @('\All Users') DiffRetentionPeriod = "30" IsDefault = $false # Updated Property Ensure = "Present" diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOOnPremisesOrganization/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOOnPremisesOrganization/2-Update.ps1 index 8f94e907b8..da8b029d11 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOOnPremisesOrganization/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOOnPremisesOrganization/2-Update.ps1 @@ -18,13 +18,13 @@ Configuration Example { EXOOnPremisesOrganization 'ConfigureOnPremisesOrganization' { - Identity = 'Contoso' - Comment = 'Mail for Contoso. Updated' # Updated Property - HybridDomains = 'contoso.com', 'sales.contoso.com' - InboundConnector = 'Inbound to Contoso' - OrganizationGuid = 'a1bc23cb-3456-bcde-abcd-feb363cacc88' - OrganizationName = 'Contoso' - OutboundConnector = 'Outbound to Contoso' + Identity = 'Integration' + Comment = 'Mail for Contoso - Updated' #Updated Property + HybridDomains = 'o365dsc.onmicrosoft.com' + InboundConnector = 'Integration Inbound Connector' + OrganizationGuid = 'e7a80bcf-696e-40ca-8775-a7f85fbb3ebc' + OrganizationName = 'O365DSC' + OutboundConnector = 'Contoso Outbound Connector' Ensure = 'Present' Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/1-Create.ps1 index a70e94d02c..f90d243abe 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/1-Create.ps1 @@ -19,6 +19,7 @@ Configuration Example { Name = "HRApp" ApplicationIdentifier = "00000006-0000-0dd1-ac00-000000000000" + AcceptSecurityIdentifierInformation = $true Enabled = $True Ensure = "Present" Credential = $Credscredential diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/2-Update.ps1 index a38a41068b..bf09619125 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOPartnerApplication/2-Update.ps1 @@ -19,7 +19,8 @@ Configuration Example { Name = "HRApp" ApplicationIdentifier = "00000006-0000-0dd1-ac00-000000000000" - Enabled = $False # Updated Property + AcceptSecurityIdentifierInformation = $False # Updated Property + Enabled = $True Ensure = "Present" Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOPerimeterConfiguration/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOPerimeterConfiguration/2-Update.ps1 index 6f4a9e1640..7a7f729945 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOPerimeterConfiguration/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOPerimeterConfiguration/2-Update.ps1 @@ -18,7 +18,7 @@ Configuration Example EXOPerimeterConfiguration 'ConfigurePerimeterConfiguration' { IsSingleInstance = 'Yes' - GatewayIPAddresses = '123.0.0.1' + #GatewayIPAddresses = '123.0.0.1' Ensure = 'Present' Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/1-Create.ps1 index 03e8295d46..3acd8f9215 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/1-Create.ps1 @@ -20,7 +20,7 @@ Configuration Example { EndUserQuarantinePermissionsValue = 87; ESNEnabled = $False; - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Present" Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/2-Update.ps1 index feb94715b4..6c5a45c055 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/2-Update.ps1 @@ -20,7 +20,7 @@ Configuration Example { EndUserQuarantinePermissionsValue = 87; ESNEnabled = $True; # Updated Property - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Present" Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/3-Remove.ps1 index 0281fc3468..bc6b68e50e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/3-Remove.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOQuarantinePolicy/3-Remove.ps1 @@ -18,7 +18,7 @@ Configuration Example { EXOQuarantinePolicy 'ConfigureQuarantinePolicy' { - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Absent" Credential = $Credscredential } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/1-Create.ps1 new file mode 100644 index 0000000000..6b6c1e6190 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/1-Create.ps1 @@ -0,0 +1,30 @@ + +<# +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(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + + Import-DscResource -ModuleName Microsoft365DSC + + $Domain = $Credscredential.Username.Split('@')[1] + node localhost + { + EXORecipientPermission 'AddSendAs' + { + Identity = "AlexW@$Domain" + Trustee = "admin@$Domain" + AccessRights = 'SendAs' + Ensure = 'Present' + Credential = $Credscredential + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/3-Remove.ps1 new file mode 100644 index 0000000000..f263aba8e4 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORecipientPermission/3-Remove.ps1 @@ -0,0 +1,30 @@ + +<# +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(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + + Import-DscResource -ModuleName Microsoft365DSC + + $Domain = $Credscredential.Username.Split('@')[1] + node localhost + { + EXORecipientPermission 'AddSendAs' + { + + Identity = 'AdeleV@$Domain' + Trustee = "admin@$Domain" + Ensure = 'Absent' + Credential = $Credscredential + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORemoteDomain/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORemoteDomain/2-Update.ps1 index 22d9d7249d..109dc72855 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXORemoteDomain/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORemoteDomain/2-Update.ps1 @@ -27,9 +27,9 @@ Configuration Example DisplaySenderName = $True DomainName = "contoso.com" IsInternal = $False - LineWrapSize = "Integration" + LineWrapSize = "Unlimited" MeetingForwardNotificationEnabled = $False - Name = "Default" + Name = "Integration" NonMimeCharacterSet = "iso-8859-1" PreferredInternetCodePageForShiftJis = "Undefined" TargetDeliveryDomain = $False diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXORoleAssignmentPolicy/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXORoleAssignmentPolicy/2-Update.ps1 index 7005a4835f..b9166d8e45 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXORoleAssignmentPolicy/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXORoleAssignmentPolicy/2-Update.ps1 @@ -17,8 +17,8 @@ Configuration Example EXORoleAssignmentPolicy 'ConfigureRoleAssignmentPolicy' { Name = "Integration Policy" - Description = "This policy grants end users the permission to set their options in Outlook on the web and perform other self-administration tasks." - IsDefault = $False # Updated Property + Description = "Updated Description" # Updated Property + IsDefault = $True Roles = @("My Marketplace Apps","MyVoiceMail","MyDistributionGroups","MyRetentionPolicies","MyContactInformation","MyBaseOptions","MyTextMessaging","MyDistributionGroupMembership","MyProfileInformation","My Custom Apps","My ReadWriteMailbox Apps") Ensure = "Present" Credential = $Credscredential diff --git a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 index bd1c11a715..b45581ddf2 100644 --- a/Modules/Microsoft365DSC/Microsoft365DSC.psd1 +++ b/Modules/Microsoft365DSC/Microsoft365DSC.psd1 @@ -3,7 +3,7 @@ # # Generated by: Microsoft Corporation # -# Generated on: 2024-02-02 +# Generated on: 2024-02-08 @{ @@ -11,7 +11,7 @@ # RootModule = '' # Version number of this module. - ModuleVersion = '1.24.131.2' + ModuleVersion = '1.24.207.2' # Supported PSEditions # CompatiblePSEditions = @() @@ -140,38 +140,25 @@ IconUri = 'https://github.com/microsoft/Microsoft365DSC/blob/Dev/Modules/Microsoft365DSC/Dependencies/Images/Logo.png?raw=true' # ReleaseNotes of this module - ReleaseNotes = '* EXOAvailabilityAddressSpace - * Added support for the TargetServiceEpr and TargetTenantId parameters. - * Fixed the logic to retrieve existing instance by Forest Name. - * EXODistributionGroup - * The Get function now retrieves the ModeratedBy and ManagedBy properties - by the users UPN instead of their GUID. - * EXOHostedContentFilterRule - * Changed logic to retrieve the Rules by name. Using the Policys name instead. - * EXOIntraOrganizationConnector - * Fixes the DiscoveryEndpoint value from the Get method to include trailing - forward slash. - * EXOMalwareFilterRule - * Fixed an issue retrieving the right value for the Enabled property - * EXOOMEConfiguration - * Fixes an error in the Get method where the ExternalMailExpiryInDays property - wasnt properly returned. - * EXOSafeLinksPolicy - * Deprecated the UseTranslatedNotificationText property - * TeamsEmergencyCallRoutingPolicy - * Fix deletion of resource - FIXES [#4261](https://github.com/microsoft/Microsoft365DSC/issues/4261) + ReleaseNotes = '* TeamsAppSetupPolicy + * Changed the logic to retrieve arrays of Ids in the Get method. + * MISC + * Drift Logging + * Now includes the full list of parameters for the current values. + * Telemetry + * Added a new M365DSCTelemetryEventId parameter to track duplication of events. + * IntuneDeviceEnrollmentPlatformRestriction + * Added Priority parameter + FIXES [#4081](https://github.com/microsoft/Microsoft365DSC/issues/4081) + * SCDLPComplianceRule + * Properly escapes fancy quotes in the Get method. * TeamsMeetingPolicy - * Fixed issue with missing ManagedIdentity parameter in Test signature. - * TeamsUpdateManagementPolicy - * Fixed issue with missing ManagedIdentity parameter in Set signature. - * TEAMS - * Added support for ManagedIdentity Authentication across Teams resources. + * Ignore the AllowUserToJoinExternalMeeting parameterfor drift evaluation + since it doesnt do anything based on official documentation. * DEPENDENCIES - * Updated MSCloudLoginAssistant dependencies to version 1.1.10. - * MISC - * Change the way to Export encoding is done so that it no longer relies - on the Get-DSCResource function.' + * Updated Microsoft.PowerApps.Administration.PowerShell to version 2.0.180. + * Updated MSCloudLoginAssistant to version 1.1.11 + * Updated ReverseDSC to version 2.0.0.19' # 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 2af67080d1..afcfc6264b 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 @@ -1309,6 +1309,10 @@ function Update-DeviceConfigurationPolicyAssignment foreach ($target in $targets) { $formattedTarget = @{"@odata.type" = $target.dataType} + if(-not $formattedTarget."@odata.type" -and $target."@odata.type") + { + $formattedTarget."@odata.type" = $target."@odata.type" + } if ($target.groupId) { $formattedTarget.Add('groupId',$target.groupId) diff --git a/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 index de0b2dc117..6514eb30e3 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCLogEngine.psm1 @@ -80,7 +80,7 @@ function New-M365DSCLogEntry #region Telemetry $driftedData = [System.Collections.Generic.Dictionary[[String], [String]]]::new() - $driftedData.Add('Event', 'Error') + $driftedData.Add('M365DSCOperation', 'Error') $driftedData.Add('CustomMessage', $Message) $driftedData.Add('Source', $Source) diff --git a/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 index 7330466d83..db573948a1 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCReport.psm1 @@ -722,83 +722,88 @@ function Compare-M365DSCConfigurations { [string]$key = Get-M365DSCCimInstanceKey -CIMInstance $instance - if ($null -ne $key) - { - $destinationResourceInstances = $destinationResource.$destinationPropertyName | Where-Object -FilterScript {$_."$key" -eq $instance."$key"} + $destinationResourceInstances = $destinationResource.$destinationPropertyName | Where-Object -FilterScript {$_."$key" -eq $instance."$key"} - if ($null -ne $destinationResourceInstances) + if ($null -ne $destinationResourceInstances) + { + # There is a chance we found multiple instances of a CIMInstance based on its key property. + # If that's the case, loop through each instance found and if at least one of them is + # a perfect match, then don't consider this a drift. + $foundOneMatch = $false + $foundMatchResource = $null + $drift = $null + foreach ($destinationResourceInstance in $destinationResourceInstances) { - # There is a chance we found 2 instances of a CIMInstance based on its key property. - # If that's the case, loop through each instance found and if at least of of them is - # a perfect match, then don't consider this a drift. - $foundOneMatch = $false - $drift = $null - foreach ($destinationResourceInstance in $destinationResourceInstances) + $foundResourceMatch = $true + [array]$driftProperties = @() + foreach ($property in $instance.Keys) { - $foundResourceMatch = $true - foreach ($property in $instance.Keys) + if ($null -eq $destinationResourceInstance."$property" -or $null -ne (Compare-Object -ReferenceObject ($instance."$property")` + -DifferenceObject ($destinationResourceInstance."$property"))) { - if ($null -eq $destinationResourceInstance."$property" -or $null -ne (Compare-Object -ReferenceObject ($instance."$property")` - -DifferenceObject ($destinationResourceInstance."$property"))) - { - $drift = @{ - ResourceName = $sourceResource.ResourceName - ResourceInstanceName = $destinationResource.ResourceInstanceName - Key = $propertyName - KeyValue = $instance."$key" - Properties = @(@{ - ParameterName = $property - CIMInstanceKey = $key - CIMInstanceValue = $instance."$Key" - ValueInSource = $instance."$property" - ValueInDestination = $destinationResourceInstance."$property" - }) - } - $foundResourceMatch = $false + $driftProperties += @{ + ParameterName = $property + CIMInstanceKey = $key + CIMInstanceValue = $instance."$Key" + ValueInSource = $instance."$property" + ValueInDestination = $destinationResourceInstance."$property" } - } - if ($foundResourceMatch) - { - $foundOneMatch = $true + $foundResourceMatch = $false } } - if ($foundOneMatch) + if ($foundResourceMatch) { - # If a match was found, clear the drift. - $drift = $null + $foundOneMatch = $true + $foundMatchResource = $destinationResourceInstance } else { - $Delta += , $drift - $drift = $null + $drift = @{ + ResourceName = $sourceResource.ResourceName + ResourceInstanceName = $destinationResource.ResourceInstanceName + Key = $propertyName + KeyValue = $instance."$key" + Properties = $driftProperties + } } } + if ($foundOneMatch) + { + # If a match was found, clear the drift. + $drift = $null + $destinationResource.$destinationPropertyName = $destinationResource.$destinationPropertyName | Where-Object { $_ -ne $foundMatchResource } + } else { - # We have detected a drift where the CIM Instance exists in the Source but NOT in the Destination - $drift = @{ - ResourceName = $sourceResource.ResourceName - ResourceInstanceName = $destinationResource.ResourceInstanceName - Key = $propertyName - KeyValue = $instance."$key" - Properties = @(@{ - ParameterName = $propertyName - CIMInstanceKey = $key - CIMInstanceValue = $instance."$Key" - ValueInSource = $instance - ValueInDestination = $null - }) - } - if ($null -ne $drift) - { - $Delta += , $drift - $drift = $null - } + $Delta += , $drift + $drift = $null + } + } + else + { + # We have detected a drift where the CIM Instance exists in the Source but NOT in the Destination + $drift = @{ + ResourceName = $sourceResource.ResourceName + ResourceInstanceName = $destinationResource.ResourceInstanceName + Key = $propertyName + KeyValue = $instance."$key" + Properties = @(@{ + ParameterName = $propertyName + CIMInstanceKey = $key + CIMInstanceValue = $instance."$Key" + ValueInSource = $instance + ValueInDestination = $null + }) + } + if ($null -ne $drift) + { + $Delta += , $drift + $drift = $null } } } } - # Needs to be a separate nested if statement otherwise the ReferenceObject an be null and it will error out; + # Needs to be a separate nested if statement otherwise the ReferenceObject can be null and it will error out; elseif ($destinationResource.ContainsKey($destinationPropertyName) -eq $false -or (-not [System.String]::IsNullOrEmpty($propertyName) -and $null -ne (Compare-Object -ReferenceObject ($sourceResource.$propertyName)` -DifferenceObject ($destinationResource.$destinationPropertyName))) -and @@ -853,8 +858,8 @@ function Compare-M365DSCConfigurations } } - # Do the scan the other way around because there's a chance that the property, if null, wasn't part of the source - # object. By scanning against the destination we will catch properties that are not null on the source but not null in destination; + # Do the scan the other way around because there's a chance that the property, if null, wasn't part of the source object. + # By scanning against the destination we will catch properties that are not null on the source but not null in destination; foreach ($propertyName in $destinationResource.Keys) { if ($propertyName -notin $filteredProperties) @@ -871,89 +876,91 @@ function Compare-M365DSCConfigurations { [string]$key = Get-M365DSCCimInstanceKey -CIMInstance $instance - if ($null -ne $key) - { - $sourceResourceInstances = $sourceResource.$sourcePropertyName | Where-Object -FilterScript {$_."$key" -eq $instance."$key"} + $sourceResourceInstances = $sourceResource.$sourcePropertyName | Where-Object -FilterScript {$_."$key" -eq $instance."$key"} - if ($null -ne $sourceResourceInstances) + if ($null -ne $sourceResourceInstances) + { + # There is a chance we found 2 instances of a CIMInstance based on its key property. + # If that's the case, loop through each instance found and if at least one of them is + # a perfect match, then don't consider this a drift. + $foundOneMatch = $false + $drift = $null + foreach ($sourceResourceInstance in $sourceResourceInstances) { - # There is a chance we found 2 instances of a CIMInstance based on its key property. - # If that's the case, loop through each instance found and if at least of of them is - # a perfect match, then don't consider this a drift. - $foundOneMatch = $false - $drift = $null - foreach ($sourceResourceInstance in $sourceResourceInstances) + $innerDrift = $null + foreach ($property in $instance.Keys) { - foreach ($property in $instance.Keys) + if ($null -eq $sourceResourceInstance."$property" -or $null -ne (Compare-Object -ReferenceObject ($instance."$property")` + -DifferenceObject ($sourceResourceInstance."$property"))) { - if ($null -eq $sourceResourceInstance."$property" -or $null -ne (Compare-Object -ReferenceObject ($instance."$property")` - -DifferenceObject ($sourceResourceInstance."$property"))) + # Make sure we haven't already added this drift in the delta return object to prevent duplicates. + $existing = $delta | Where-Object -FilterScript {$_.ResourceName -eq $destinationResource.ResourceName -and ` + $_.ResourceInstanceName -eq $destinationResource.ResourceInstanceName} + + $sameEntry = $null + if ($null -ne $existing) { - # Make sure we haven't already added this drift in the delta return object to prevent duplicates. - $existing = $delta | Where-Object -FilterScript {$_.ResourceName -eq $destinationResource.ResourceName -and ` - $_.ResourceInstanceName -eq $destinationResource.ResourceInstanceName} - - $sameEntry = $null - if ($null -ne $existing) - { - $sameEntry = $existing.Properties | Where-Object -FilterScript {$_.ParameterName -eq $property -and ` - $_.CIMInstanceKey -eq $key -and ` - $_.CIMInstanceValue -eq ($instance."$key") -and ` - $_.ValueInSource -eq $sourceResourceInstance."$property" -and ` - $_.ValueInDestination -eq $instance."$property"} - } + $sameEntry = $existing.Properties | Where-Object -FilterScript {$_.ParameterName -eq $property -and ` + $_.CIMInstanceKey -eq $key -and ` + $_.CIMInstanceValue -eq ($instance."$key") -and ` + $_.ValueInSource -eq $sourceResourceInstance."$property" -and ` + $_.ValueInDestination -eq $instance."$property"} + } - if ($null -eq $sameEntry) - { - $drift = @{ - ResourceName = $destinationResource.ResourceName - ResourceInstanceName = $destinationResource.ResourceInstanceName - Key = $propertyName - KeyValue = $instance."$key" - Properties = @(@{ - ParameterName = $property - CIMInstanceKey = $key - CIMInstanceValue = $instance."$Key" - ValueInSource = $sourceResourceInstance."$property" - ValueInDestination = $instance."$property" - }) - } + if ($null -eq $sameEntry) + { + $innerDrift = @{ + ResourceName = $destinationResource.ResourceName + ResourceInstanceName = $destinationResource.ResourceInstanceName + Key = $propertyName + KeyValue = $instance."$key" + Properties = @(@{ + ParameterName = $property + CIMInstanceKey = $key + CIMInstanceValue = $instance."$Key" + ValueInSource = $sourceResourceInstance."$property" + ValueInDestination = $instance."$property" + }) } } } - if ($null -eq $drift) - { - $foundOneMatch = $true - } } - if ($foundOneMatch) + if ($null -eq $innerDrift) { - # If a match was found, clear the drift. - $drift = $null - } - } - else - { - # We have detected a drift where the CIM Instance exists in the Destination but NOT in the Source - $drift = @{ - ResourceName = $destinationResource.ResourceName - ResourceInstanceName = $destinationResource.ResourceInstanceName - Key = $propertyName - KeyValue = $instance."$key" - Properties = @(@{ - ParameterName = $propertyName - CIMInstanceKey = $key - CIMInstanceValue = $instance."$Key" - ValueInSource = $null - ValueInDestination = $instance - }) + $foundOneMatch = $true } - if ($null -ne $drift) + else { - $Delta += , $drift - $drift = $null + $drift = $innerDrift } } + if ($foundOneMatch) + { + # If a match was found, clear the drift. + $drift = $null + } + } + else + { + # We have detected a drift where the CIM Instance exists in the Destination but NOT in the Source + $drift = @{ + ResourceName = $destinationResource.ResourceName + ResourceInstanceName = $destinationResource.ResourceInstanceName + Key = $propertyName + KeyValue = $instance."$key" + Properties = @(@{ + ParameterName = $propertyName + CIMInstanceKey = $key + CIMInstanceValue = $instance."$Key" + ValueInSource = $null + ValueInDestination = $instance + }) + } + if ($null -ne $drift) + { + $Delta += , $drift + $drift = $null + } } } } @@ -1151,6 +1158,10 @@ function Get-M365DSCResourceKey { return @('Id') } + if ($Resource.ResourceName -eq 'IntuneDeviceEnrollmentPlatformRestriction' -and $Resource.Keys.Where({ $_ -like "*Restriction"})) + { + return @('ResourceInstanceName') + } if ($Resource.ResourceName -eq 'TeamsChannel' -and -not [System.String]::IsNullOrEmpty($Resource.TeamName)) { # Teams Channel displaynames are not tenant-unique (e.g. "General" is almost in every team), but should be unique per team diff --git a/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 index f9d9554dd2..23c203d16a 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCTelemetryEngine.psm1 @@ -5,7 +5,7 @@ This function gets the Application Insights key to be used for storing telemetry .Functionality Internal, Hidden #> -function Get-ApplicationInsightsTelemetryClient +function Get-M365DSCApplicationInsightsTelemetryClient { [CmdletBinding()] param() @@ -53,13 +53,12 @@ function Add-M365DSCTelemetryEvent [System.Collections.Generic.Dictionary[[System.String], [System.Double]]] $Metrics ) - $TelemetryEnabled = [System.Environment]::GetEnvironmentVariable('M365DSCTelemetryEnabled', ` [System.EnvironmentVariableTarget]::Machine) if ($null -eq $TelemetryEnabled -or $TelemetryEnabled -eq $true) { - $TelemetryClient = Get-ApplicationInsightsTelemetryClient + $TelemetryClient = Get-M365DSCApplicationInsightsTelemetryClient try { @@ -189,31 +188,74 @@ function Add-M365DSCTelemetryEvent [array]$version = (Get-Module 'Microsoft365DSC').Version | Sort-Object -Descending $Data.Add('M365DSCVersion', $version[0].ToString()) - # Get Dependencies loaded versions + # LCM Metadata Information try { - $currentPath = Join-Path -Path $PSScriptRoot -ChildPath '../' -Resolve - $manifest = Import-PowerShellDataFile "$currentPath/Microsoft365DSC.psd1" - $dependencies = $manifest.RequiredModules + $LCMInfo = Get-DscLocalConfigurationManager -ErrorAction Stop + + $certificateConfigured = $false + if (-not [System.String]::IsNullOrEmpty($LCMInfo.CertificateID)) + { + $certificateConfigured = $true + } - $dependenciesContent = '' - foreach ($dependency in $dependencies) + $partialConfiguration = $false + if (-not [System.String]::IsNullOrEmpty($LCMInfo.PartialConfigurations)) + { + $partialConfiguration = $true + } + $Data.Add('LCMUsesPartialConfigurations', $partialConfiguration) + $Data.Add('LCMCertificateConfigured', $certificateConfigured) + $Data.Add('LCMConfigurationMode', $LCMInfo.ConfigurationMode) + $Data.Add('LCMConfigurationModeFrequencyMins', $LCMInfo.ConfigurationModeFrequencyMins) + $Data.Add('LCMRefreshMode', $LCMInfo.RefreshMode) + $Data.Add('LCMState', $LCMInfo.LCMState) + $Data.Add('LCMStateDetail', $LCMInfo.LCMStateDetail) + + if ($Global:M365DSCExportInProgress) + { + $Data.Add('M365DSCOperation', 'Export') + } + elseif ($LCMInfo.LCMStateDetail -eq 'LCM is performing a consistency check.' -or ` + $LCMInfo.LCMStateDetail -eq 'LCM exécute une vérification de cohérence.' -or ` + $LCMInfo.LCMStateDetail -eq 'LCM führt gerade eine Konsistenzüberprüfung durch.') { - $dependenciesContent += Get-Module $dependency.ModuleName | Out-String + $Data.Add('M365DSCOperation', 'MonitoringScheduled') + } + elseif ($LCMInfo.LCMStateDetail -eq 'LCM is testing node against the configuration.') + { + $Data.Add('M365DSCOperation', 'MonitoringManual') + } + elseif ($LCMInfo.LCMStateDetail -eq 'LCM is applying a new configuration.' -or ` + $LCMInfo.LCMStateDetail -eq 'LCM applique une nouvelle configuration.') + { + $Data.Add('M365DSCOperation', 'ApplyingConfiguration') + } + else + { + $Data.Add('M365DSCOperation', 'Undetermined') } - $Data.Add('DependenciesVersion', $dependenciesContent) } catch { Write-Verbose -Message $_ } + $M365DSCTelemetryEventId = (New-GUID).ToString() + $Data.Add('M365DSCTelemetryEventId', $M365DSCTelemetryEventId) + $TelemetryClient.TrackEvent($Type, $Data, $Metrics) - $TelemetryClient.Flush() } catch { - Write-Error $_ + try + { + $TelemetryClient.TrackEvent('Error', $Data, $Metrics) + } + catch + { + Write-Error $_ + } } } } @@ -336,16 +378,27 @@ function Format-M365DSCTelemetryParameters { $data.Add('Resource', $ResourceName) $data.Add('Method', $CommandName) - if (-not $Parameters.ApplicationId) + if ($Parameters.Credential) { - $data.Add('Principal', $Parameters.Credential.UserName) - $data.Add('TenantId', $Parameters.Credential.UserName.Split('@')[1]) + try + { + $data.Add('Principal', $Parameters.Credential.UserName) + $data.Add('TenantId', $Parameters.Credential.UserName.Split('@')[1]) + } + catch + { + Write-Verbose -Message $_ + } } - else + elseif ($Parameters.ApplicationId) { $data.Add('Principal', $Parameters.ApplicationId) $data.Add('TenantId', $Parameters.TenantId) } + elseif (-not [System.String]::IsNullOrEmpty($TenantId)) + { + $data.Add('TenantId', $Parameters.TenantId) + } $data.Add('ConnectionMode', (Get-M365DSCAuthenticationMode -Parameters $Parameters)) } catch diff --git a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 index aca92258d4..2b3ab15ca4 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCUtil.psm1 @@ -897,7 +897,8 @@ function Test-M365DSCParameterState { $EventMessage = [System.Text.StringBuilder]::New() $EventMessage.Append("`r`n") | Out-Null - $EventMessage.Append(" `r`n") | Out-Null + $TenantName = Get-M365DSCTenantNameFromParameterSet -ParameterSet $DesiredValues + $EventMessage.Append(" `r`n") | Out-Null $EventMessage.Append(" `r`n") | Out-Null foreach ($key in $DriftedParameters.Keys) @@ -917,8 +918,8 @@ function Test-M365DSCParameterState $driftedData.Add('CurrentValue', [string]($CurrentValues[$key])) $driftedData.Add('DesiredValue', [string]($DesiredValues[$key])) } - $TenantName = Get-M365DSCTenantNameFromParameterSet -ParameterSet $DesiredValues $driftedData.Add('Tenant', $TenantName) + $driftedData.Add('Resource', $source.Split('_')[1]) Add-M365DSCTelemetryEvent -Type 'DriftInfo' -Data $driftedData #endregion $EventMessage.Append(" " + $DriftedParameters.$key + "`r`n") | Out-Null @@ -943,6 +944,17 @@ function Test-M365DSCParameterState $EventMessage.Append(" $Value`r`n") | Out-Null } $EventMessage.Append(" `r`n") | Out-Null + $EventMessage.Append(" `r`n") | Out-Null + foreach ($Key in $CurrentValues.Keys) + { + $Value = $CurrentValues.$Key + if ([System.String]::IsNullOrEmpty($Value)) + { + $Value = "`$null" + } + $EventMessage.Append(" $Value`r`n") | Out-Null + } + $EventMessage.Append(" `r`n") | Out-Null $EventMessage.Append('') | Out-Null Add-M365DSCEvent -Message $EventMessage.ToString() -EventType 'Drift' -EntryType 'Warning' ` @@ -970,9 +982,6 @@ function Test-M365DSCParameterState -EventID 2 -Source $Source } - #region Telemetry - Add-M365DSCTelemetryEvent -Data $data - #endregion return $returnValue } @@ -1164,7 +1173,7 @@ function Export-M365DSCConfiguration [Switch] $Validate ) - + $Global:M365DSCExportInProgress = $true $Global:MaximumFunctionCount = 32767 # Define the exported resource instances' names Global variable @@ -1247,7 +1256,7 @@ function Export-M365DSCConfiguration #region Telemetry $data = [System.Collections.Generic.Dictionary[[String], [String]]]::new() - $data.Add('Event', 'Extraction') + $data.Add('M365DSCOperation', 'Extraction') $data.Add('Path', [System.String]::IsNullOrEmpty($Path)) $data.Add('FileName', $null -ne [System.String]::IsNullOrEmpty($FileName)) @@ -1348,6 +1357,7 @@ function Export-M365DSCConfiguration # Clear the exported resource instances' names Global variable $Global:M365DSCExportedResourceInstancesNames = $null + $Global:M365DSCExportInProgress = $false } $Script:M365DSCDependenciesValidated = $false @@ -1708,7 +1718,7 @@ function New-M365DSCConnection { $message = 'Both Authentication methods are attempted' Write-Verbose -Message $message - $data.Add('Event', 'Error') + $data.Add('M365DSCOperation', 'Error') $data.Add('Exception', $message) $errorText = "You can't specify both the Credential and CertificateThumbprint" $data.Add('CustomMessage', $errorText) @@ -1725,7 +1735,7 @@ function New-M365DSCConnection $message = 'No Authentication method was provided' Write-Verbose -Message $message $message += "`r`nProvided Keys --> $($InboundParameters.Keys)" - $data.Add('Event', 'Error') + $data.Add('M365DSCOperation', 'Error') $data.Add('Exception', $message) $errorText = 'You must specify either the Credential or ApplicationId, TenantId and CertificateThumbprint parameters.' $data.Add('CustomMessage', $errorText) @@ -1865,7 +1875,7 @@ function New-M365DSCConnection $message = 'No Authentication method was provided' Write-Verbose -Message $message $message += "`r`nProvided Keys --> $($InboundParameters.Keys)" - $data.Add('Event', 'Error') + $data.Add('M365DSCOperation', 'Error') $data.Add('Exception', $message) $errorText = 'You must specify either the Credential or ApplicationId, TenantId and CertificateThumbprint parameters.' $data.Add('CustomMessage', $errorText) @@ -3761,11 +3771,11 @@ function Get-M365DSCAuthenticationMode { $AuthenticationType = 'ServicePrincipalWithPath' } - elseif ($Parameters.Credentials -and $Parameters.ApplicationId) + elseif ($Parameters.Credential -and $Parameters.ApplicationId) { $AuthenticationType = 'CredentialsWithApplicationId' } - elseif ($Parameters.Credentials) + elseif ($Parameters.Credential) { $AuthenticationType = 'Credentials' } diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 index 8ae6b2b387..7f5f58570e 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 @@ -468,7 +468,7 @@ EXOOfflineAddressBook 'ConfigureOfflineAddressBook' { Name = "Integration Address Book" - AddressLists = @('\Offline Global Address List') + AddressLists = @('\All Users') DiffRetentionPeriod = "30" IsDefault = $true Ensure = "Present" @@ -619,6 +619,7 @@ { Name = "HRApp" ApplicationIdentifier = "00000006-0000-0dd1-ac00-000000000000" + AcceptSecurityIdentifierInformation = $true Enabled = $True Ensure = "Present" Credential = $Credscredential @@ -650,10 +651,18 @@ { EndUserQuarantinePermissionsValue = 87; ESNEnabled = $False; - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Present" Credential = $Credscredential } + EXORecipientPermission 'AddSendAs' + { + Identity = "AlexW@$Domain" + Trustee = "admin@$Domain" + AccessRights = 'SendAs' + Ensure = 'Present' + Credential = $Credscredential + } EXORemoteDomain '583b0b70-b45d-401f-98a6-0e7fa8434946' { Identity = "Integration" diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 index 25081b9bf3..b944ef9129 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 @@ -125,13 +125,6 @@ Ensure = "Present" Credential = $Credscredential } - EXOAuthenticationPolicyAssignment 'ConfigureAuthenticationPolicyAssignment' - { - UserName = "AdeleV@$Domain" - AuthenticationPolicyName = "Test Policy" # Updaqted Property - Ensure = "Present" - Credential = $Credscredential - } EXOAvailabilityAddressSpace 'ConfigureAvailabilityAddressSpace' { Identity = 'Contoso.com' @@ -174,7 +167,7 @@ EnforceSchedulingHorizon = $True; Ensure = "Present"; ForwardRequestsToDelegates = $True; - Identity = "AdeleV"; + Identity = "admin@$Domain"; MaximumConflictInstances = 0; MaximumDurationInMinutes = 1440; MinimumDurationInMinutes = 0; @@ -206,10 +199,10 @@ ActiveSyncBlockedDeviceIDs = @() ActiveSyncDebugLogging = $False ActiveSyncEnabled = $True - ActiveSyncMailboxPolicy = 'Demo EXO Mobile Device Policy Default' + ActiveSyncMailboxPolicy = 'Default' ActiveSyncSuppressReadReceipt = $False EwsEnabled = $True - Identity = 'AdeleV' + Identity = "admin@$Domain" ImapEnabled = $True # Updated Property ImapForceICalForCalendarRetrievalOption = $False ImapMessagesRetrievalMimeFormat = 'BestBodyFormat' @@ -220,7 +213,7 @@ OutlookMobileEnabled = $True OWAEnabled = $True OWAforDevicesEnabled = $True - OwaMailboxPolicy = 'OwaMailboxPolicy-Default' + OwaMailboxPolicy = 'OwaMailboxPolicy-Integration' PopEnabled = $False PopForceICalForCalendarRetrievalOption = $True PopMessagesRetrievalMimeFormat = 'BestBodyFormat' @@ -296,8 +289,8 @@ Name = "Integration Policy" EnabledEmailAddressTemplates = @("SMTP:@$Domain") EnabledPrimarySMTPAddressTemplate = "@$Domain" - ManagedByFilter = "" - Priority = 2 # Updated Property + ManagedByFilter = "Department -eq 'Sales'" # Updated Property + Priority = 1 Ensure = "Present" Credential = $Credscredential } @@ -312,7 +305,7 @@ } EXOGroupSettings 'TestGroup' { - DisplayName = "Test Group"; + DisplayName = "All Company"; AccessType = "Public"; AlwaysSubscribeMembersToCalendarEvents = $False; AuditLogAgeLimit = "90.00:00:00"; @@ -483,12 +476,12 @@ CreateOOFEvent = $False; Credential = $Credscredential; DeclineAllEventsForScheduledOOF = $False; - DeclineEventsForScheduledOOF = $True; # Updated Property + DeclineEventsForScheduledOOF = $False; DeclineMeetingMessage = ""; EndTime = "1/23/2024 3:00:00 PM"; Ensure = "Present"; ExternalAudience = "All"; - ExternalMessage = ""; + ExternalMessage = (New-Guid).ToString(); # Updated Property Identity = "AdeleV@$Domain"; InternalMessage = ""; OOFEventSubject = ""; @@ -499,7 +492,7 @@ Credential = $credsCredential; DetailLevel = "AvailabilityOnly"; Ensure = "Present"; - Identity = "AdeleV:\Calendar"; + Identity = "AlexW@$Domain" + ":\Calendar"; PublishDateRangeFrom = "ThreeMonths"; PublishDateRangeTo = "ThreeMonths"; PublishEnabled = $True; # Updated Property @@ -511,7 +504,7 @@ Credential = $credsCredential; Deny = $True; # Updated Property Ensure = "Present"; - Identity = "AdeleV"; + Identity = "AlexW@$Domain"; InheritanceType = "All"; User = "NT AUTHORITY\SELF"; } diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXODataClassification.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXODataClassification.Tests.ps1 index e2c9b7fe7d..061e44f6e2 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXODataClassification.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXODataClassification.Tests.ps1 @@ -31,9 +31,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return 'Credentials' } - Mock -CommandName New-DataClassification -MockWith { - } - Mock -CommandName Set-DataClassification -MockWith { } @@ -58,10 +55,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-DataClassification -MockWith { return $null } - - Mock -CommandName New-DataClassification -MockWith { - - } } It 'Should return False from the Get method' { diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORecipientPermission.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORecipientPermission.Tests.ps1 new file mode 100644 index 0000000000..ca1f3f0b94 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXORecipientPermission.Tests.ps1 @@ -0,0 +1,161 @@ +[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) + +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource EXORecipientPermission -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 'test@password1' -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 Add-RecipientPermission -MockWith { + } + + Mock -CommandName Remove-RecipientPermission -MockWith { + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + } + + # Test contexts + Context -Name 'Permission doesnt exist and it should' -Fixture { + BeforeAll { + $testParams = @{ + Ensure = 'Present' + Credential = $Credential + Identity = 'john.smith' + Trustee = 'john.doe' + } + + Mock -CommandName Get-RecipientPermission -MockWith { + return $null + } + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should return absent from the Get Method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + } + + It 'Should add the permission in the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Add-RecipientPermission -Exactly 1 + } + } + + Context -Name 'Permission exists and is not the Desired State' -Fixture { + BeforeAll { + $testParams = @{ + Ensure = 'Present' + Credential = $Credential + Identity = 'john.smith' + Trustee = 'john.doe' + } + + Mock -CommandName Get-RecipientPermission -MockWith { + return $null + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should return present from the Get Method' { + (Get-TargetResource @testParams).Ensure | Should -Be Absent + } + } + + Context -Name 'Permission exist and it should not' -Fixture { + BeforeAll { + $testParams = @{ + Ensure = 'Absent' + Credential = $Credential + Identity = 'john.smith' + Trustee = 'john.doe' + } + + Mock -CommandName Get-RecipientPermission -MockWith { + return @{ + Identity = 'john.smith' + Trustee = 'john.doe' + 'AccessControlType' = 'Allow' + AccessRights = @('SendAs') + IsInherited = $false + InheritanceType = 'None' + } + } + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should return absent from the Get Method' { + (Get-TargetResource @testParams).Ensure | Should -Be Present + } + + It 'Should remove the permission in the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Remove-RecipientPermission -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + + Mock -CommandName Get-RecipientPermission -MockWith { + return @{ + Identity = 'john.smith' + Trustee = 'john.doe' + 'AccessControlType' = 'Allow' + AccessRights = @('SendAs') + IsInherited = $false + InheritanceType = 'None' + } + } + } + + 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/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index dc213dcafb..72f1b9c480 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -131,6 +131,27 @@ function Add-MailboxPermission $InheritanceType ) } +function Add-RecipientPermission +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $AccessRights, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $Trustee + ) +} function Disable-JournalRule { [CmdletBinding()] @@ -552,8 +573,12 @@ function Get-DistributionGroup [CmdletBinding()] param( [Parameter()] - [System.String] - $SortBy, + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromDLMembersWithDisplayNames, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromWithDisplayNames, [Parameter()] [System.Management.Automation.PSCredential] @@ -579,13 +604,21 @@ function Get-DistributionGroup [System.String] $Filter, + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromSendersOrMembersWithDisplayNames, + [Parameter()] [System.Object] $ResultSize, [Parameter()] [System.String] - $Anr + $Anr, + + [Parameter()] + [System.String] + $SortBy ) } function Get-DistributionGroupMember @@ -640,6 +673,39 @@ function Get-GlobalAddressList $DefaultOnly ) } +function Get-Group +{ + [CmdletBinding()] + param( + [Parameter()] + [System.String] + $SortBy, + + [Parameter()] + [System.Object] + $OrganizationalUnit, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object[]] + $RecipientTypeDetails, + + [Parameter()] + [System.Object] + $ResultSize, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.String] + $Anr + ) +} function Get-HostedConnectionFilterPolicy { [CmdletBinding()] @@ -735,10 +801,6 @@ function Get-Mailbox { [CmdletBinding()] param( - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ServiceSafetyConfiguration, - [Parameter()] [System.String] $SortBy, @@ -767,6 +829,18 @@ function Get-Mailbox [System.Management.Automation.SwitchParameter] $SoftDeletedMailbox, + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromSendersOrMembersWithDisplayNames, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromWithDisplayNames, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAcceptMessagesOnlyFromDLMembersWithDisplayNames, + [Parameter()] [System.Object] $ResultSize, @@ -842,17 +916,82 @@ function Get-MailboxCalendarFolder $Identity ) } -function Get-MailboxFolderStatistics +function Get-MailboxFolder { [CmdletBinding()] param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $MailFolderOnly, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $GetChildren, + [Parameter()] [System.Object] $Identity, + [Parameter()] + [System.Object] + $ResultSize, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Recurse + ) +} +function Get-MailboxFolderStatistics +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $Database, + [Parameter()] [System.String] - $FolderScope + $DiagnosticInfo, + + [Parameter()] + [System.Object] + $StoreMailboxIdentity, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeOldestAndNewestItems, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UseCustomRouting, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Archive, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeSoftDeletedRecipients, + + [Parameter()] + [System.Int32] + $SkipCount, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeAnalysis, + + [Parameter()] + [System.Object] + $ResultSize, + + [Parameter()] + [System.Object] + $FolderScope, + + [Parameter()] + [System.Object] + $Identity ) } function Get-MailboxPermission @@ -1340,6 +1479,100 @@ function Get-QuarantinePolicy $QuarantinePolicyType ) } +function Get-Recipient +{ + [CmdletBinding()] + param( + [Parameter()] + [System.String] + $SortBy, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.String] + $RecipientPreviewFilter, + + [Parameter()] + [System.String] + $Anr, + + [Parameter()] + [System.String] + $BookmarkDisplayName, + + [Parameter()] + [System.Object] + $Capabilities, + + [Parameter()] + [System.Object] + $ResultSize, + + [Parameter()] + [System.Object[]] + $RecipientTypeDetails, + + [Parameter()] + [System.String[]] + $Properties, + + [Parameter()] + [System.Object] + $PropertySet, + + [Parameter()] + [System.Object] + $AuthenticationType, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IncludeSoftDeletedRecipients, + + [Parameter()] + [System.Object[]] + $RecipientType, + + [Parameter()] + [System.Object] + $OrganizationalUnit, + + [Parameter()] + [System.Boolean] + $IncludeBookmarkObject + ) +} +function Get-RecipientPermission +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ReadFromDomainController, + + [Parameter()] + [System.Object] + $AccessRights, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $ResultSize, + + [Parameter()] + [System.Object] + $Trustee + ) +} function Get-RemoteDomain { [CmdletBinding()] @@ -1368,7 +1601,11 @@ function Get-ReportSubmissionRule param( [Parameter()] [System.Object] - $Identity + $Identity, + + [Parameter()] + [System.Object] + $State ) } function Get-ResourceConfig @@ -2001,37 +2238,45 @@ function New-App [CmdletBinding()] param( [Parameter()] - [System.String] - $Etoken, + [System.Uri] + $Url, [Parameter()] - [System.IO.Stream] - $FileStream, + [System.String] + $Identity, [Parameter()] [System.Boolean] $Enabled, [Parameter()] - [System.Uri] - $Url, + [System.Object] + $AddInOverrides, [Parameter()] [System.Object] $Mailbox, + [Parameter()] + [System.IO.Stream] + $FileStream, + [Parameter()] [System.String] $MarketplaceServicesUrl, [Parameter()] - [System.Management.Automation.SwitchParameter] - $PrivateCatalog, + [System.String] + $Etoken, [Parameter()] [System.String] $MarketplaceCorrelationID, + [Parameter()] + [System.String] + $Version, + [Parameter()] [System.Object] $DefaultStateForUser, @@ -2044,6 +2289,10 @@ function New-App [System.String] $MarketplaceUserProfileType, + [Parameter()] + [System.Object] + $AllowSetting, + [Parameter()] [System.Management.Automation.SwitchParameter] $DownloadOnly, @@ -2056,10 +2305,18 @@ function New-App [System.Object] $UserList, + [Parameter()] + [System.String] + $AppState, + [Parameter()] [System.Management.Automation.SwitchParameter] $OrganizationApp, + [Parameter()] + [System.String] + $AppType, + [Parameter()] [System.String] $MarketplaceAssetID, @@ -2074,9 +2331,17 @@ function New-App [Parameter()] [System.Management.Automation.SwitchParameter] - $AllowReadWriteMailbox - ) -} + $AllowReadWriteMailbox, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PrivateCatalog, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UpdateAppState + ) +} function New-ApplicationAccessPolicy { [CmdletBinding()] @@ -2245,35 +2510,6 @@ function New-ClientAccessRule $Scope ) } -function New-DataClassification -{ - [CmdletBinding()] - param( - [Parameter()] - [System.String] - $Description, - - [Parameter()] - [System.String] - $Name, - - [Parameter()] - [System.Globalization.CultureInfo] - $Locale, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm, - - [Parameter()] - [System.Object] - $Fingerprints, - - [Parameter()] - [System.Object] - $ClassificationRuleCollectionIdentity - ) -} function New-DataEncryptionPolicy { [CmdletBinding()] @@ -4353,7 +4589,277 @@ function New-ReportSubmissionPolicy { [CmdletBinding()] param( + [Parameter()] + [System.String] + $PostSubmitMessage, + + [Parameter()] + [System.Object] + $ReportJunkAddresses, + + [Parameter()] + [System.Boolean] + $NotificationsForPhishMalwareSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.String] + $PhishingReviewResultMessage, + + [Parameter()] + [System.String] + $PostSubmitMessageTitle, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForNotJunk, + + [Parameter()] + [System.Boolean] + $EnableCustomizedMsg, + + [Parameter()] + [System.Object] + $NotificationSenderAddress, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonTextForJunk, + + [Parameter()] + [System.Boolean] + $NotificationsForSpamSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.String] + $PostSubmitMessageForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageForPhishing, + + [Parameter()] + [System.Boolean] + $EnableThirdPartyAddress, + + [Parameter()] + [System.String] + $PreSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String] + $PreSubmitMessageForJunk, + + [Parameter()] + [System.Int32] + $UserSubmissionOptions, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonTextForPhishing, + + [Parameter()] + [System.String] + $PreSubmitMessageForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageTitleForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForNotJunk, + + [Parameter()] + [System.Boolean] + $ReportJunkToCustomizedAddress, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonLinkForPhishing, + + [Parameter()] + [System.Boolean] + $ReportNotJunkToCustomizedAddress, + + [Parameter()] + [System.String] + $PostSubmitMessageTitleForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForPhishing, + + [Parameter()] + [System.String] + $NotificationFooterMessage, + + [Parameter()] + [System.Boolean] + $EnableOrganizationBranding, + + [Parameter()] + [System.String] + $PreSubmitMessageForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForPhishing, + + [Parameter()] + [System.Boolean] + $EnableReportToMicrosoft, + + [Parameter()] + [System.String] + $PreSubmitMessageTitleForJunk, + + [Parameter()] + [System.Boolean] + $ReportChatMessageEnabled, + + [Parameter()] + [System.Object] + $ThirdPartyReportAddresses, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForJunk, + + [Parameter()] + [System.Boolean] + $NotificationsForCleanSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.String] + $PostSubmitMessageForNotJunk, + + [Parameter()] + [System.Object] + $MultiLanguageSetting, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageForJunk, + + [Parameter()] + [System.Boolean] + $DisableQuarantineReportingOption, + + [Parameter()] + [System.Object] + $ReportNotJunkAddresses, + + [Parameter()] + [System.Boolean] + $EnableUserEmailNotification, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForJunk, + + [Parameter()] + [System.String] + $PostSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageTitleForJunk, + + [Parameter()] + [System.Boolean] + $DisableUserSubmissionOptions, + + [Parameter()] + [System.Boolean] + $OnlyShowPhishingDisclaimer, + + [Parameter()] + [System.String] + $PostSubmitMessageTitleForNotJunk, + + [Parameter()] + [System.String] + $PreSubmitMessage, + + [Parameter()] + [System.String] + $PreSubmitMessageTitleForNotJunk, + + [Parameter()] + [System.String] + $JunkReviewResultMessage, + + [Parameter()] + [System.Boolean] + $EnableCustomNotificationSender, + + [Parameter()] + [System.Boolean] + $ReportChatMessageToCustomizedAddressEnabled, + + [Parameter()] + [System.Object] + $ReportPhishAddresses, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageTitleForJunk, + + [Parameter()] + [System.String] + $NotJunkReviewResultMessage, + + [Parameter()] + [System.Boolean] + $NotificationsForSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.Boolean] + $PreSubmitMessageEnabled, + + [Parameter()] + [System.Boolean] + $PostSubmitMessageEnabled, + + [Parameter()] + [System.String] + $PreSubmitMessageTitle, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForPhishing, + + [Parameter()] + [System.String] + $UserSubmissionOptionsMessage, + + [Parameter()] + [System.String] + $PostSubmitMessageForPhishing, + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonLinkForJunk, + + [Parameter()] + [System.Boolean] + $ReportPhishToCustomizedAddress ) } function New-ReportSubmissionRule @@ -4364,17 +4870,25 @@ function New-ReportSubmissionRule [System.String] $Name, + [Parameter()] + [System.Object[]] + $SentTo, + [Parameter()] [System.String] $Comments, [Parameter()] - [System.String[]] - $SentTo, + [System.Object] + $ReportSubmissionPolicy, [Parameter()] - [System.String] - $ReportSubmissionPolicy + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Boolean] + $Enabled ) } function New-RoleAssignmentPolicy @@ -5503,6 +6017,10 @@ function Remove-App [System.Object] $Identity, + [Parameter()] + [System.String] + $AppType, + [Parameter()] [System.Management.Automation.SwitchParameter] $OrganizationApp, @@ -6073,8 +6591,45 @@ function Remove-QuarantinePolicy $Identity, [Parameter()] - [System.Object] - $DomainController + [System.Object] + $DomainController + ) +} +function Remove-RecipientPermission +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipDomainValidationForMailContact, + + [Parameter()] + [System.Object] + $AccessRights, + + [Parameter()] + [System.Object] + $Trustee, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Deny, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipDomainValidationForMailUser, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipDomainValidationForSharedMailbox ) } function Remove-RemoteDomain @@ -6104,12 +6659,12 @@ function Remove-ReportSubmissionRule [CmdletBinding()] param( [Parameter()] - [System.Object] - $Identity, + [System.Management.Automation.SwitchParameter] + $Confirm, [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm + [System.Object] + $Identity ) } function Remove-RoleAssignmentPolicy @@ -9232,6 +9787,10 @@ function Set-MailContact [System.String] $CustomAttribute15, + [Parameter()] + [System.Object] + $UserSMimeCertificate, + [Parameter()] [System.Object] $ExtensionCustomAttribute1, @@ -9278,7 +9837,7 @@ function Set-MailContact [Parameter()] [System.Object] - $GrantSendOnBehalfTo, + $UserCertificate, [Parameter()] [System.Object] @@ -9296,6 +9855,10 @@ function Set-MailContact [System.Management.Automation.SwitchParameter] $ForceUpgrade, + [Parameter()] + [System.Object] + $GrantSendOnBehalfTo, + [Parameter()] [System.String] $CustomAttribute12 @@ -10042,6 +10605,10 @@ function Set-OrganizationConfig [System.Boolean] $MailTipsAllTipsEnabled, + [Parameter()] + [System.Boolean] + $PostponeRoamingSignaturesUntilLater, + [Parameter()] [System.Object] $RemotePublicFolderMailboxes, @@ -11430,107 +11997,283 @@ function Set-ReportSubmissionPolicy param( [Parameter()] [System.String] - $Identity, + $PostSubmitMessage, [Parameter()] - [System.Boolean] - $DisableQuarantineReportingOption, + [System.Object] + $ReportJunkAddresses, [Parameter()] [System.Boolean] - $EnableCustomNotificationSender, + $NotificationsForPhishMalwareSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.String] + $PhishingReviewResultMessage, + + [Parameter()] + [System.String] + $PostSubmitMessageTitle, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForNotJunk, [Parameter()] [System.Boolean] - $EnableOrganizationBranding, + $EnableCustomizedMsg, + + [Parameter()] + [System.Object] + $NotificationSenderAddress, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonTextForJunk, [Parameter()] [System.Boolean] - $EnableReportToMicrosoft, + $NotificationsForSpamSubmissionAirInvestigationsEnabled, + + [Parameter()] + [System.String] + $PostSubmitMessageForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageForPhishing, [Parameter()] [System.Boolean] $EnableThirdPartyAddress, [Parameter()] - [System.Boolean] - $EnableUserEmailNotification, + [System.String] + $PreSubmitMessageTitleForPhishing, [Parameter()] [System.String] - $JunkReviewResultMessage, + $PreSubmitMessageForJunk, + + [Parameter()] + [System.Int32] + $UserSubmissionOptions, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonTextForPhishing, [Parameter()] [System.String] - $NotJunkReviewResultMessage, + $PreSubmitMessageForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageTitleForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForNotJunk, + + [Parameter()] + [System.Boolean] + $ReportJunkToCustomizedAddress, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonLinkForPhishing, + + [Parameter()] + [System.Boolean] + $ReportNotJunkToCustomizedAddress, + + [Parameter()] + [System.String] + $PostSubmitMessageTitleForJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForPhishing, [Parameter()] [System.String] $NotificationFooterMessage, + [Parameter()] + [System.Boolean] + $EnableOrganizationBranding, + [Parameter()] [System.String] - $NotificationSenderAddress, + $PreSubmitMessageForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForNotJunk, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForPhishing, + + [Parameter()] + [System.Boolean] + $EnableReportToMicrosoft, [Parameter()] [System.String] - $PhishingReviewResultMessage, + $PreSubmitMessageTitleForJunk, + + [Parameter()] + [System.Boolean] + $ReportChatMessageEnabled, + + [Parameter()] + [System.Object] + $ThirdPartyReportAddresses, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageButtonLinkForJunk, + + [Parameter()] + [System.Boolean] + $NotificationsForCleanSubmissionAirInvestigationsEnabled, [Parameter()] [System.String] - $PostSubmitMessage, + $PostSubmitMessageForNotJunk, + + [Parameter()] + [System.Object] + $MultiLanguageSetting, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageForJunk, [Parameter()] [System.Boolean] - $PostSubmitMessageEnabled, + $DisableQuarantineReportingOption, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Object] + $ReportNotJunkAddresses, + + [Parameter()] + [System.Boolean] + $EnableUserEmailNotification, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageForJunk, [Parameter()] [System.String] - $PostSubmitMessageTitle, + $PostSubmitMessageTitleForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePreSubmitMessageTitleForJunk, + + [Parameter()] + [System.Boolean] + $DisableUserSubmissionOptions, + + [Parameter()] + [System.Boolean] + $OnlyShowPhishingDisclaimer, + + [Parameter()] + [System.String] + $PostSubmitMessageTitleForNotJunk, [Parameter()] [System.String] $PreSubmitMessage, [Parameter()] - [System.Boolean] - $PreSubmitMessageEnabled, + [System.String] + $PreSubmitMessageTitleForNotJunk, [Parameter()] [System.String] - $PreSubmitMessageTitle, + $JunkReviewResultMessage, [Parameter()] - [System.String[]] - $ReportJunkAddresses = @(), + [System.Boolean] + $EnableCustomNotificationSender, [Parameter()] [System.Boolean] - $ReportJunkToCustomizedAddress, + $ReportChatMessageToCustomizedAddressEnabled, + + [Parameter()] + [System.Object] + $ReportPhishAddresses, [Parameter()] [System.String[]] - $ReportNotJunkAddresses = @(), + $MultiLanguagePostSubmitMessageTitleForJunk, + + [Parameter()] + [System.String] + $NotJunkReviewResultMessage, [Parameter()] [System.Boolean] - $ReportNotJunkToCustomizedAddress, + $NotificationsForSubmissionAirInvestigationsEnabled, [Parameter()] - [System.String[]] - $ReportPhishAddresses = @(), + [System.Boolean] + $PreSubmitMessageEnabled, [Parameter()] [System.Boolean] - $ReportPhishToCustomizedAddress, + $PostSubmitMessageEnabled, + + [Parameter()] + [System.String] + $PreSubmitMessageTitle, [Parameter()] [System.String[]] - $ThirdPartyReportAddresses = @(), + $MultiLanguagePreSubmitMessageTitleForPhishing, [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm + [System.String[]] + $MultiLanguagePreSubmitMessageButtonTextForPhishing, + + [Parameter()] + [System.String] + $UserSubmissionOptionsMessage, + + [Parameter()] + [System.String] + $PostSubmitMessageForPhishing, + + [Parameter()] + [System.String[]] + $MultiLanguagePostSubmitMessageButtonLinkForJunk, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Boolean] + $ReportPhishToCustomizedAddress ) } function Set-ReportSubmissionRule @@ -11539,15 +12282,23 @@ function Set-ReportSubmissionRule param( [Parameter()] [System.String] - $Identity, + $Name, + + [Parameter()] + [System.Object[]] + $SentTo, [Parameter()] [System.String] $Comments, [Parameter()] - [System.String[]] - $SentTo, + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $ReportSubmissionPolicy, [Parameter()] [System.Management.Automation.SwitchParameter] @@ -12927,7 +13678,11 @@ function Set-User param( [Parameter()] [System.String] - $Company, + $MailboxRegion, + + [Parameter()] + [System.Boolean] + $IsShadowMailbox, [Parameter()] [System.String] @@ -12982,8 +13737,8 @@ function Set-User $Force, [Parameter()] - [System.String] - $LastName, + [System.Object] + $ManagedOnboardingType, [Parameter()] [System.Management.Automation.SwitchParameter] @@ -13022,8 +13777,8 @@ function Set-User $AssistantName, [Parameter()] - [System.Object] - $OtherHomePhone, + [System.String] + $Company, [Parameter()] [System.String] @@ -13046,12 +13801,12 @@ function Set-User $Notes, [Parameter()] - [System.Management.Automation.SwitchParameter] - $PermanentlyClearPreviousMailboxInfo, + [System.String] + $LastName, [Parameter()] - [System.String] - $MailboxRegion, + [System.Management.Automation.SwitchParameter] + $PermanentlyClearPreviousMailboxInfo, [Parameter()] [System.Object] @@ -13097,6 +13852,10 @@ function Set-User [System.Object] $WindowsEmailAddress, + [Parameter()] + [System.String] + $StreetAddress, + [Parameter()] [System.Boolean] $RemotePowerShellEnabled, @@ -13110,8 +13869,8 @@ function Set-User $GeoCoordinates, [Parameter()] - [System.String] - $StreetAddress, + [System.Object] + $OtherHomePhone, [Parameter()] [System.Object] @@ -13144,6 +13903,7 @@ function Update-RoleGroupMember ) } #endregion + #region Microsoft.Graph.Applications function Get-MgApplication { diff --git a/docs/docs/resources/exchange/EXOAuthenticationPolicyAssignment.md b/docs/docs/resources/exchange/EXOAuthenticationPolicyAssignment.md index 498c4d50bf..62a9c78606 100644 --- a/docs/docs/resources/exchange/EXOAuthenticationPolicyAssignment.md +++ b/docs/docs/resources/exchange/EXOAuthenticationPolicyAssignment.md @@ -65,33 +65,6 @@ Configuration Example ### Example 2 -```powershell -Configuration Example -{ - param( - [Parameter(Mandatory = $true)] - [PSCredential] - $Credscredential - ) - Import-DscResource -ModuleName Microsoft365DSC - - $Domain = $Credscredential.Username.Split('@')[1] - node localhost - { - EXOAuthenticationPolicyAssignment 'ConfigureAuthenticationPolicyAssignment' - { - UserName = "AdeleV@$Domain" - AuthenticationPolicyName = "Test Policy" # Updaqted Property - Ensure = "Present" - Credential = $Credscredential - } - } -} -``` - -### Example 3 - - ```powershell Configuration Example { diff --git a/docs/docs/resources/exchange/EXOCASMailboxSettings.md b/docs/docs/resources/exchange/EXOCASMailboxSettings.md index d4453b4317..ee6c197d18 100644 --- a/docs/docs/resources/exchange/EXOCASMailboxSettings.md +++ b/docs/docs/resources/exchange/EXOCASMailboxSettings.md @@ -85,6 +85,7 @@ Configuration Example Import-DscResource -ModuleName Microsoft365DSC + $Domain = $Credscredential.Username.Split('@')[1] node localhost { EXOCASMailboxSettings 'AdeleVCasMailboxSettings' @@ -93,10 +94,10 @@ Configuration Example ActiveSyncBlockedDeviceIDs = @() ActiveSyncDebugLogging = $False ActiveSyncEnabled = $True - ActiveSyncMailboxPolicy = 'Demo EXO Mobile Device Policy Default' + ActiveSyncMailboxPolicy = 'Default' ActiveSyncSuppressReadReceipt = $False EwsEnabled = $True - Identity = 'AdeleV' + Identity = "admin@$Domain" ImapEnabled = $True # Updated Property ImapForceICalForCalendarRetrievalOption = $False ImapMessagesRetrievalMimeFormat = 'BestBodyFormat' @@ -107,7 +108,7 @@ Configuration Example OutlookMobileEnabled = $True OWAEnabled = $True OWAforDevicesEnabled = $True - OwaMailboxPolicy = 'OwaMailboxPolicy-Default' + OwaMailboxPolicy = 'OwaMailboxPolicy-Integration' PopEnabled = $False PopForceICalForCalendarRetrievalOption = $True PopMessagesRetrievalMimeFormat = 'BestBodyFormat' diff --git a/docs/docs/resources/exchange/EXOCalendarProcessing.md b/docs/docs/resources/exchange/EXOCalendarProcessing.md index 39eb464dec..009995378e 100644 --- a/docs/docs/resources/exchange/EXOCalendarProcessing.md +++ b/docs/docs/resources/exchange/EXOCalendarProcessing.md @@ -117,7 +117,7 @@ Configuration Example EnforceSchedulingHorizon = $True; Ensure = "Present"; ForwardRequestsToDelegates = $True; - Identity = "AdeleV"; + Identity = "admin@$Domain"; MaximumConflictInstances = 0; MaximumDurationInMinutes = 1440; MinimumDurationInMinutes = 0; diff --git a/docs/docs/resources/exchange/EXOEmailAddressPolicy.md b/docs/docs/resources/exchange/EXOEmailAddressPolicy.md index 5fe66dd421..10e9f6b5d6 100644 --- a/docs/docs/resources/exchange/EXOEmailAddressPolicy.md +++ b/docs/docs/resources/exchange/EXOEmailAddressPolicy.md @@ -93,8 +93,8 @@ Configuration Example Name = "Integration Policy" EnabledEmailAddressTemplates = @("SMTP:@$Domain") EnabledPrimarySMTPAddressTemplate = "@$Domain" - ManagedByFilter = "" - Priority = 2 # Updated Property + ManagedByFilter = "Department -eq 'Sales'" # Updated Property + Priority = 1 Ensure = "Present" Credential = $Credscredential } diff --git a/docs/docs/resources/exchange/EXOGroupSettings.md b/docs/docs/resources/exchange/EXOGroupSettings.md index beb5db2d4f..f9ddf2d3bd 100644 --- a/docs/docs/resources/exchange/EXOGroupSettings.md +++ b/docs/docs/resources/exchange/EXOGroupSettings.md @@ -106,7 +106,7 @@ Configuration Example { EXOGroupSettings 'TestGroup' { - DisplayName = "Test Group"; + DisplayName = "All Company"; AccessType = "Public"; AlwaysSubscribeMembersToCalendarEvents = $False; AuditLogAgeLimit = "90.00:00:00"; diff --git a/docs/docs/resources/exchange/EXOMailboxAutoReplyConfiguration.md b/docs/docs/resources/exchange/EXOMailboxAutoReplyConfiguration.md index 5357252f4a..d976f09127 100644 --- a/docs/docs/resources/exchange/EXOMailboxAutoReplyConfiguration.md +++ b/docs/docs/resources/exchange/EXOMailboxAutoReplyConfiguration.md @@ -72,12 +72,12 @@ Configuration Example CreateOOFEvent = $False; Credential = $Credscredential; DeclineAllEventsForScheduledOOF = $False; - DeclineEventsForScheduledOOF = $True; # Updated Property + DeclineEventsForScheduledOOF = $False; DeclineMeetingMessage = ""; EndTime = "1/23/2024 3:00:00 PM"; Ensure = "Present"; ExternalAudience = "All"; - ExternalMessage = ""; + ExternalMessage = (New-Guid).ToString(); # Updated Property Identity = "AdeleV@$Domain"; InternalMessage = ""; OOFEventSubject = ""; diff --git a/docs/docs/resources/exchange/EXOMailboxCalendarFolder.md b/docs/docs/resources/exchange/EXOMailboxCalendarFolder.md index 1f491c98a5..cbbfc603e7 100644 --- a/docs/docs/resources/exchange/EXOMailboxCalendarFolder.md +++ b/docs/docs/resources/exchange/EXOMailboxCalendarFolder.md @@ -57,6 +57,7 @@ Configuration Example ) Import-DscResource -ModuleName Microsoft365DSC + $Domain = $Credscredential.Username.Split('@')[1] node localhost { EXOMailboxCalendarFolder "JohnCalendarFolder" @@ -64,7 +65,7 @@ Configuration Example Credential = $credsCredential; DetailLevel = "AvailabilityOnly"; Ensure = "Present"; - Identity = "AdeleV:\Calendar"; + Identity = "AlexW@$Domain" + ":\Calendar"; PublishDateRangeFrom = "ThreeMonths"; PublishDateRangeTo = "ThreeMonths"; PublishEnabled = $True; # Updated Property diff --git a/docs/docs/resources/exchange/EXOMailboxPermission.md b/docs/docs/resources/exchange/EXOMailboxPermission.md index 4fec5d4340..9e9a8da182 100644 --- a/docs/docs/resources/exchange/EXOMailboxPermission.md +++ b/docs/docs/resources/exchange/EXOMailboxPermission.md @@ -54,6 +54,7 @@ Configuration Example ) Import-DscResource -ModuleName Microsoft365DSC + $Domain = $Credscredential.Username.Split('@')[1] node localhost { EXOMailboxPermission "TestPermission" @@ -62,7 +63,7 @@ Configuration Example Credential = $credsCredential; Deny = $True; # Updated Property Ensure = "Present"; - Identity = "AdeleV"; + Identity = "AlexW@$Domain"; InheritanceType = "All"; User = "NT AUTHORITY\SELF"; } diff --git a/docs/docs/resources/exchange/EXOMailboxPlan.md b/docs/docs/resources/exchange/EXOMailboxPlan.md index a73658b8ad..a71b4df323 100644 --- a/docs/docs/resources/exchange/EXOMailboxPlan.md +++ b/docs/docs/resources/exchange/EXOMailboxPlan.md @@ -62,11 +62,11 @@ Configuration Example EXOMailboxPlan 'ConfigureMailboxPlan' { Ensure = "Present"; - Identity = "Integration Plan"; - IssueWarningQuota = "98 GB (105,226,698,752 bytes)"; + Identity = "ExchangeOnlineEssentials"; + IssueWarningQuota = "15 GB (16,106,127,360 bytes)"; MaxReceiveSize = "25 MB (26,214,400 bytes)"; MaxSendSize = "25 MB (26,214,400 bytes)"; - ProhibitSendQuota = "99 GB (106,300,440,576 bytes)"; + ProhibitSendQuota = "15 GB (16,106,127,360 bytes)"; ProhibitSendReceiveQuota = "15 GB (16,106,127,360 bytes)"; # Updated Property RetainDeletedItemsFor = "14.00:00:00"; RoleAssignmentPolicy = "Default Role Assignment Policy"; diff --git a/docs/docs/resources/exchange/EXOMailboxSettings.md b/docs/docs/resources/exchange/EXOMailboxSettings.md index 13089584c9..cefefccc2b 100644 --- a/docs/docs/resources/exchange/EXOMailboxSettings.md +++ b/docs/docs/resources/exchange/EXOMailboxSettings.md @@ -60,7 +60,7 @@ Configuration Example { EXOMailboxSettings 'OttawaTeamMailboxSettings' { - DisplayName = 'Ottawa Employees' + DisplayName = 'Conf Room Adams' TimeZone = 'Eastern Standard Time' Locale = 'en-US' # Updated Property Ensure = 'Present' diff --git a/docs/docs/resources/exchange/EXOOfflineAddressBook.md b/docs/docs/resources/exchange/EXOOfflineAddressBook.md index cdadd9da05..fa73a78e70 100644 --- a/docs/docs/resources/exchange/EXOOfflineAddressBook.md +++ b/docs/docs/resources/exchange/EXOOfflineAddressBook.md @@ -60,7 +60,7 @@ Configuration Example EXOOfflineAddressBook 'ConfigureOfflineAddressBook' { Name = "Integration Address Book" - AddressLists = @('\Offline Global Address List') + AddressLists = @('\All Users') DiffRetentionPeriod = "30" IsDefault = $true Ensure = "Present" @@ -92,8 +92,7 @@ Configuration Example EXOOfflineAddressBook 'ConfigureOfflineAddressBook' { Name = "Integration Address Book" - AddressLists = @('\Offline Global Address List') - ConfiguredAttributes = @('OfficeLocation, ANR','ProxyAddresses, ANR','PhoneticGivenName, ANR','GivenName, ANR','PhoneticSurname, ANR','Surname, ANR','Account, ANR','PhoneticDisplayName, ANR','ExternalDirectoryObjectId, Value','ExternalMemberCount, Value','TotalMemberCount, Value','ModerationEnabled, Value','MailboxGuid, Value','DelivContLength, Value','MailTipTranslations, Value','ObjectGuid, Value','DisplayTypeEx, Value','DisplayNamePrintableAnsi, Value','HomeMdbA, Value','Certificate, Value','UserSMimeCertificate, Value','UserCertificate, Value','Comment, Value','PagerTelephoneNumber, Value','AssistantTelephoneNumber, Value','MobileTelephoneNumber, Value','PrimaryFaxNumber, Value','Home2TelephoneNumberMv, Value','Business2TelephoneNumberMv, Value','HomeTelephoneNumber, Value','TargetAddress, Value','PhoneticDepartmentName, Value','DepartmentName, Value','Assistant, Value','PhoneticCompanyName, Value','CompanyName, Value','Title, Value','Country, Value','PostalCode, Value','StateOrProvince, Value','Locality, Value','StreetAddress, Value','Initials, Value','BusinessTelephoneNumber, Value','SendRichInfo, Value','ObjectType, Value','DisplayType, Value','RejectMessagesFromDLMembers, Indicator','AcceptMessagesOnlyFromDLMembers, Indicator','RejectMessagesFrom, Indicator','AcceptMessagesOnlyFrom, Indicator','UmSpokenName, Indicator','ThumbnailPhoto, Indicator') + AddressLists = @('\All Users') DiffRetentionPeriod = "30" IsDefault = $false # Updated Property Ensure = "Present" diff --git a/docs/docs/resources/exchange/EXOOnPremisesOrganization.md b/docs/docs/resources/exchange/EXOOnPremisesOrganization.md index 9a5dcd5078..c99234621e 100644 --- a/docs/docs/resources/exchange/EXOOnPremisesOrganization.md +++ b/docs/docs/resources/exchange/EXOOnPremisesOrganization.md @@ -116,13 +116,13 @@ Configuration Example { EXOOnPremisesOrganization 'ConfigureOnPremisesOrganization' { - Identity = 'Contoso' - Comment = 'Mail for Contoso. Updated' # Updated Property - HybridDomains = 'contoso.com', 'sales.contoso.com' - InboundConnector = 'Inbound to Contoso' - OrganizationGuid = 'a1bc23cb-3456-bcde-abcd-feb363cacc88' - OrganizationName = 'Contoso' - OutboundConnector = 'Outbound to Contoso' + Identity = 'Integration' + Comment = 'Mail for Contoso - Updated' #Updated Property + HybridDomains = 'o365dsc.onmicrosoft.com' + InboundConnector = 'Integration Inbound Connector' + OrganizationGuid = 'e7a80bcf-696e-40ca-8775-a7f85fbb3ebc' + OrganizationName = 'O365DSC' + OutboundConnector = 'Contoso Outbound Connector' Ensure = 'Present' Credential = $Credscredential } diff --git a/docs/docs/resources/exchange/EXOPartnerApplication.md b/docs/docs/resources/exchange/EXOPartnerApplication.md index e7830f4f35..ef140ee08c 100644 --- a/docs/docs/resources/exchange/EXOPartnerApplication.md +++ b/docs/docs/resources/exchange/EXOPartnerApplication.md @@ -61,6 +61,7 @@ Configuration Example { Name = "HRApp" ApplicationIdentifier = "00000006-0000-0dd1-ac00-000000000000" + AcceptSecurityIdentifierInformation = $true Enabled = $True Ensure = "Present" Credential = $Credscredential @@ -91,7 +92,8 @@ Configuration Example { Name = "HRApp" ApplicationIdentifier = "00000006-0000-0dd1-ac00-000000000000" - Enabled = $False # Updated Property + AcceptSecurityIdentifierInformation = $False # Updated Property + Enabled = $True Ensure = "Present" Credential = $Credscredential } diff --git a/docs/docs/resources/exchange/EXOPerimeterConfiguration.md b/docs/docs/resources/exchange/EXOPerimeterConfiguration.md index 921f997dde..3b82181618 100644 --- a/docs/docs/resources/exchange/EXOPerimeterConfiguration.md +++ b/docs/docs/resources/exchange/EXOPerimeterConfiguration.md @@ -56,7 +56,7 @@ Configuration Example EXOPerimeterConfiguration 'ConfigurePerimeterConfiguration' { IsSingleInstance = 'Yes' - GatewayIPAddresses = '123.0.0.1' + #GatewayIPAddresses = '123.0.0.1' Ensure = 'Present' Credential = $Credscredential } diff --git a/docs/docs/resources/exchange/EXOQuarantinePolicy.md b/docs/docs/resources/exchange/EXOQuarantinePolicy.md index 86ee5e75f5..c4b147b75a 100644 --- a/docs/docs/resources/exchange/EXOQuarantinePolicy.md +++ b/docs/docs/resources/exchange/EXOQuarantinePolicy.md @@ -69,7 +69,7 @@ Configuration Example { EndUserQuarantinePermissionsValue = 87; ESNEnabled = $False; - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Present" Credential = $Credscredential } @@ -100,7 +100,7 @@ Configuration Example { EndUserQuarantinePermissionsValue = 87; ESNEnabled = $True; # Updated Property - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Present" Credential = $Credscredential } @@ -129,7 +129,7 @@ Configuration Example { EXOQuarantinePolicy 'ConfigureQuarantinePolicy' { - Identity = "$Domain\DefaultFullAccessPolicy"; + Identity = "$Domain\IntegrationPolicy"; Ensure = "Absent" Credential = $Credscredential } diff --git a/docs/docs/resources/exchange/EXORecipientPermission.md b/docs/docs/resources/exchange/EXORecipientPermission.md new file mode 100644 index 0000000000..3d959b534d --- /dev/null +++ b/docs/docs/resources/exchange/EXORecipientPermission.md @@ -0,0 +1,102 @@ +# EXORecipientPermission + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **Identity** | Key | String | The mailbox the permission should be given on. | | +| **Trustee** | Key | String | The account to give the permission to. | | +| **AccessRights** | Write | StringArray[] | The access rights granted to the account. Only 'SendAs' is supported. | | +| **Ensure** | Write | String | Present ensures the group exists, absent ensures it is removed | `Present`, `Absent` | +| **Credential** | Write | PSCredential | Credentials of the Exchange Global 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. | | +| **CertificatePassword** | Write | PSCredential | Username can be made up to anything but password will be used for CertificatePassword | | +| **CertificatePath** | Write | String | Path to certificate used in service principal usually a PFX file. | | +| **ManagedIdentity** | Write | Boolean | Managed ID being used for authentication. | | + +## Description + +This resource allows users to retrieve Office 365 Recipient Permissions. + +## Permissions + +### Exchange + +To authenticate with Microsoft Exchange, this resource required the following permissions: + +#### Roles + +- Mail Enabled Public Folders, MyName, Public Folders, Compliance Admin, User Options, Message Tracking, View-Only Recipients, Role Management, Legal Hold, Audit Logs, Retention Management, Distribution Groups, Move Mailboxes, Information Rights Management, Mail Recipient Creation, Reset Password, View-Only Audit Logs, Mail Recipients, Mailbox Search, UM Mailboxes, Security Group Creation and Membership, Mailbox Import Export, MyMailboxDelegation, MyDisplayName + +#### Role Groups + +- Organization Management + +## 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(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + + Import-DscResource -ModuleName Microsoft365DSC + + $Domain = $Credscredential.Username.Split('@')[1] + node localhost + { + EXORecipientPermission 'AddSendAs' + { + Identity = "AlexW@$Domain" + Trustee = "admin@$Domain" + AccessRights = 'SendAs' + Ensure = 'Present' + Credential = $Credscredential + } + } +} +``` + +### Example 2 + +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(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + + Import-DscResource -ModuleName Microsoft365DSC + + $Domain = $Credscredential.Username.Split('@')[1] + node localhost + { + EXORecipientPermission 'AddSendAs' + { + + Identity = 'AdeleV@$Domain' + Trustee = "admin@$Domain" + Ensure = 'Absent' + Credential = $Credscredential + } + } +} +``` + diff --git a/docs/docs/resources/exchange/EXORemoteDomain.md b/docs/docs/resources/exchange/EXORemoteDomain.md index 3237473427..c3d5db54c0 100644 --- a/docs/docs/resources/exchange/EXORemoteDomain.md +++ b/docs/docs/resources/exchange/EXORemoteDomain.md @@ -132,9 +132,9 @@ Configuration Example DisplaySenderName = $True DomainName = "contoso.com" IsInternal = $False - LineWrapSize = "Integration" + LineWrapSize = "Unlimited" MeetingForwardNotificationEnabled = $False - Name = "Default" + Name = "Integration" NonMimeCharacterSet = "iso-8859-1" PreferredInternetCodePageForShiftJis = "Undefined" TargetDeliveryDomain = $False diff --git a/docs/docs/resources/exchange/EXORoleAssignmentPolicy.md b/docs/docs/resources/exchange/EXORoleAssignmentPolicy.md index 1b483a8b3b..fdfcda774f 100644 --- a/docs/docs/resources/exchange/EXORoleAssignmentPolicy.md +++ b/docs/docs/resources/exchange/EXORoleAssignmentPolicy.md @@ -87,8 +87,8 @@ Configuration Example EXORoleAssignmentPolicy 'ConfigureRoleAssignmentPolicy' { Name = "Integration Policy" - Description = "This policy grants end users the permission to set their options in Outlook on the web and perform other self-administration tasks." - IsDefault = $False # Updated Property + Description = "Updated Description" # Updated Property + IsDefault = $True Roles = @("My Marketplace Apps","MyVoiceMail","MyDistributionGroups","MyRetentionPolicies","MyContactInformation","MyBaseOptions","MyTextMessaging","MyDistributionGroupMembership","MyProfileInformation","My Custom Apps","My ReadWriteMailbox Apps") Ensure = "Present" Credential = $Credscredential diff --git a/docs/docs/resources/intune/IntuneAppConfigurationPolicy.md b/docs/docs/resources/intune/IntuneAppConfigurationPolicy.md index 4e60a0ee8f..cecb30f398 100644 --- a/docs/docs/resources/intune/IntuneAppConfigurationPolicy.md +++ b/docs/docs/resources/intune/IntuneAppConfigurationPolicy.md @@ -4,6 +4,7 @@ | Parameter | Attribute | DataType | Description | Allowed Values | | --- | --- | --- | --- | --- | +| **Id** | Write | String | Key of the entity. Read-Only. | | | **DisplayName** | Key | String | Display name of the app configuration policy. | | | **Description** | Write | String | Description of the app configuration policy. | | | **Assignments** | Write | MSFT_DeviceManagementConfigurationPolicyAssignments[] | Assignments of the Intune Policy. | | diff --git a/docs/docs/resources/intune/IntuneDeviceEnrollmentPlatformRestriction.md b/docs/docs/resources/intune/IntuneDeviceEnrollmentPlatformRestriction.md index 603b856830..cce07b5e29 100644 --- a/docs/docs/resources/intune/IntuneDeviceEnrollmentPlatformRestriction.md +++ b/docs/docs/resources/intune/IntuneDeviceEnrollmentPlatformRestriction.md @@ -17,6 +17,7 @@ | **MacRestriction** | Write | MSFT_DeviceEnrollmentPlatformRestriction | Mac restrictions based on platform, platform operating system version, and device ownership. | | | **MacOSRestriction** | Write | MSFT_DeviceEnrollmentPlatformRestriction | Mac OS restrictions based on platform, platform operating system version, and device ownership. | | | **Assignments** | Write | MSFT_DeviceManagementConfigurationPolicyAssignments[] | Assignments of the policy. | | +| **Priority** | Write | UInt32 | Priority is used when a user exists in multiple groups that are assigned enrollment configuration. Users are subject only to the configuration with the lowest priority value. Inherited from deviceEnrollmentConfiguration. | | | **Ensure** | Write | String | Present ensures the restriction exists, absent ensures it is removed. | `Present`, `Absent` | | **Credential** | Write | PSCredential | Credentials of the Intune Admin | | | **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | diff --git a/docs/docs/resources/teams/TeamsUserCallingSettings.md b/docs/docs/resources/teams/TeamsUserCallingSettings.md index 369c7b6078..4dd57c90d4 100644 --- a/docs/docs/resources/teams/TeamsUserCallingSettings.md +++ b/docs/docs/resources/teams/TeamsUserCallingSettings.md @@ -17,7 +17,10 @@ | **ForwardingTargetType** | Write | String | The forwarding target type. Supported values are Voicemail, SingleTarget, MyDelegates and Group. Voicemail is only supported for Immediate forwarding. | `Group`, `MyDelegates`, `SingleTarget`, `Voicemail` | | **ForwardingTarget** | Write | String | The forwarding target. Supported types of values are ObjectId's, SIP addresses and phone numbers. For phone numbers we support the following types of formats: E.164 (+12065551234 or +1206555000;ext=1234) or non-E.164 like 1234. | | | **Ensure** | Write | String | Present ensures the policy exists, absent ensures it is removed. | `Present`, `Absent` | -| **Credential** | Required | PSCredential | Credentials of the Teams Global Admin. | | +| **Credential** | Write | PSCredential | Credentials of the Teams Global Admin. | | +| **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | +| **TenantId** | Write | String | Name of the Azure Active Directory tenant used for authentication. Format contoso.onmicrosoft.com | | +| **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. | | diff --git a/docs/docs/user-guide/get-started/powershell7-support.md b/docs/docs/user-guide/get-started/powershell7-support.md index b060a665e9..5b699bac5b 100644 --- a/docs/docs/user-guide/get-started/powershell7-support.md +++ b/docs/docs/user-guide/get-started/powershell7-support.md @@ -25,7 +25,7 @@ To solve this, make sure the Microsoft365DSC is properly installed under C:\Prog **Issues loading the PnP.PowerShell Module** -The PnP.PowerShell module, which is currently being used by the SharePoint Online and OndeDrive for Business workloads needs to be loaded using Windows PowerShell. In PowerShell 7+, this is done by running the **Import-Module** cmdlet using the **-UseWindowsPowerShell** switch, and requires the modules to be located under C:\Program Files\WindowsPowerShell. In order for Microsoft365DSC to work for SharePoint Online and OneDrive for Business with PowerShell 7, you need to make sure that the PnP.PowerShell module is located under C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell. This can be achieve =d by either manually moving the module to that location, or by using PowerShell 5.1 to install it using the following line: +The PnP.PowerShell module, which is currently being used by the SharePoint Online and OndeDrive for Business workloads needs to be loaded using Windows PowerShell. In PowerShell 7+, this is done by running the **Import-Module** cmdlet using the **-UseWindowsPowerShell** switch, and requires the modules to be located under C:\Program Files\WindowsPowerShell. In order for Microsoft365DSC to work for SharePoint Online and OneDrive for Business with PowerShell 7, you need to make sure that the PnP.PowerShell module is located under C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell. This can be achieved by either manually moving the module to that location, or by using PowerShell 5.1 to install it using the following line: ``` Install-Module PnP.PowerShell -Force -Scope AllUsers