From a29baef061a9ffede143ffd8dab3c74c836ec135 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Thu, 5 Sep 2024 09:58:53 +0530 Subject: [PATCH 01/11] first commit --- .../MSFT_EXOMigrationEnpoint.psm1 | 425 ++++++++++++++++++ .../MSFT_EXOMigrationEnpoint.schema.mof | 13 + .../MSFT_EXOMigrationEnpoint/readme.md | 6 + .../MSFT_EXOMigrationEnpoint/settings.json | 32 ++ .../Resources/ResourceName/1-Create.ps1 | 26 ++ .../Resources/ResourceName/2-Update.ps1 | 26 ++ .../Resources/ResourceName/3-Remove.ps1 | 26 ++ .../Microsoft365DSC.ResourceName.Tests.ps1 | 176 ++++++++ 8 files changed, 730 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json create mode 100644 Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 new file mode 100644 index 0000000000..d81da06c27 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 @@ -0,0 +1,425 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + ##TODO - Replace the PrimaryKey + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $ApplicationID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, + + [Parameter()] + [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [System.String] + $EndpointType, + + [Parameter()] + [System.String] + $ExchangeServer, + + [Parameter()] + [System.String] + $MailboxPermission, + + [Parameter()] + [System.String] + $MaxConcurrentIncrementalSyncs, + + [Parameter()] + [System.String] + $MaxConcurrentMigrations, + + [Parameter()] + [System.String] + $NspiServer, + + [Parameter()] + [System.String] + $Port, + + [Parameter()] + [System.String] + $RemoteServer, + + [Parameter()] + [System.String] + $RemoteTenant, + + [Parameter()] + [System.String] + $RpcProxyServer, + + [Parameter()] + [ValidateSet('None', 'Tls', 'Ssl')] + [System.String] + $Security, + + [Parameter()] + [System.String] + $SourceMailboxLegacyDN, + + [Parameter()] + [System.String] + $UseAutoDiscover, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + ##TODO - Add the list of Parameters + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + ##TODO - Replace the workload by the one associated to your resource + New-M365DSCConnection -Workload 'Workload' ` + -InboundParameters $PSBoundParameters | Out-Null + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + try + { + if ($null -ne $Script:exportedInstances -and $Script:ExportMode) + { + ##TODO - Replace the PrimaryKey in the Filter by the one for the resource + $instance = $Script:exportedInstances | Where-Object -FilterScript {$_.PrimaryKey -eq $PrimaryKey} + } + else + { + ##TODO - Replace the cmdlet by the one to retrieve a specific instance. + $instance = Get-cmdlet -PrimaryKey $PrimaryKey -ErrorAction Stop + } + if ($null -eq $instance) + { + return $nullResult + } + + $results = @{ + ##TODO - Add the list of parameters to be returned + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + return [System.Collections.Hashtable] $results + } + catch + { + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + ##TODO - Replace the PrimaryKey + [Parameter(Mandatory = $true)] + [System.String] + $PrimaryKey, + + ##TODO - Add the list of Parameters + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentInstance = Get-TargetResource @PSBoundParameters + + $setParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + # CREATE + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + ##TODO - Replace by the New cmdlet for the resource + New-Cmdlet @SetParameters + } + # UPDATE + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + ##TODO - Replace by the Update/Set cmdlet for the resource + Set-cmdlet @SetParameters + } + # REMOVE + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + ##TODO - Replace by the Remove cmdlet for the resource + Remove-cmdlet @SetParameters + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + ##TODO - Replace the PrimaryKey + [Parameter(Mandatory = $true)] + [System.String] + $PrimaryKey, + + ##TODO - Add the list of Parameters + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + ##TODO - Replace workload + $ConnectionMode = New-M365DSCConnection -Workload 'Workload' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + $Script:ExportMode = $true + ##TODO - Replace Get-Cmdlet by the cmdlet to retrieve all instances + [array] $Script:exportedInstances = Get-Cmdlet -ErrorAction Stop + + $i = 1 + $dscContent = '' + if ($Script:exportedInstances.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $Script:exportedInstances) + { + $displayedKey = $config.Id + Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline + $params = @{ + ##TODO - Specify the Primary Key + #PrimaryKey = $config.PrimaryKey + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof new file mode 100644 index 0000000000..6fa43ce435 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof @@ -0,0 +1,13 @@ +[ClassVersion("1.0.0.0"), FriendlyName("ResourceName")] +class MSFT_ResourceName : OMI_BaseResource +{ + [Key, Description("")] String PrimaryKey; + [Write, Description("")] String OtherProperties; + + [Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; + [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; + [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; + [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; + [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; + [Write, Description("Access token used for authentication.")] String AccessTokens[]; +}; \ No newline at end of file diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md new file mode 100644 index 0000000000..32e0e7fb27 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md @@ -0,0 +1,6 @@ + +# ResourceName + +## Description + +##TODO - Provide a short description of what the resource is set to configure. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json new file mode 100644 index 0000000000..edf14b05e4 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json @@ -0,0 +1,32 @@ +{ + "resourceName": "ResourceName", + "description": "Description of what the resource is about.", + "roles": { + "read": [ + "Role" + ], + "update": [ + "Role" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [ + { + "name": "Permission for Monitoring and Export" + } + ], + "update": [ + { + "name": "Permission for deploying" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 @@ -0,0 +1,26 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 @@ -0,0 +1,26 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 @@ -0,0 +1,26 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 new file mode 100644 index 0000000000..20857e0393 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 @@ -0,0 +1,176 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + BeforeAll { + + $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force + $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) + + Mock -CommandName Confirm-M365DSCDependencies -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + ##TODO - Mock any Remove/Set/New cmdlets + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + # Test contexts + Context -Name "The instance should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return $null + Mock -CommandName Get-Cmdlet -MockWith { + return $null + } + } + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should create a new instance from the Set method' { + ##TODO - Replace the New-Cmdlet by the appropriate one + Should -Invoke -CommandName New-Cmdlet -Exactly 1 + } + } + + Context -Name "The instance exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Absent' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return an instance + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should remove the instance from the Set method' { + ##TODO - Replace the Remove-Cmdlet by the appropriate one + Should -Invoke -CommandName Remove-Cmdlet -Exactly 1 + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return the desired values + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + ##TODO - Add Parameters + Ensure = 'Present' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return a drift + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + ##TODO - Replace the Update-Cmdlet by the appropriate one + Should -Invoke -CommandName Update-Cmdlet -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return an instance + Mock -CommandName Get-Cmdlet -MockWith { + return @{ + + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope From f0101e6914fb9fcaf6248aa4c05a53aa23c5f9b8 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Thu, 3 Oct 2024 12:25:55 +0530 Subject: [PATCH 02/11] added the logic, examples and tests --- .../MSFT_EXOMigrationEndpoint.psm1} | 256 +++++++++++++--- .../MSFT_EXOMigrationEndpoint.schema.mof | 30 ++ .../MSFT_EXOMigrationEndpoint/readme.md | 6 + .../MSFT_EXOMigrationEndpoint/settings.json | 34 +++ .../MSFT_EXOMigrationEnpoint.schema.mof | 13 - .../MSFT_EXOMigrationEnpoint/readme.md | 6 - .../MSFT_EXOMigrationEnpoint/settings.json | 32 -- .../1-Create.ps1 | 0 .../EXOMigrationEndpoint/2-Update.ps1 | 42 +++ .../EXOMigrationEndpoint/3-Remove.ps1 | 40 +++ .../Resources/ResourceName/2-Update.ps1 | 26 -- .../Resources/ResourceName/3-Remove.ps1 | 26 -- ...osoft365DSC.EXOMigrationEndpoint.Tests.ps1 | 253 ++++++++++++++++ .../Microsoft365DSC.ResourceName.Tests.ps1 | 176 ----------- Tests/Unit/Stubs/Microsoft365.psm1 | 276 ++++++++++++++++++ 15 files changed, 898 insertions(+), 318 deletions(-) rename Modules/Microsoft365DSC/DSCResources/{MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 => MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1} (58%) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/settings.json delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json rename Modules/Microsoft365DSC/Examples/Resources/{ResourceName => EXOMigrationEndpoint}/1-Create.ps1 (100%) create mode 100644 Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 create mode 100644 Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 delete mode 100644 Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 delete mode 100644 Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMigrationEndpoint.Tests.ps1 delete mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 similarity index 58% rename from Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 rename to Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 index d81da06c27..2898ab3ac5 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 @@ -4,7 +4,6 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( - ##TODO - Replace the PrimaryKey [Parameter(Mandatory = $true)] [System.String] $Identity, @@ -15,7 +14,7 @@ function Get-TargetResource [Parameter()] [System.String] - $ApplicationID, + $AppID, [Parameter()] [System.String] @@ -84,8 +83,6 @@ function Get-TargetResource [System.String] $Ensure = 'Present', - ##TODO - Add the list of Parameters - [Parameter()] [System.Management.Automation.PSCredential] $Credential, @@ -111,8 +108,7 @@ function Get-TargetResource $AccessTokens ) - ##TODO - Replace the workload by the one associated to your resource - New-M365DSCConnection -Workload 'Workload' ` + New-M365DSCConnection -Workload 'ExchangeOnline' ` -InboundParameters $PSBoundParameters | Out-Null #Ensure the proper dependencies are installed in the current environment. @@ -133,29 +129,45 @@ function Get-TargetResource { if ($null -ne $Script:exportedInstances -and $Script:ExportMode) { - ##TODO - Replace the PrimaryKey in the Filter by the one for the resource - $instance = $Script:exportedInstances | Where-Object -FilterScript {$_.PrimaryKey -eq $PrimaryKey} + $migrationEndpoint = $Script:exportedInstances | Where-Object -FilterScript {$_.Identity -eq $Identity} } else { - ##TODO - Replace the cmdlet by the one to retrieve a specific instance. - $instance = Get-cmdlet -PrimaryKey $PrimaryKey -ErrorAction Stop + $migrationEndpoint = Get-MigrationEndpoint -Identity $Identity -ErrorAction Stop } - if ($null -eq $instance) + if ($null -eq $migrationEndpoint) { return $nullResult } $results = @{ - ##TODO - Add the list of parameters to be returned - Ensure = 'Present' - Credential = $Credential - ApplicationId = $ApplicationId - TenantId = $TenantId - CertificateThumbprint = $CertificateThumbprint - ManagedIdentity = $ManagedIdentity.IsPresent - AccessTokens = $AccessTokens + Identity = $Identity + AcceptUntrustedCertificates = $migrationEndpoint.AcceptUntrustedCertificates + AppID = $migrationEndpoint.AppID + AppSecretKeyVaultUrl = $migrationEndpoint.AppSecretKeyVaultUrl + Authentication = $migrationEndpoint.Authentication + EndpointType = $migrationEndpoint.EndpointType + ExchangeServer = $migrationEndpoint.ExchangeServer + MailboxPermission = $migrationEndpoint.MailboxPermission + MaxConcurrentIncrementalSyncs = $migrationEndpoint.MaxConcurrentIncrementalSyncs + MaxConcurrentMigrations = $migrationEndpoint.MaxConcurrentMigrations + NspiServer = $migrationEndpoint.NspiServer + Port = $migrationEndpoint.Port + RemoteServer = $migrationEndpoint.RemoteServer + RemoteTenant = $migrationEndpoint.RemoteTenant + RpcProxyServer = $migrationEndpoint.RpcProxyServer + Security = $migrationEndpoint.Security + SourceMailboxLegacyDN = $migrationEndpoint.SourceMailboxLegacyDN + UseAutoDiscover = $migrationEndpoint.UseAutoDiscover + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens } + return [System.Collections.Hashtable] $results } catch @@ -175,12 +187,84 @@ function Set-TargetResource [CmdletBinding()] param ( - ##TODO - Replace the PrimaryKey [Parameter(Mandatory = $true)] [System.String] - $PrimaryKey, + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $AppID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, + + [Parameter()] + [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [System.String] + $EndpointType, + + [Parameter()] + [System.String] + $ExchangeServer, + + [Parameter()] + [System.String] + $MailboxPermission, + + [Parameter()] + [System.String] + $MaxConcurrentIncrementalSyncs, + + [Parameter()] + [System.String] + $MaxConcurrentMigrations, + + [Parameter()] + [System.String] + $NspiServer, + + [Parameter()] + [System.String] + $Port, + + [Parameter()] + [System.String] + $RemoteServer, + + [Parameter()] + [System.String] + $RemoteTenant, - ##TODO - Add the list of Parameters + [Parameter()] + [System.String] + $RpcProxyServer, + + [Parameter()] + [ValidateSet('None', 'Tls', 'Ssl')] + [System.String] + $Security, + + [Parameter()] + [System.String] + $SourceMailboxLegacyDN, + + [Parameter()] + [System.String] + $UseAutoDiscover, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', [Parameter()] [System.Management.Automation.PSCredential] @@ -221,25 +305,50 @@ function Set-TargetResource $currentInstance = Get-TargetResource @PSBoundParameters - $setParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + $setParams = [System.Collections.Hashtable]($PSBoundParameters) + $setParams = Remove-M365DSCAuthenticationParameter -BoundParameters $setParams + $setParams.Remove('RemoteTenant') + $setParams.Remove('EndpointType') + $setParams.Remove('UseAutoDiscover') + $setParams.Add('Confirm', $false) + + $newParams = [System.Collections.Hashtable]($PSBoundParameters) + $newParams = Remove-M365DSCAuthenticationParameter -BoundParameters $newParams + $newParams.Remove('EndpointType') + $newParams.Remove('Identity') + $newParams.Add('Name', $Identity) + $newParams.Add('Confirm', [Switch]$false) + + if ($EndpointType -eq "IMAP") + { + # Removing mailbox permission parameter as this is valid only for outlook anywhere migration + $setParams.Remove('MailboxPermission') + $newParams.Remove('MailboxPermission') + + # adding skip verification switch to skip verifying + # that the remote server is reachable when creating a migration endpoint. + $setParams.Add('SkipVerification', [Switch]$true) + $newParams.Add('SkipVerification', [Switch]$true) + + $newParams.Add('IMAP', [Switch]$true) + } + + # add the logic for other endpoint types ('Exchange Remote', 'Outlook Anywhere', 'Google Workspace') # CREATE if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { - ##TODO - Replace by the New cmdlet for the resource - New-Cmdlet @SetParameters + New-MigrationEndpoint @newParams } # UPDATE elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { - ##TODO - Replace by the Update/Set cmdlet for the resource - Set-cmdlet @SetParameters + Set-MigrationEndpoint @setParams } # REMOVE elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { - ##TODO - Replace by the Remove cmdlet for the resource - Remove-cmdlet @SetParameters + Remove-MigrationEndpoint -Identity $Identity } } @@ -249,12 +358,84 @@ function Test-TargetResource [OutputType([System.Boolean])] param ( - ##TODO - Replace the PrimaryKey [Parameter(Mandatory = $true)] [System.String] - $PrimaryKey, + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $AppID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, - ##TODO - Add the list of Parameters + [Parameter()] + [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [System.String] + $EndpointType, + + [Parameter()] + [System.String] + $ExchangeServer, + + [Parameter()] + [System.String] + $MailboxPermission, + + [Parameter()] + [System.String] + $MaxConcurrentIncrementalSyncs, + + [Parameter()] + [System.String] + $MaxConcurrentMigrations, + + [Parameter()] + [System.String] + $NspiServer, + + [Parameter()] + [System.String] + $Port, + + [Parameter()] + [System.String] + $RemoteServer, + + [Parameter()] + [System.String] + $RemoteTenant, + + [Parameter()] + [System.String] + $RpcProxyServer, + + [Parameter()] + [ValidateSet('None', 'Tls', 'Ssl')] + [System.String] + $Security, + + [Parameter()] + [System.String] + $SourceMailboxLegacyDN, + + [Parameter()] + [System.String] + $UseAutoDiscover, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', [Parameter()] [System.Management.Automation.PSCredential] @@ -344,8 +525,7 @@ function Export-TargetResource $AccessTokens ) - ##TODO - Replace workload - $ConnectionMode = New-M365DSCConnection -Workload 'Workload' ` + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` -InboundParameters $PSBoundParameters #Ensure the proper dependencies are installed in the current environment. @@ -363,8 +543,7 @@ function Export-TargetResource try { $Script:ExportMode = $true - ##TODO - Replace Get-Cmdlet by the cmdlet to retrieve all instances - [array] $Script:exportedInstances = Get-Cmdlet -ErrorAction Stop + [array] $Script:exportedInstances = Get-MigrationEndpoint -ErrorAction Stop $i = 1 $dscContent = '' @@ -378,11 +557,10 @@ function Export-TargetResource } foreach ($config in $Script:exportedInstances) { - $displayedKey = $config.Id + $displayedKey = $config.Identity Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline $params = @{ - ##TODO - Specify the Primary Key - #PrimaryKey = $config.PrimaryKey + Identity = $config.Identity Credential = $Credential ApplicationId = $ApplicationId TenantId = $TenantId diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof new file mode 100644 index 0000000000..8848a16f25 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof @@ -0,0 +1,30 @@ +[ClassVersion("1.0.0.0"), FriendlyName("EXOMigrationEndpoint")] +class MSFT_EXOMigrationEndpoint : OMI_BaseResource +{ + [Key, Description("Identity of the migration endpoint.")] String Identity; + [Write, Description("Specifies whether to accept untrusted certificates.")] Boolean AcceptUntrustedCertificates; + [Write, Description("The Application ID used for authentication.")] String AppID; + [Write, Description("The URL of the Key Vault that stores the application secret.")] String AppSecretKeyVaultUrl; + [Write, Description("The authentication method for the migration endpoint.")] String Authentication; + [Write, Description("The type of migration endpoint."), ValueMap{"Exchange Remote", "Outlook Anywhere", "Google Workspace", "IMAP"}, Values{"Exchange Remote", "Outlook Anywhere", "Google Workspace", "IMAP"}] String EndpointType; + [Write, Description("The Exchange Server address for the migration endpoint.")] String ExchangeServer; + [Write, Description("The mailbox permission for the migration endpoint.")] String MailboxPermission; + [Write, Description("The maximum number of concurrent incremental syncs.")] String MaxConcurrentIncrementalSyncs; + [Write, Description("The maximum number of concurrent migrations.")] String MaxConcurrentMigrations; + [Write, Description("The NSPI server for the migration endpoint.")] String NspiServer; + [Write, Description("The port number for the migration endpoint.")] String Port; + [Write, Description("The remote server for the migration endpoint.")] String RemoteServer; + [Write, Description("The remote tenant for the migration endpoint.")] String RemoteTenant; + [Write, Description("The RPC proxy server for the migration endpoint.")] String RpcProxyServer; + [Write, Description("The security level for the migration endpoint."), ValueMap{"None", "Tls", "Ssl"}, Values{"None", "Tls", "Ssl"}] String Security; + [Write, Description("The legacy distinguished name of the source mailbox.")] String SourceMailboxLegacyDN; + [Write, Description("Specifies whether to use AutoDiscover.")] Boolean UseAutoDiscover; + + [Write, Description("Specifies if the migration endpoint should exist or not."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; + [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; + [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; + [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; + [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; + [Write, Description("Access token used for authentication.")] String AccessTokens[]; +}; diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/readme.md new file mode 100644 index 0000000000..a5d359017c --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/readme.md @@ -0,0 +1,6 @@ + +# EXOMigrationEndpoint + +## Description + +Use this resource to create and monitor migration endpoints in exchange. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/settings.json new file mode 100644 index 0000000000..d223f925cd --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/settings.json @@ -0,0 +1,34 @@ +{ + "resourceName": "EXOMigrationEndpoint", + "description": "Use this resource to create and monitor migration endpoint in exchange", + "roles": { + "read": [ + "Global Reader" + ], + "update": [ + "Exchange Administrator" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [], + "update": [] + } + }, + "exchange": { + "requiredroles": [ + "Recipient Policies", + "View-Only Recipients", + "Mail Recipient Creation", + "View-Only Configuration", + "Mail Recipients" + ], + "requiredrolegroups": "Organization Management" + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof deleted file mode 100644 index 6fa43ce435..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/MSFT_EXOMigrationEnpoint.schema.mof +++ /dev/null @@ -1,13 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("ResourceName")] -class MSFT_ResourceName : OMI_BaseResource -{ - [Key, Description("")] String PrimaryKey; - [Write, Description("")] String OtherProperties; - - [Write, Description("Credentials of the workload's Admin"), EmbeddedInstance("MSFT_Credential")] string Credential; - [Write, Description("Id of the Azure Active Directory application to authenticate with.")] String ApplicationId; - [Write, Description("Id of the Azure Active Directory tenant used for authentication.")] String TenantId; - [Write, Description("Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication.")] String CertificateThumbprint; - [Write, Description("Managed ID being used for authentication.")] Boolean ManagedIdentity; - [Write, Description("Access token used for authentication.")] String AccessTokens[]; -}; \ No newline at end of file diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md deleted file mode 100644 index 32e0e7fb27..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/readme.md +++ /dev/null @@ -1,6 +0,0 @@ - -# ResourceName - -## Description - -##TODO - Provide a short description of what the resource is set to configure. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json deleted file mode 100644 index edf14b05e4..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEnpoint/settings.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "resourceName": "ResourceName", - "description": "Description of what the resource is about.", - "roles": { - "read": [ - "Role" - ], - "update": [ - "Role" - ] - }, - "permissions": { - "graph": { - "delegated": { - "read": [], - "update": [] - }, - "application": { - "read": [ - { - "name": "Permission for Monitoring and Export" - } - ], - "update": [ - { - "name": "Permission for deploying" - } - ] - } - } - } -} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 similarity index 100% rename from Modules/Microsoft365DSC/Examples/Resources/ResourceName/1-Create.ps1 rename to Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 new file mode 100644 index 0000000000..4ec28ef8fc --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 @@ -0,0 +1,42 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + Credential = $Credscredential; + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + # value for security updated from Tls to None + Security = "None"; + } + + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 new file mode 100644 index 0000000000..9ac7745bec --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 @@ -0,0 +1,40 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + Credential = $Credscredential; + EndpointType = "IMAP"; + Ensure = "Absent"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "None"; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 deleted file mode 100644 index b516274848..0000000000 --- a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/2-Update.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -<# -This example is used to test new resources and showcase the usage of new resources being worked on. -It is not meant to use as a production baseline. -#> - -Configuration Example -{ - param( - [Parameter()] - [System.String] - $ApplicationId, - - [Parameter()] - [System.String] - $TenantId, - - [Parameter()] - [System.String] - $CertificateThumbprint - ) - Import-DscResource -ModuleName Microsoft365DSC - node localhost - { - - } -} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 deleted file mode 100644 index b516274848..0000000000 --- a/Modules/Microsoft365DSC/Examples/Resources/ResourceName/3-Remove.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -<# -This example is used to test new resources and showcase the usage of new resources being worked on. -It is not meant to use as a production baseline. -#> - -Configuration Example -{ - param( - [Parameter()] - [System.String] - $ApplicationId, - - [Parameter()] - [System.String] - $TenantId, - - [Parameter()] - [System.String] - $CertificateThumbprint - ) - Import-DscResource -ModuleName Microsoft365DSC - node localhost - { - - } -} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMigrationEndpoint.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMigrationEndpoint.Tests.ps1 new file mode 100644 index 0000000000..1afff8ab03 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMigrationEndpoint.Tests.ps1 @@ -0,0 +1,253 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + BeforeAll { + + $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force + $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) + + Mock -CommandName Confirm-M365DSCDependencies -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + } + + Mock -CommandName Set-MigrationEndpoint -MockWith { + } + + Mock -CommandName New-MigrationEndpoint -MockWith { + } + + Mock -CommandName Remove-MigrationEndpoint -MockWith { + } + + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + # Test contexts + Context -Name "The instance should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + return $null + } + } + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should create a new instance from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName New-MigrationEndpoint -Exactly 1 + } + } + + Context -Name "The instance exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + Ensure = 'Absent' + Credential = $Credential; + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + return @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } + } + } + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should remove the instance from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Remove-MigrationEndpoint -Exactly 1 + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + return @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The instance exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + return @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "None"; + } + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Set-MigrationEndpoint -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Get-MigrationEndpoint -MockWith { + return @{ + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + EndpointType = "IMAP"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } + } + } + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 deleted file mode 100644 index 20857e0393..0000000000 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ResourceName.Tests.ps1 +++ /dev/null @@ -1,176 +0,0 @@ -[CmdletBinding()] -param( -) -$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` - -ChildPath '..\..\Unit' ` - -Resolve -$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\Stubs\Microsoft365.psm1' ` - -Resolve) -$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\Stubs\Generic.psm1' ` - -Resolve) -Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\UnitTestHelper.psm1' ` - -Resolve) - -$CurrentScriptPath = $PSCommandPath.Split('\') -$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] -$ResourceName = $CurrentScriptName.Split('.')[1] -$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` - -DscResource $ResourceName -GenericStubModule $GenericStubPath - -Describe -Name $Global:DscHelper.DescribeHeader -Fixture { - InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { - Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope - BeforeAll { - - $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force - $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) - - Mock -CommandName Confirm-M365DSCDependencies -MockWith { - } - - Mock -CommandName New-M365DSCConnection -MockWith { - return "Credentials" - } - - ##TODO - Mock any Remove/Set/New cmdlets - - # Mock Write-Host to hide output during the tests - Mock -CommandName Write-Host -MockWith { - } - $Script:exportedInstances =$null - $Script:ExportMode = $false - } - # Test contexts - Context -Name "The instance should exist but it DOES NOT" -Fixture { - BeforeAll { - $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; - } - - ##TODO - Mock the Get-Cmdlet to return $null - Mock -CommandName Get-Cmdlet -MockWith { - return $null - } - } - It 'Should return Values from the Get method' { - (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' - } - It 'Should return false from the Test method' { - Test-TargetResource @testParams | Should -Be $false - } - - It 'Should create a new instance from the Set method' { - ##TODO - Replace the New-Cmdlet by the appropriate one - Should -Invoke -CommandName New-Cmdlet -Exactly 1 - } - } - - Context -Name "The instance exists but it SHOULD NOT" -Fixture { - BeforeAll { - $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Absent' - Credential = $Credential; - } - - ##TODO - Mock the Get-Cmdlet to return an instance - Mock -CommandName Get-Cmdlet -MockWith { - return @{ - - } - } - } - It 'Should return Values from the Get method' { - (Get-TargetResource @testParams).Ensure | Should -Be 'Present' - } - It 'Should return false from the Test method' { - Test-TargetResource @testParams | Should -Be $false - } - - It 'Should remove the instance from the Set method' { - ##TODO - Replace the Remove-Cmdlet by the appropriate one - Should -Invoke -CommandName Remove-Cmdlet -Exactly 1 - } - } - - Context -Name "The instance exists and values are already in the desired state" -Fixture { - BeforeAll { - $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; - } - - ##TODO - Mock the Get-Cmdlet to return the desired values - Mock -CommandName Get-Cmdlet -MockWith { - return @{ - - } - } - } - - It 'Should return true from the Test method' { - Test-TargetResource @testParams | Should -Be $true - } - } - - Context -Name "The instance exists and values are NOT in the desired state" -Fixture { - BeforeAll { - $testParams = @{ - ##TODO - Add Parameters - Ensure = 'Present' - Credential = $Credential; - } - - ##TODO - Mock the Get-Cmdlet to return a drift - Mock -CommandName Get-Cmdlet -MockWith { - return @{ - - } - } - } - - It 'Should return Values from the Get method' { - (Get-TargetResource @testParams).Ensure | Should -Be 'Present' - } - - It 'Should return false from the Test method' { - Test-TargetResource @testParams | Should -Be $false - } - - It 'Should call the Set method' { - Set-TargetResource @testParams - ##TODO - Replace the Update-Cmdlet by the appropriate one - Should -Invoke -CommandName Update-Cmdlet -Exactly 1 - } - } - - Context -Name 'ReverseDSC Tests' -Fixture { - BeforeAll { - $Global:CurrentModeIsExport = $true - $Global:PartialExportFileName = "$(New-Guid).partial.ps1" - $testParams = @{ - Credential = $Credential; - } - - ##TODO - Mock the Get-Cmdlet to return an instance - Mock -CommandName Get-Cmdlet -MockWith { - return @{ - - } - } - } - 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 d8d8db6694..a60f853733 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -1405,6 +1405,282 @@ function Remove-MgBetaRoleManagementEntitlementManagementRoleAssignment ) } +function Get-MigrationEndpoint +{ + [CmdletBinding()] + param( + [Parameter()] + [System.String] + $DiagnosticInfo, + + [Parameter()] + [System.Object] + $Type, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $Partition + ) +} + +function Set-MigrationEndpoint +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.Object] + $MaxConcurrentMigrations, + + [Parameter()] + [System.Byte[]] + $ServiceAccountKeyFileData, + + [Parameter()] + [System.Object] + $TestMailbox, + + [Parameter()] + [System.String] + $ExchangeServer, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipVerification, + + [Parameter()] + [System.Object] + $Authentication, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.Object] + $Port, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.Object] + $RemoteServer, + + [Parameter()] + [System.Object] + $Partition, + + [Parameter()] + [System.Object] + $MailboxPermission, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.String] + $SourceMailboxLegacyDN, + + [Parameter()] + [System.String] + $NspiServer, + + [Parameter()] + [System.Object] + $RPCProxyServer, + + [Parameter()] + [System.String] + $PublicFolderDatabaseServerLegacyDN, + + [Parameter()] + [System.Object] + $Security, + + [Parameter()] + [System.Object] + $MaxConcurrentIncrementalSyncs, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credentials + ) +} + +function New-MigrationEndpoint +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $Name, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ExchangeRemoteMove, + + [Parameter()] + [System.Object] + $MaxConcurrentMigrations, + + [Parameter()] + [System.Byte[]] + $ServiceAccountKeyFileData, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PublicFolder, + + [Parameter()] + [System.Object] + $TestMailbox, + + [Parameter()] + [System.String] + $ExchangeServer, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $SkipVerification, + + [Parameter()] + [System.Object] + $Authentication, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ExchangeOutlookAnywhere, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Gmail, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Compliance, + + [Parameter()] + [System.Int32] + $Port, + + [Parameter()] + [System.Security.SecureString] + $OAuthCode, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.Object] + $RemoteServer, + + [Parameter()] + [System.Object] + $Partition, + + [Parameter()] + [System.Object] + $MailboxPermission, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.String] + $SourceMailboxLegacyDN, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IMAP, + + [Parameter()] + [System.String] + $RemoteTenant, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PublicFolderToUnifiedGroup, + + [Parameter()] + [System.String] + $NspiServer, + + [Parameter()] + [System.String] + $RedirectUri, + + [Parameter()] + [System.Object] + $RPCProxyServer, + + [Parameter()] + [System.Object] + $EmailAddress, + + [Parameter()] + [System.Object] + $Security, + + [Parameter()] + [System.Object] + $MaxConcurrentIncrementalSyncs, + + [Parameter()] + [System.String] + $PublicFolderDatabaseServerLegacyDN, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Autodiscover + ) +} + +function Remove-MigrationEndpoint +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $Partition + ) +} + function Set-ManagementRoleEntry { [CmdletBinding()] From 2f4f0bb760e3ea1f58fc5d0277df08db66eb0888 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Thu, 3 Oct 2024 12:28:36 +0530 Subject: [PATCH 03/11] updated changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2196377267..95054c78ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log for Microsoft365DSC +# Unreleased + +* EXOMigrationEndpoint + * Initial Release + # 1.24.1002.1 * AADAdministrativeUnit From 9cc1a46dc4aa93beef4dc95f7b30c4f0658604d7 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Fri, 4 Oct 2024 09:46:25 +0530 Subject: [PATCH 04/11] minor --- .../MSFT_EXOMigrationEndpoint.psm1 | 6 +++--- .../MSFT_EXOMigrationEndpoint.schema.mof | 2 +- .../Resources/EXOMigrationEndpoint/1-Create.ps1 | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 index 2898ab3ac5..8e8ef54b1a 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 @@ -25,7 +25,7 @@ function Get-TargetResource $Authentication, [Parameter()] - [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [ValidateSet('IMAP')] [System.String] $EndpointType, @@ -208,7 +208,7 @@ function Set-TargetResource $Authentication, [Parameter()] - [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [ValidateSet('IMAP')] [System.String] $EndpointType, @@ -379,7 +379,7 @@ function Test-TargetResource $Authentication, [Parameter()] - [ValidateSet('Exchange Remote', 'Outlook Anywhere', 'Google Workspace', 'IMAP')] + [ValidateSet('IMAP')] [System.String] $EndpointType, diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof index 8848a16f25..6f6e4c9692 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof @@ -6,7 +6,7 @@ class MSFT_EXOMigrationEndpoint : OMI_BaseResource [Write, Description("The Application ID used for authentication.")] String AppID; [Write, Description("The URL of the Key Vault that stores the application secret.")] String AppSecretKeyVaultUrl; [Write, Description("The authentication method for the migration endpoint.")] String Authentication; - [Write, Description("The type of migration endpoint."), ValueMap{"Exchange Remote", "Outlook Anywhere", "Google Workspace", "IMAP"}, Values{"Exchange Remote", "Outlook Anywhere", "Google Workspace", "IMAP"}] String EndpointType; + [Write, Description("The type of migration endpoint."), ValueMap{"IMAP"}, Values{"IMAP"}] String EndpointType; [Write, Description("The Exchange Server address for the migration endpoint.")] String ExchangeServer; [Write, Description("The mailbox permission for the migration endpoint.")] String MailboxPermission; [Write, Description("The maximum number of concurrent incremental syncs.")] String MaxConcurrentIncrementalSyncs; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 index b516274848..e96d8c8010 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 @@ -21,6 +21,20 @@ Configuration Example Import-DscResource -ModuleName Microsoft365DSC node localhost { - + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + Credential = $Credscredential; + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } } } From 17c7d1f7a35967846c24600aad466e1bd8980be3 Mon Sep 17 00:00:00 2001 From: Piyush Dubey Date: Fri, 4 Oct 2024 20:10:19 +0530 Subject: [PATCH 05/11] minor --- .../EXOMailboxFolderPermission/1-Create.ps1 | 10 ++++++---- .../EXOMailboxFolderPermission/2-Update.ps1 | 10 ++++++---- .../Resources/EXOMailboxIRMAccess/1-Create.ps1 | 12 +++++++----- .../{2-Update.ps1 => 2-Remove.ps1} | 11 ++++++++++- .../Resources/EXOManagementScope/1-Create.ps1 | 4 +++- .../Resources/EXOManagementScope/2-Update.ps1 | 4 +++- .../Resources/EXOManagementScope/3-Remove.ps1 | 4 +++- .../Resources/EXOMigrationEndpoint/1-Create.ps1 | 4 +++- .../Resources/EXOMigrationEndpoint/2-Update.ps1 | 5 +++-- .../Resources/EXOMigrationEndpoint/3-Remove.ps1 | 4 +++- 10 files changed, 47 insertions(+), 21 deletions(-) rename Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/{2-Update.ps1 => 2-Remove.ps1} (50%) diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/1-Create.ps1 index 512a22ca2a..30d854debf 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/1-Create.ps1 @@ -25,10 +25,12 @@ Configuration Example { EXOMailboxFolderPermission "EXOMailboxFolderPermission-admin:\Calendar" { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "amdin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "amdin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/2-Update.ps1 index 22c39789c9..53f644e60e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxFolderPermission/2-Update.ps1 @@ -23,10 +23,12 @@ Configuration Example { EXOMailboxFolderPermission "EXOMailboxFolderPermission-admin:\Calendar" { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "admin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "admin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 index f47d2d2105..224ba6554e 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 @@ -23,11 +23,13 @@ Configuration Example { EXOMailboxIRMAccess "EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com" { - AccessLevel = "Block"; - Credential = $Credscredential; - Ensure = "Present"; - Identity = "qwe@$OrganizationName"; - User = "admin@$OrganizationName"; + AccessLevel = "Block"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "qwe@$OrganizationName"; + User = "admin@$OrganizationName"; } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Remove.ps1 similarity index 50% rename from Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Update.ps1 rename to Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Remove.ps1 index b516274848..e57be7daf4 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/2-Remove.ps1 @@ -21,6 +21,15 @@ Configuration Example Import-DscResource -ModuleName Microsoft365DSC node localhost { - + EXOMailboxIRMAccess "EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com" + { + AccessLevel = "Block"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Absent"; + Identity = "qwe@$OrganizationName"; + User = "admin@$OrganizationName"; + } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/1-Create.ps1 index ba630d844a..e583a1d42c 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/1-Create.ps1 @@ -25,7 +25,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/2-Update.ps1 index 64528717e8..8ceabe1be9 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/2-Update.ps1 @@ -23,7 +23,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/3-Remove.ps1 index 3524dc103d..1b2e95e5af 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/3-Remove.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOManagementScope/3-Remove.ps1 @@ -23,7 +23,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Absent"; Exclusive = $False; Identity = "Test New DGs"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 index e96d8c8010..58211df214 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.ps1 @@ -25,7 +25,9 @@ Configuration Example { AcceptUntrustedCertificates = $True; Authentication = "Basic"; - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint EndpointType = "IMAP"; Ensure = "Present"; Identity = "testIMAP"; diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 index 4ec28ef8fc..85ec1ba902 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 @@ -25,7 +25,9 @@ Configuration Example { AcceptUntrustedCertificates = $True; Authentication = "Basic"; - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint EndpointType = "IMAP"; Ensure = "Present"; Identity = "testIMAP"; @@ -37,6 +39,5 @@ Configuration Example # value for security updated from Tls to None Security = "None"; } - } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 index 9ac7745bec..e1e47e2730 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.ps1 @@ -25,7 +25,9 @@ Configuration Example { AcceptUntrustedCertificates = $True; Authentication = "Basic"; - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint EndpointType = "IMAP"; Ensure = "Absent"; Identity = "testIMAP"; From 49230ce21aa5b91637e4adac01c27dc285ee5274 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Fri, 4 Oct 2024 20:19:31 +0000 Subject: [PATCH 06/11] Updated Schema Definition --- Modules/Microsoft365DSC/SchemaDefinition.json | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index 86844fd218..39930e9bbd 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -5914,6 +5914,91 @@ } ] }, + { + "ClassName": "MSFT_ADOPermission", + "Parameters": [ + { + "CIMType": "String", + "Name": "NamespaceId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "DisplayName", + "Option": "Write" + }, + { + "CIMType": "UInt32", + "Name": "Bit", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Token", + "Option": "Write" + } + ] + }, + { + "ClassName": "MSFT_ADOPermissionGroupSettings", + "Parameters": [ + { + "CIMType": "String", + "Name": "GroupName", + "Option": "Key" + }, + { + "CIMType": "String", + "Name": "OrganizationName", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Descriptor", + "Option": "Write" + }, + { + "CIMType": "MSFT_ADOPermission[]", + "Name": "AllowPermissions", + "Option": "Write" + }, + { + "CIMType": "MSFT_ADOPermission[]", + "Name": "DenyPermissions", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_ADOSecurityPolicy", "Parameters": [ From 8cb209d5432f0ab1fabc8077f98891c1c0165e39 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Sat, 5 Oct 2024 19:35:25 +0000 Subject: [PATCH 07/11] Updated Resources and Cmdlet documentation pages --- .../exchange/EXOMailboxFolderPermission.md | 20 +- .../resources/exchange/EXOMailboxIRMAccess.md | 23 ++- .../resources/exchange/EXOManagementScope.md | 12 +- .../exchange/EXOMigrationEndpoint.md | 189 ++++++++++++++++++ 4 files changed, 227 insertions(+), 17 deletions(-) create mode 100644 docs/docs/resources/exchange/EXOMigrationEndpoint.md diff --git a/docs/docs/resources/exchange/EXOMailboxFolderPermission.md b/docs/docs/resources/exchange/EXOMailboxFolderPermission.md index e73479bb40..41176e7e58 100644 --- a/docs/docs/resources/exchange/EXOMailboxFolderPermission.md +++ b/docs/docs/resources/exchange/EXOMailboxFolderPermission.md @@ -75,10 +75,12 @@ Configuration Example { EXOMailboxFolderPermission "EXOMailboxFolderPermission-admin:\Calendar" { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "amdin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "amdin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } @@ -123,10 +125,12 @@ Configuration Example { EXOMailboxFolderPermission "EXOMailboxFolderPermission-admin:\Calendar" { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "admin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "admin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } diff --git a/docs/docs/resources/exchange/EXOMailboxIRMAccess.md b/docs/docs/resources/exchange/EXOMailboxIRMAccess.md index d349b97793..280d5c2b7d 100644 --- a/docs/docs/resources/exchange/EXOMailboxIRMAccess.md +++ b/docs/docs/resources/exchange/EXOMailboxIRMAccess.md @@ -62,11 +62,13 @@ Configuration Example { EXOMailboxIRMAccess "EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com" { - AccessLevel = "Block"; - Credential = $Credscredential; - Ensure = "Present"; - Identity = "qwe@$OrganizationName"; - User = "admin@$OrganizationName"; + AccessLevel = "Block"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "qwe@$OrganizationName"; + User = "admin@$OrganizationName"; } } } @@ -96,7 +98,16 @@ Configuration Example Import-DscResource -ModuleName Microsoft365DSC node localhost { - + EXOMailboxIRMAccess "EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com" + { + AccessLevel = "Block"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Absent"; + Identity = "qwe@$OrganizationName"; + User = "admin@$OrganizationName"; + } } } ``` diff --git a/docs/docs/resources/exchange/EXOManagementScope.md b/docs/docs/resources/exchange/EXOManagementScope.md index 873248793d..ab66d2b4c3 100644 --- a/docs/docs/resources/exchange/EXOManagementScope.md +++ b/docs/docs/resources/exchange/EXOManagementScope.md @@ -66,7 +66,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; @@ -103,7 +105,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; @@ -140,7 +144,9 @@ Configuration Example { EXOManagementScope "EXOManagementScope-Test New DGs" { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Absent"; Exclusive = $False; Identity = "Test New DGs"; diff --git a/docs/docs/resources/exchange/EXOMigrationEndpoint.md b/docs/docs/resources/exchange/EXOMigrationEndpoint.md new file mode 100644 index 0000000000..e8a3134503 --- /dev/null +++ b/docs/docs/resources/exchange/EXOMigrationEndpoint.md @@ -0,0 +1,189 @@ +# EXOMigrationEndpoint + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **Identity** | Key | String | Identity of the migration endpoint. | | +| **AcceptUntrustedCertificates** | Write | Boolean | Specifies whether to accept untrusted certificates. | | +| **AppID** | Write | String | The Application ID used for authentication. | | +| **AppSecretKeyVaultUrl** | Write | String | The URL of the Key Vault that stores the application secret. | | +| **Authentication** | Write | String | The authentication method for the migration endpoint. | | +| **EndpointType** | Write | String | The type of migration endpoint. | `IMAP` | +| **ExchangeServer** | Write | String | The Exchange Server address for the migration endpoint. | | +| **MailboxPermission** | Write | String | The mailbox permission for the migration endpoint. | | +| **MaxConcurrentIncrementalSyncs** | Write | String | The maximum number of concurrent incremental syncs. | | +| **MaxConcurrentMigrations** | Write | String | The maximum number of concurrent migrations. | | +| **NspiServer** | Write | String | The NSPI server for the migration endpoint. | | +| **Port** | Write | String | The port number for the migration endpoint. | | +| **RemoteServer** | Write | String | The remote server for the migration endpoint. | | +| **RemoteTenant** | Write | String | The remote tenant for the migration endpoint. | | +| **RpcProxyServer** | Write | String | The RPC proxy server for the migration endpoint. | | +| **Security** | Write | String | The security level for the migration endpoint. | `None`, `Tls`, `Ssl` | +| **SourceMailboxLegacyDN** | Write | String | The legacy distinguished name of the source mailbox. | | +| **UseAutoDiscover** | Write | Boolean | Specifies whether to use AutoDiscover. | | +| **Ensure** | Write | String | Specifies if the migration endpoint should exist or not. | `Present`, `Absent` | +| **Credential** | Write | PSCredential | Credentials of the workload's Admin | | +| **ApplicationId** | Write | String | Id of the Azure Active Directory application to authenticate with. | | +| **TenantId** | Write | String | Id of the Azure Active Directory tenant used for authentication. | | +| **CertificateThumbprint** | Write | String | Thumbprint of the Azure Active Directory application's authentication certificate to use for authentication. | | +| **ManagedIdentity** | Write | Boolean | Managed ID being used for authentication. | | +| **AccessTokens** | Write | StringArray[] | Access token used for authentication. | | + + +## Description + +Use this resource to create and monitor migration endpoints in exchange. + +## Permissions + +### Exchange + +To authenticate with Microsoft Exchange, this resource required the following permissions: + +#### Roles + +- Recipient Policies, View-Only Recipients, Mail Recipient Creation, View-Only Configuration, Mail Recipients + +#### 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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } + } +} +``` + +### 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()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + # value for security updated from Tls to None + Security = "None"; + } + } +} +``` + +### Example 3 + +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. + +```powershell +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + EXOMigrationEndpoint "EXOMigrationEndpoint-testIMAP" + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Absent"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "None"; + } + } +} +``` + From 41aae4d7cd37d35a9183db987162b6453efd664b Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Sat, 5 Oct 2024 19:37:41 +0000 Subject: [PATCH 08/11] Updated Schema Definition --- Modules/Microsoft365DSC/SchemaDefinition.json | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index 39930e9bbd..7bbcdaf2d8 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -12484,6 +12484,136 @@ } ] }, + { + "ClassName": "MSFT_EXOMigrationEndpoint", + "Parameters": [ + { + "CIMType": "String", + "Name": "Identity", + "Option": "Key" + }, + { + "CIMType": "Boolean", + "Name": "AcceptUntrustedCertificates", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "AppID", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "AppSecretKeyVaultUrl", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Authentication", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "EndpointType", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ExchangeServer", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "MailboxPermission", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "MaxConcurrentIncrementalSyncs", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "MaxConcurrentMigrations", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "NspiServer", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Port", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "RemoteServer", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "RemoteTenant", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "RpcProxyServer", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Security", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "SourceMailboxLegacyDN", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "UseAutoDiscover", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "Ensure", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_EXOMobileDeviceMailboxPolicy", "Parameters": [ From b4d8b9be5ff50bda8375ac9b5a91dc3e44bfd7c0 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Sat, 5 Oct 2024 19:38:00 +0000 Subject: [PATCH 09/11] Updated {Create} EXO Integration Tests --- .../M365DSCIntegration.EXO.Create.Tests.ps1 | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 index f69b8d3f89..ab1e4fab0a 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Create.Tests.ps1 @@ -411,10 +411,12 @@ } EXOMailboxFolderPermission 'EXOMailboxFolderPermission-admin:\Calendar' { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "amdin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "amdin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } @@ -431,11 +433,13 @@ } EXOMailboxIRMAccess 'EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com' { - AccessLevel = "Block"; - Credential = $Credscredential; - Ensure = "Present"; - Identity = "qwe@$OrganizationName"; - User = "admin@$OrganizationName"; + AccessLevel = "Block"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "qwe@$OrganizationName"; + User = "admin@$OrganizationName"; } EXOMailContact 'TestMailContact' { @@ -508,7 +512,9 @@ } EXOManagementScope 'EXOManagementScope-Test New DGs' { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; @@ -530,6 +536,23 @@ TenantId = $TenantId CertificateThumbprint = $CertificateThumbprint } + EXOMigrationEndpoint 'EXOMigrationEndpoint-testIMAP' + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "Tls"; + } EXOMobileDeviceMailboxPolicy 'ConfigureMobileDeviceMailboxPolicy' { Name = "Default" From 82bbfa1986c258e09cc62ffbcfbd52128a08bcf5 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Sat, 5 Oct 2024 19:38:31 +0000 Subject: [PATCH 10/11] Updated {Update} EXO Integration Tests --- .../M365DSCIntegration.EXO.Update.Tests.ps1 | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 index bae977e5b8..4a382c8f63 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Update.Tests.ps1 @@ -679,10 +679,12 @@ } EXOMailboxFolderPermission 'EXOMailboxFolderPermission-admin:\Calendar' { - Credential = $Credscredential; - Ensure = "Present"; - Identity = "admin:\Calendar"; - UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + Ensure = "Present"; + Identity = "admin:\Calendar"; + UserPermissions = @(MSFT_EXOMailboxFolderUserPermission { User = 'Default' AccessRights = 'AvailabilityOnly' } @@ -825,7 +827,9 @@ } EXOManagementScope 'EXOManagementScope-Test New DGs' { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; Exclusive = $False; Identity = "Test New DGs"; @@ -847,6 +851,24 @@ TenantId = $TenantId CertificateThumbprint = $CertificateThumbprint } + EXOMigrationEndpoint 'EXOMigrationEndpoint-testIMAP' + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Present"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + # value for security updated from Tls to None + Security = "None"; + } EXOMobileDeviceMailboxPolicy 'ConfigureMobileDeviceMailboxPolicy' { Name = "Default" From f81045915a0e3ef8f04fb91953671fd66f7fd340 Mon Sep 17 00:00:00 2001 From: NikCharlebois Date: Sat, 5 Oct 2024 19:38:54 +0000 Subject: [PATCH 11/11] Updated {Update} EXO Integration Tests --- .../M365DSCIntegration.EXO.Remove.Tests.ps1 | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Remove.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Remove.Tests.ps1 index 331165c9c1..9e231050c0 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Remove.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.EXO.Remove.Tests.ps1 @@ -340,7 +340,9 @@ } EXOManagementScope 'EXOManagementScope-Test New DGs' { - Credential = $Credscredential; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint Ensure = "Absent"; Exclusive = $False; Identity = "Test New DGs"; @@ -357,6 +359,23 @@ TenantId = $TenantId CertificateThumbprint = $CertificateThumbprint } + EXOMigrationEndpoint 'EXOMigrationEndpoint-testIMAP' + { + AcceptUntrustedCertificates = $True; + Authentication = "Basic"; + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + EndpointType = "IMAP"; + Ensure = "Absent"; + Identity = "testIMAP"; + MailboxPermission = "Admin"; + MaxConcurrentIncrementalSyncs = "10"; + MaxConcurrentMigrations = "20"; + Port = 993; + RemoteServer = "gmail.com"; + Security = "None"; + } EXOMobileDeviceMailboxPolicy 'ConfigureMobileDeviceMailboxPolicy' { Name = "Default"