diff --git a/CHANGELOG.md b/CHANGELOG.md index f5f8336f10..3dbda4f640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # UNRELEASED +* EXOMailboxIRMAccess + * Initial Release. * AADPasswordRuleSettings * Initial release * AzureSubscription diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.psm1 new file mode 100644 index 0000000000..13c1f4be94 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.psm1 @@ -0,0 +1,392 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $User, + + [Parameter()] + [ValidateSet('Block')] + [System.String] + $AccessLevel, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters | Out-Null + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + try + { + if ($null -ne $Script:exportedInstances -and $Script:ExportMode) + { + $instance = $Script:exportedInstances | Where-Object -FilterScript {$_.Identity -eq $Identity -and $_.User -eq $User} + } + else + { + $instance = Get-MailboxIRMAccess -Identity $Identity -User $User + } + if ($null -eq $instance) + { + return $nullResult + } + + $results = @{ + Identity = $Identity + User = $User + AccessLevel = $instance.AccessLevel + 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 + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $User, + + [Parameter()] + [ValidateSet('Block')] + [System.String] + $AccessLevel, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $currentInstance = Get-TargetResource @PSBoundParameters + + $setParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + # CREATE + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Set-MailboxIRMAccess @setParameters + } + # REMOVE + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + $setParameters.Remove('AccessLevel') | Out-Null + Remove-MailboxIRMAccess @SetParameters + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter(Mandatory = $true)] + [System.String] + $User, + + [Parameter()] + [ValidateSet('Block')] + [System.String] + $AccessLevel, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + ##TODO - Replace workload + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + [array]$mailboxes = Get-Mailbox -ResultSize 'Unlimited' -ErrorAction Stop + + if ($mailboxes.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + $dscContent = '' + $i = 1 + foreach ($mailbox in $mailboxes) + { + Write-Host " |---[$i/$($mailboxes.Count)] $($mailbox.UserPrincipalName)" -NoNewline + + [Array]$irmAccesses = Get-MailboxIRMAccess -Identity $mailbox.UserPrincipalName + + $j = 1 + Write-Host "`r`n" -NoNewline + foreach ($irmAccess in $irmAccesses) + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + + Write-Host " |---[$j/$($irmAccesses.Count)] $($irmAccess.User)" -NoNewline + Write-Host "`r`n" -NoNewline + $dscIRMAccess = @{ + Identity = $mailbox.UserPrincipalName + User = $irmAccess.User + AccessLevel = $irmAccess.AccessLevel + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + CertificatePassword = $CertificatePassword + Managedidentity = $ManagedIdentity.IsPresent + CertificatePath = $CertificatePath + AccessTokens = $AccessTokens + } + + $Result = $dscIRMAccess + $Result = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Result + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Result ` + -Credential $Credential + $dscContent += $currentDSCBlock + + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $j++ + } + + $i++ + } + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.schema.mof new file mode 100644 index 0000000000..8dc3e7f108 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/MSFT_EXOMailboxIRMAccess.schema.mof @@ -0,0 +1,14 @@ +[ClassVersion("1.0.0.0"), FriendlyName("EXOMailboxIRMAccess")] +class MSFT_EXOMailboxIRMAccess : OMI_BaseResource +{ + [Key, Description("The Identity parameter specifies the mailbox that you want to modify")] String Identity; + [Key, Description("The User parameter specifies the delegate who is blocked from reading IRM-protected messages in the mailbox.")] String User; + [Write, Description("The AccessLevel parameter specifies what delegates can do to IRM-protected messages in the mailbox that's specified by the Identity parameter."), ValueMap{"Block"}, Values{"Block"}] string AccessLevel; + [Write, Description("Present ensures the resource exists, absent ensures it is removed"), 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_EXOMailboxIRMAccess/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/readme.md new file mode 100644 index 0000000000..afc0ca3907 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/readme.md @@ -0,0 +1,6 @@ + +# EXOMailboxIRMAccess + +## Description + +Use this resource to set MailboxIRMAccess settings diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/settings.json new file mode 100644 index 0000000000..df17329583 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMailboxIRMAccess/settings.json @@ -0,0 +1,33 @@ +{ + "resourceName": "EXOMailboxIRMAccess", + "description": "Use this resource to create block Mailbox IRM access for delegates.", + "roles": { + "read": [ + "Global Reader" + ], + "update": [ + "Exchange Administrator" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [], + "update": [] + } + }, + "exchange": { + "requiredroles": [ + "Hygiene Management", + "Compliance Management", + "Organization Management", + "View-Only Organization Management" + ], + "requiredrolegroups": "Organization Management" + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 new file mode 100644 index 0000000000..f47d2d2105 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/1-Create.ps1 @@ -0,0 +1,33 @@ +<# +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 + { + EXOMailboxIRMAccess "EXOMailboxIRMAccess-qwe@testorg.onmicrosoft.com" + { + AccessLevel = "Block"; + Credential = $Credscredential; + 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-Update.ps1 new file mode 100644 index 0000000000..b516274848 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMailboxIRMAccess/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/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMailboxIRMAccess.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMailboxIRMAccess.Tests.ps1 new file mode 100644 index 0000000000..dd15e92933 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOMailboxIRMAccess.Tests.ps1 @@ -0,0 +1,167 @@ +[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-MailboxIRMAccess -MockWith { + } + + Mock -CommandName Set-MailboxIRMAccess -MockWith { + } + + Mock -CommandName Remove-MailboxIRMAccess -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 = @{ + AccessLevel = "Block"; + Identity = "qwe@test.org"; + User = "admin@test.org"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MailboxIRMAccess -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 Set-MailboxIRMAccess -Exactly 1 + } + } + + Context -Name "The instance exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + AccessLevel = "Block"; + Identity = "qwe@test.org"; + User = "admin@test.org"; + Ensure = 'Absent' + Credential = $Credential; + } + + ##TODO - Mock the Get-Cmdlet to return an instance + Mock -CommandName Get-MailboxIRMAccess -MockWith { + return @{ + AccessLevel = "Block"; + Identity = "qwe@test.org"; + User = "admin@test.org"; + } + } + } + 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-MailboxIRMAccess -Exactly 1 + } + } + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AccessLevel = "Block"; + Identity = "qwe@test.org"; + User = "admin@test.org"; + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MailboxIRMAccess -MockWith { + return @{ + AccessLevel = "Block"; + Identity = "qwe@test.org"; + User = "admin@test.org"; + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Get-MailboxIRMAccess -MockWith { + return @{ + Identity = "john.smith@contoso.com"; + AccessLevel = "Block"; + User = "admin@contoso.com"; + } + } + + Mock -CommandName Get-Mailbox -MockWith { + return @{ + UserPrincipalName = "john.smith@contoso.com"; + } + } + } + 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.EXOManagementScope.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOManagementScope.Tests.ps1 index dde34a4529..1ebcd0c4ad 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOManagementScope.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.EXOManagementScope.Tests.ps1 @@ -35,7 +35,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { return "Credentials" } - ##TODO - Mock any Remove/Set/New cmdlets Mock -CommandName New-ManagementScope -MockWith { } @@ -66,7 +65,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { RecipientRestrictionFilter = "Name -like 'Nik*'"; } - ##TODO - Mock the Get-Cmdlet to return $null Mock -CommandName Get-ManagementScope -MockWith { return $null } @@ -95,7 +93,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { RecipientRestrictionFilter = "Name -like 'Nik*'"; } - ##TODO - Mock the Get-Cmdlet to return an instance Mock -CommandName Get-ManagementScope -MockWith { return @{ Exclusive = $False; @@ -129,7 +126,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { RecipientRestrictionFilter = "Name -like 'Nik*'"; } - ##TODO - Mock the Get-Cmdlet to return the desired values Mock -CommandName Get-ManagementScope -MockWith { return @{ Exclusive = $False; @@ -141,7 +137,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } It 'Should return true from the Test method' { - Test-TargetResource -Verbose @testParams | Should -Be $true + Test-TargetResource @testParams | Should -Be $true } } @@ -156,7 +152,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { RecipientRestrictionFilter = "Name -like 'Nik*'"; } - ##TODO - Mock the Get-Cmdlet to return a drift Mock -CommandName Get-ManagementScope -MockWith { return @{ Exclusive = $False; @@ -189,7 +184,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Credential = $Credential; } - ##TODO - Mock the Get-Cmdlet to return an instance Mock -CommandName Get-ManagementScope -MockWith { return @{ Exclusive = $False; diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index f27e97e9d1..36fb0879a9 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -89,6 +89,52 @@ function Disable-AzSubscription #endregion # region ExchangeOnlineManagement +function Get-MailboxIRMAccess +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $User, + + [Parameter()] + [System.Object] + $Identity + ) +} + +function Set-MailboxIRMAccess +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $User, + + [Parameter()] + [System.Object] + $Identity, + + [Parameter()] + [System.Object] + $AccessLevel + ) +} + +function Remove-MailboxIRMAccess +{ + [CmdletBinding()] + param( + [Parameter()] + [System.Object] + $User, + + [Parameter()] + [System.Object] + $Identity + ) +} + function Get-ArcConfig { [CmdletBinding()]