diff --git a/CHANGELOG.md b/CHANGELOG.md index 527b2c86df..4ca0e1c0f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,24 @@ * Initial release. * AADConnectorGroupApplicationProxy Initial release. +* AADDeviceRegistrationPolicy + * Initial release. * AADEntitlementManagementSettings * Added support for ApplicationSecret +* ADOPermissionGroupSettings + * Initial release. +* EXOMigrationEndpoint + * Initial Release +* IntuneAppAndBrowserIsolationPolicyWindows10 + * Initial release. + FIXES [#3028](https://github.com/microsoft/Microsoft365DSC/issues/3028) +* IntuneEndpointDetectionAndResponsePolicyWindows10 + * Migrate to new Settings Catalog cmdlets. * M365DSCDRGUtil * Fixes an issue for the handling of skipped one-property elements in the Settings Catalog. FIXES [#5086](https://github.com/microsoft/Microsoft365DSC/issues/5086) + * Add Set support for secret Settings Catalog values + * Removed unused functions # 1.24.1002.1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.psm1 new file mode 100644 index 0000000000..c6d32acefa --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.psm1 @@ -0,0 +1,603 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter()] + [Boolean] + $AzureADJoinIsAdminConfigurable, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureADAllowedToJoin, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinUsers, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinGroups, + + [Parameter()] + [System.Boolean] + $MultiFactorAuthConfiguration, + + [Parameter()] + [System.Boolean] + $LocalAdminsEnableGlobalAdmins, + + [Parameter()] + [System.Boolean] + $LocalAdminPasswordIsEnabled, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureAdJoinLocalAdminsRegisteringMode, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringGroups, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringUsers, + + [Parameter()] + [System.UInt32] + $UserDeviceQuota, + + [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 + ) + + try + { + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -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 + + $getValue = Get-MgBetaPolicyDeviceRegistrationPolicy -ErrorAction Stop + + $AzureADAllowedToJoin = 'None' + $AzureADAllowedToJoinUsers = @() + $AzureADAllowedToJoinGroups = @() + if ($getValue.AzureADJoin.AllowedToJoin.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.allDeviceRegistrationMembership') + { + $AzureADAllowedToJoin = 'All' + } + elseif ($getValue.AzureADJoin.AllowedToJoin.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.enumeratedDeviceRegistrationMembership') + { + $AzureADAllowedToJoin = 'Selected' + + foreach ($userId in $getValue.AzureAdJoin.AllowedToJoin.AdditionalProperties.users) + { + $userInfo = Get-MgUser -UserId $userId + $AzureADAllowedToJoinUsers += $userInfo.UserPrincipalName + } + + foreach ($groupId in $getValue.AzureAdJoin.AllowedToJoin.AdditionalProperties.groups) + { + $groupInfo = Get-MgGroup -GroupId $groupId + $AzureADAllowedToJoinGroups += $groupInfo.DisplayName + } + } + + $AzureAdJoinLocalAdminsRegisteringUsers = @() + $AzureAdJoinLocalAdminsRegisteringGroups = @() + $AzureAdJoinLocalAdminsRegisteringMode = 'All' + + if ($getValue.AzureAdJoin.LocalAdmins.RegisteringUsers.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.noDeviceRegistrationMembership') + { + $AzureAdJoinLocalAdminsRegisteringMode = 'None' + } + elseif ($getValue.AzureAdJoin.LocalAdmins.RegisteringUsers.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.enumeratedDeviceRegistrationMembership') + { + $AzureAdJoinLocalAdminsRegisteringMode = 'Selected' + foreach ($userId in $getValue.AzureAdJoin.LocalAdmins.RegisteringUsers.AdditionalProperties.users) + { + $userInfo = Get-MgUser -UserId $userId + $AzureAdJoinLocalAdminsRegisteringUsers += $userInfo.UserPrincipalName + } + + foreach ($groupId in $getValue.AzureAdJoin.LocalAdmins.RegisteringUsers.AdditionalProperties.groups) + { + $groupInfo = Get-MgGroup -GroupId $groupId + $AzureAdJoinLocalAdminsRegisteringGroups += $groupInfo.DisplayName + } + } + + $MultiFactorAuthConfiguration = $false + if ($getValue.MultiFactorAuthConfiguration -eq 'required') + { + $MultiFactorAuthConfiguration = $true + } + $LocalAdminsEnableGlobalAdmins = $true + if (-not $getValue.AzureAdJoin.LocalAdmins.EnableGlobalAdmins) + { + $LocalAdminsEnableGlobalAdmins = $false + } + $results = @{ + IsSingleInstance = 'Yes' + AzureADAllowedToJoin = $AzureADAllowedToJoin + AzureADAllowedToJoinGroups = $AzureADAllowedToJoinGroups + AzureADAllowedToJoinUsers = $AzureADAllowedToJoinUsers + UserDeviceQuota = $getValue.UserDeviceQuota + MultiFactorAuthConfiguration = $MultiFactorAuthConfiguration + LocalAdminsEnableGlobalAdmins = $LocalAdminsEnableGlobalAdmins + LocalAdminPasswordIsEnabled = [Boolean]$getValue.LocalAdminPassword.IsEnabled + AzureAdJoinLocalAdminsRegisteringMode = $AzureAdJoinLocalAdminsRegisteringMode + AzureAdJoinLocalAdminsRegisteringGroups = $AzureAdJoinLocalAdminsRegisteringGroups + AzureAdJoinLocalAdminsRegisteringUsers = $AzureAdJoinLocalAdminsRegisteringUsers + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + 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)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter()] + [Boolean] + $AzureADJoinIsAdminConfigurable, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureADAllowedToJoin, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinUsers, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinGroups, + + [Parameter()] + [System.Boolean] + $MultiFactorAuthConfiguration, + + [Parameter()] + [System.Boolean] + $LocalAdminsEnableGlobalAdmins, + + [Parameter()] + [System.Boolean] + $LocalAdminPasswordIsEnabled, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureAdJoinLocalAdminsRegisteringMode, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringGroups, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringUsers, + + [Parameter()] + [System.UInt32] + $UserDeviceQuota, + + [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 + ) + + #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 + + $MultiFactorAuthConfigurationValue = "notRequired" + if ($MultiFactorAuthConfiguration) + { + $MultiFactorAuthConfigurationValue = 'required' + } + + $azureADRegistrationAllowedToRegister = "#microsoft.graph.noDeviceRegistrationMembership" + if ($AzureAdJoinLocalAdminsRegisteringMode -eq 'All') + { + $azureADRegistrationAllowedToRegister = "#microsoft.graph.allDeviceRegistrationMembership" + } + elseif ($AzureAdJoinLocalAdminsRegisteringMode -eq 'Selected') + { + $azureADRegistrationAllowedToRegister = "#microsoft.graph.enumeratedDeviceRegistrationMembership" + + $azureADRegistrationAllowedUsers = @() + foreach ($user in $AzureAdJoinLocalAdminsRegisteringUsers) + { + $userInfo = Get-MgUser -UserId $user + $azureADRegistrationAllowedUsers += $userInfo.Id + } + + $azureADRegistrationAllowedGroups = @() + foreach ($group in $AzureAdJoinLocalAdminsRegisteringGroups) + { + $groupInfo = Get-MgGroup -Filter "DisplayName eq '$group'" + $azureADRegistrationAllowedGroups += $groupInfo.Id + } + } + + $localAdminAllowedMode = "#microsoft.graph.noDeviceRegistrationMembership" + if ($AzureAdJoinLocalAdminsRegisteringMode -eq 'All') + { + $localAdminAllowedMode = "#microsoft.graph.allDeviceRegistrationMembership" + } + elseif ($AzureAdJoinLocalAdminsRegisteringMode -eq 'Selected') + { + $localAdminAllowedMode = "#microsoft.graph.enumeratedDeviceRegistrationMembership" + + $localAdminAllowedUsers = @() + foreach ($user in $AzureAdJoinLocalAdminsRegisteringUsers) + { + $userInfo = Get-MgUser -UserId $user + $localAdminAllowedUsers += $userInfo.Id + } + + $localAdminAllowedGroups = @() + foreach ($group in $AzureAdJoinLocalAdminsRegisteringGroups) + { + $groupInfo = Get-MgGroup -Filter "DisplayName eq '$group'" + $localAdminAllowedGroups += $groupInfo.Id + } + } + + $updateParameters = @{ + userDeviceQuota = $UserDeviceQuota + multiFactorAuthConfiguration = $MultiFactorAuthConfigurationValue + azureADJoin = @{ + isAdminConfigurable =$AzureADJoinIsAdminConfigurable + allowedToJoin = @{ + '@odata.type' = $azureADRegistrationAllowedToRegister + users = $AzureADAllowedToJoinUsers + groups = $AzureADAllowedToJoinGroups + } + localAdmins = @{ + enableGlobalAdmins = $LocalAdminsEnableGlobalAdmins + registeringUsers = @{ + '@odata.type' = $localAdminAllowedMode + users = $localAdminAllowedUsers + groups = $localAdminAllowedGroups + } + } + } + localAdminPassword = @{ + isEnabled = $LocalAdminPasswordIsEnabled + } + azureADRegistration = @{ + isAdminConfigurable = $false + allowedToRegister = @{ + '@odata.type' = "#microsoft.graph.allDeviceRegistrationMembership" + } + } + } + $uri = $Global:MSCloudLoginConnectionProfile.MicrosoftGraph.ResourceUrl + 'beta/policies/deviceRegistrationPolicy' + Write-Verbose -Message "Updating Device Registration Policy with payload:`r`n$(ConvertTo-Json $updateParameters -Depth 10)" + Invoke-MgGraphRequest -Method PUT -Uri $uri -Body $updateParameters +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Yes')] + [System.String] + $IsSingleInstance, + + [Parameter()] + [Boolean] + $AzureADJoinIsAdminConfigurable, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureADAllowedToJoin, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinUsers, + + [Parameter()] + [System.String[]] + $AzureADAllowedToJoinGroups, + + [Parameter()] + [System.Boolean] + $MultiFactorAuthConfiguration, + + [Parameter()] + [System.Boolean] + $LocalAdminsEnableGlobalAdmins, + + [Parameter()] + [System.Boolean] + $LocalAdminPasswordIsEnabled, + + [Parameter()] + [ValidateSet('All', 'Selected', 'None')] + [System.String] + $AzureAdJoinLocalAdminsRegisteringMode, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringGroups, + + [Parameter()] + [System.String[]] + $AzureAdJoinLocalAdminsRegisteringUsers, + + [Parameter()] + [System.UInt32] + $UserDeviceQuota, + + [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 + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + Write-Verbose -Message "Testing configuration of the Device Registration Policy" + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -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 + { + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + $params = @{ + IsSingleInstance = 'Yes' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + 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 + { + if ($_.ErrorDetails.Message -like "*Insufficient privileges*") + { + Write-Host "`r`n $($Global:M365DSCEmojiYellowCircle) Insufficient permissions or license to export Attribute Sets." + } + else + { + 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_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.schema.mof new file mode 100644 index 0000000000..5096bb720f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/MSFT_AADDeviceRegistrationPolicy.schema.mof @@ -0,0 +1,23 @@ +[ClassVersion("1.0.0.0"), FriendlyName("AADDeviceRegistrationPolicy")] +class MSFT_AADDeviceRegistrationPolicy : OMI_BaseResource +{ + [Key, Description("Only valid value is 'Yes'."), ValueMap{"Yes"}, Values{"Yes"}] String IsSingleInstance; + [Write, Description("Determines whether or not administrators can configure Azure AD Join.")] Boolean AzureADJoinIsAdminConfigurable; + [Write, Description("Specifies the maximum number of devices that a user can have within your organization before blocking new device registrations. The default value is set to 50. If this property isn't specified during the policy update operation, it's automatically reset to 0 to indicate that users aren't allowed to join any devices.")] UInt32 UserDeviceQuota; + [Write, Description("Scope that a device registration policy applies to."), ValueMap{"All", "Selected", "None"}, Values{"All", "Selected", "None"}] String AzureADAllowedToJoin; + [Write, Description("List of users that this policy applies to.")] String AzureADAllowedToJoinUsers[]; + [Write, Description("List of groups that this policy applies to.")] String AzureADAllowedToJoinGroups[]; + [Write, Description("Specifies the authentication policy for a user to complete registration using Microsoft Entra join or Microsoft Entra registered within your organization.")] Boolean MultiFactorAuthConfiguration; + [Write, Description("Indicates whether global administrators are local administrators on all Microsoft Entra-joined devices. This setting only applies to future registrations. Default is true.")] Boolean LocalAdminsEnableGlobalAdmins; + [Write, Description("Scope that a device registration policy applies to for local admins."), ValueMap{"All", "Selected", "None"}, Values{"All", "Selected", "None"}] String AzureAdJoinLocalAdminsRegisteringMode; + [Write, Description("List of groups that this policy applies to.")] String AzureAdJoinLocalAdminsRegisteringGroups[]; + [Write, Description("List of users that this policy applies to.")] String AzureAdJoinLocalAdminsRegisteringUsers[]; + [Write, Description("Specifies whether this policy scope is configurable by the admin. The default value is false. An admin can set it to true to enable Local Admin Password Solution (LAPS) within their organzation.")] Boolean LocalAdminPasswordIsEnabled; + [Write, Description("Credentials of the 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("Secret of the Azure Active Directory tenant used for authentication."), EmbeddedInstance("MSFT_Credential")] String ApplicationSecret; + [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_AADDeviceRegistrationPolicy/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/readme.md new file mode 100644 index 0000000000..740e58881b --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/readme.md @@ -0,0 +1,6 @@ + +# AADDeviceRegistrationPolicy + +## Description + +Represents the policy scope that controls quota restrictions, additional authentication, and authorization policies to register device identities to your organization. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/settings.json new file mode 100644 index 0000000000..3324b5f4e0 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADDeviceRegistrationPolicy/settings.json @@ -0,0 +1,34 @@ +{ + "resourceName": "AADDeviceRegistrationPolicy", + "description": "Represents the policy scope that controls quota restrictions, additional authentication, and authorization policies to register device identities to your organization.", + "roles": { + "read": [ + "Security Reader" + ], + "update": [ + "Authentication Policy Administrator" + ] + }, + "permissions": { + "graph": { + "delegated": { + "read": [ + ], + "update": [ + ] + }, + "application": { + "read": [ + { + "name": "Policy.Read.DeviceConfiguration" + } + ], + "update": [ + { + "name": "Policy.ReadWrite.DeviceConfiguration" + } + ] + } + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroup/MSFT_ADOPermissionGroup.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroup/MSFT_ADOPermissionGroup.psm1 index 1f9df20d61..1af5a2f77b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroup/MSFT_ADOPermissionGroup.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroup/MSFT_ADOPermissionGroup.psm1 @@ -477,8 +477,8 @@ function Export-TargetResource { $Script:ExportMode = $true - $profile = Invoke-M365DSCAzureDevOPSWebRequest -Uri 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=5.1' - $accounts = Invoke-M365DSCAzureDevOPSWebRequest -Uri "https://app.vssps.visualstudio.com/_apis/accounts?api-version=7.1-preview.1&memberId=$($profile.id)" + $profileValue = Invoke-M365DSCAzureDevOPSWebRequest -Uri 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=5.1' + $accounts = Invoke-M365DSCAzureDevOPSWebRequest -Uri "https://app.vssps.visualstudio.com/_apis/accounts?api-version=7.1-preview.1&memberId=$($profileValue.id)" $i = 1 $dscContent = '' diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.psm1 new file mode 100644 index 0000000000..c405642904 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.psm1 @@ -0,0 +1,680 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $GroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $OrganizationName, + + [Parameter()] + [System.String] + $Descriptor, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $AllowPermissions, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $DenyPermissions, + + [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 'AzureDevOPS' ` + -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 + try + { + if ($null -ne $Script:exportedInstances -and $Script:ExportMode) + { + if (-not [System.String]::IsNullOrEmpty($Descriptor)) + { + $instance = $Script:exportedInstances | Where-Object -FilterScript {$_.descriptor -eq $Descriptor} + } + + if ($null -eq $instance) + { + $instance = $Script:exportedInstances | Where-Object -FilterScript {$_.principalName -eq $PrincipalName} + } + } + else + { + $uri = "https://vssps.dev.azure.com/$OrganizationName/_apis/graph/groups?api-version=7.1-preview.1" + $allInstances = (Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri).value + if (-not [System.String]::IsNullOrEmpty($Descriptor)) + { + $instance = $allInstances | Where-Object -FilterScript {$_.descriptor -eq $Descriptor} + } + if ($null -eq $instance) + { + $instance = $allInstances | Where-Object -FilterScript {$_.principalName -eq $PrincipalName} + } + } + if ($null -eq $instance) + { + return $nullResult + } + + $groupPermissions = Get-M365DSCADOGroupPermission -GroupName $instance.principalName -OrganizationName $OrganizationName + + $results = @{ + OrganizationName = $OrganizationName + GroupName = $instance.principalName + Descriptor = $instance.Descriptor + AllowPermissions = $groupPermissions.Allow + DenyPermissions = $groupPermissions.Deny + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + return [System.Collections.Hashtable] $results + } + catch + { + Write-Verbose -Message $_ + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $GroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $OrganizationName, + + [Parameter()] + [System.String] + $Descriptor, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $AllowPermissions, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $DenyPermissions, + + [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 + + $uri = "https://vssps.dev.azure.com/$($OrganizationName)/_apis/identities?subjectDescriptors=$($currentInstance.Descriptor)&api-version=7.2-preview.1" + $info = Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri + $descriptor = $info.value.descriptor + + # Get all Namespaces from the Allow and Deny + $namespacesToUpdate = @() + foreach ($namespace in $AllowPermissions) + { + if ($namespacesToUpdate.Length -eq 0 -or -not $namespacesToUpdate.NameSpaceId.Contains($namespace.namespaceId)) + { + $namespacesToUpdate += $namespace + } + } + foreach ($namespace in $DenyPermissions) + { + if ($namespacesToUpdate.Length -eq 0 -or -not $namespacesToUpdate.NameSpaceId.Contains($namespace.namespaceId)) + { + $namespacesToUpdate += $namespace + } + } + + foreach ($namespace in $namespacesToUpdate) + { + $allowPermissionValue = 0 + $denyPermissionValue = 0 + $allowPermissionsEntries = $AllowPermissions | Where-Object -FilterScript {$_.NamespaceId -eq $namespace.namespaceId} + foreach ($entry in $allowPermissionsEntries) + { + $allowPermissionValue += [Uint32]::Parse($entry.Bit) + } + + $denyPermissionsEntries = $DenyPermissions | Where-Object -FilterScript {$_.NamespaceId -eq $namespace.namespaceId} + foreach ($entry in $denyPermissionsEntries) + { + $denyPermissionValue += [Uint32]::Parse($entry.Bit) + } + + $updateParams = @{ + merge = $false + token = $namespace.token + accessControlEntries = @( + @{ + descriptor = $descriptor + allow = $allowPermissionValue + deny = $denyPermissionValue + extendedInfo = @{} + } + ) + } + $uri = "https://dev.azure.com/$($OrganizationName)/_apis/accesscontrolentries/$($namespace.namespaceId)?api-version=7.1" + $body = ConvertTo-Json $updateParams -Depth 10 -Compress + Write-Verbose -Message "Updating with payload:`r`n$body" + Invoke-M365DSCAzureDevOPSWebRequest -Method POST ` + -Uri $uri ` + -Body $body ` + -ContentType 'application/json' + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $GroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $OrganizationName, + + [Parameter()] + [System.String] + $Descriptor, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $AllowPermissions, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $DenyPermissions, + + [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() + + # Evaluate Permissions + $testResult = $true + foreach ($permission in $AllowPermissions) + { + $instance = $CurrentValues.AllowPermissions | Where-Object -FilterScript {$_.Token -eq $permission.Token -and ` + $_.DisplayName -eq $permission.DisplayName -and ` + $_.Bit -eq $permission.Bit -and ` + $_.NamespaceId -eq $permission.NamespaceId} + if ($null -eq $instance) + { + $testResult = $false + Write-Verbose -Message "Drift detected in AllowPermission: {$($permission.DisplayName)}" + } + } + + foreach ($permission in $DenyPermissions) + { + $instance = $CurrentValues.DenyPermissions | Where-Object -FilterScript {$_.Token -eq $permission.Token -and ` + $_.DisplayName -eq $permission.DisplayName -and ` + $_.Bit -eq $permission.Bit -and ` + $_.NamespaceId -eq $permission.NamespaceId} + if ($null -eq $instance) + { + $testResult = $false + Write-Verbose -Message "Drift detected in DenyPermission: {$($permission.DisplayName)}" + } + } + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + if ($testResult) + { + $ValuesToCheck.Remove('AllowPermissions') | Out-Null + $ValuesToCheck.Remove('DenyPermissions') | Out-Null + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + } + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + $ConnectionMode = New-M365DSCConnection -Workload 'AzureDevOPS' ` + -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 + + $profileValue = Invoke-M365DSCAzureDevOPSWebRequest -Uri 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=5.1' + $accounts = Invoke-M365DSCAzureDevOPSWebRequest -Uri "https://app.vssps.visualstudio.com/_apis/accounts?api-version=7.1-preview.1&memberId=$($profileValue.id)" + + $i = 1 + $dscContent = '' + if ($accounts.count -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + return '' + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($account in $accounts) + { + $organization = $account.Value.accountName + $uri = "https://vssps.dev.azure.com/$organization/_apis/graph/groups?api-version=7.1-preview.1" + + [array] $Script:exportedInstances = (Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri).Value + + $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.principalName + if ($null -ne $Global:M365DSCExportResourceInstancesCount) + { + $Global:M365DSCExportResourceInstancesCount++ + } + Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline + $params = @{ + OrganizationName = $Organization + GroupName = $config.principalName + Descriptor = $config.descriptor + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + if (-not $config.principalName.StartsWith("[TEAM FOUNDATION]")) + { + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + if ($results.AllowPermissions.Length -gt 0) + { + $Results.AllowPermissions = Get-M365DSCADOPermissionsAsString $Results.AllowPermissions + } + + if ($results.DenyPermissions.Length -gt 0) + { + $Results.DenyPermissions = Get-M365DSCADOPermissionsAsString $Results.DenyPermissions + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + + if ($null -ne $Results.AllowPermissions) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'AllowPermissions' + } + if ($null -ne $Results.DenyPermissions) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock ` + -ParameterName 'DenyPermissions' + } + + $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 '' + } +} + +function Get-M365DSCADOGroupPermission +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param( + [Parameter(Mandatory = $true)] + [System.String] + $GroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $OrganizationName + ) + + $results = @{ + Allow = @() + Deny = @() + } + + try + { + $uri = "https://vssps.dev.azure.com/$($OrganizationName)/_apis/graph/groups?api-version=7.1-preview.1" + $groupInfo = Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri + $mygroup = $groupInfo.value | Where-Object -FilterScript {$_.principalName -eq $GroupName} + + $uri = "https://vssps.dev.azure.com/$($OrganizationName)/_apis/identities?subjectDescriptors=$($mygroup.descriptor)&api-version=7.2-preview.1" + $info = Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri + $descriptor = $info.value.descriptor + + $uri = "https://dev.azure.com/$($OrganizationName)/_apis/securitynamespaces?api-version=7.1-preview.1" + $responseSecurity = Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri + $securityNamespaces = $responseSecurity.Value + + foreach ($namespace in $securityNamespaces) + { + $uri = "https://dev.azure.com/$($OrganizationName)/_apis/accesscontrollists/$($namespace.namespaceId)?api-version=7.2-preview.1" + $response = Invoke-M365DSCAzureDevOPSWebRequest -Uri $uri + + foreach ($entry in $response.value) + { + $token = $entry.token + foreach ($ace in $entry.acesDictionary) + { + if ($ace.$descriptor) + { + $allow = $ace.$descriptor.Allow + $allowBinary = [Convert]::ToString($allow, 2) + + $deny = $ace.$descriptor.Deny + $denyBinary = [Convert]::ToString($deny, 2) + + # Breakdown the allow bits + $position = -1 + $bitMaskPositionsFound = @() + do + { + $position = $allowBinary.IndexOf('1', $position + 1) + if ($position -ge 0) + { + $zerosToAdd = $allowBinary.Length - $position - 1 + $value = '1' + for ($i = 1; $i -le $zerosToAdd; $i++) + { + $value += '0' + } + + $bitMaskPositionsFound += $value + } + } while($position -ge 0 -and ($position+1) -le $allowBinary.Length) + + foreach ($bitmask in $bitMaskPositionsFound) + { + $associatedAction = $namespace.actions | Where-Object -FilterScript {[Convert]::ToString($_.bit,2) -eq $bitmask} + if (-not [System.String]::IsNullOrEmpty($associatedAction.displayName)) + { + $entry = @{ + DisplayName = $associatedAction.displayName + Bit = $associatedAction.bit + NamespaceId = $namespace.namespaceId + Token = $token + } + $results.Allow += $entry + } + } + + # Breakdown the deny bits + $position = -1 + $bitMaskPositionsFound = @() + do + { + $position = $denyBinary.IndexOf('1', $position + 1) + if ($position -ge 0) + { + $zerosToAdd = $denyBinary.Length - $position - 1 + $value = '1' + for ($i = 1; $i -le $zerosToAdd; $i++) + { + $value += '0' + } + + $bitMaskPositionsFound += $value + } + } while($position -ge 0 -and ($position+1) -le $denyBinary.Length) + + foreach ($bitmask in $bitMaskPositionsFound) + { + $associatedAction = $namespace.actions | Where-Object -FilterScript {[Convert]::ToString($_.bit,2) -eq $bitmask} + if (-not [System.String]::IsNullOrEmpty($associatedAction.displayName)) + { + $entry = @{ + DisplayName = $associatedAction.displayName + Bit = $associatedAction.bit + NamespaceId = $namespace.namespaceId + Token = $token + } + $results.Deny += $entry + } + } + } + } + } + } + } + catch + { + throw $_ + } + return $results +} + +function Get-M365DSCADOPermissionsAsString +{ + [CmdletBinding()] + [OutputType([System.String])] + param( + [Parameter(Mandatory = $true)] + [System.Collections.ArrayList] + $Permissions + ) + + $StringContent = [System.Text.StringBuilder]::new() + $StringContent.Append('@(') | Out-Null + foreach ($permission in $Permissions) + { + $StringContent.Append(" MSFT_ADOPermission { `r`n") | Out-Null + $StringContent.Append(" NamespaceId = '$($permission.NamespaceId)'`r`n") | Out-Null + $StringContent.Append(" DisplayName = '$($permission.DisplayName.Replace("'", "''"))'`r`n") | Out-Null + $StringContent.Append(" Bit = '$($permission.Bit)'`r`n") | Out-Null + $StringContent.Append(" Token = '$($permission.Token)'`r`n") | Out-Null + $StringContent.Append(" }`r`n") | Out-Null + } + $StringContent.Append(' )') | Out-Null + return $StringContent.ToString() +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.schema.mof new file mode 100644 index 0000000000..e4c33762cb --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/MSFT_ADOPermissionGroupSettings.schema.mof @@ -0,0 +1,25 @@ +[ClassVersion("1.0.0")] +class MSFT_ADOPermission +{ + [Write, Description("Id of the associate security namespace.")] String NamespaceId; + [Write, Description("Display name of the permission scope.")] String DisplayName; + [Write, Description("Bit mask for the permission")] UInt32 Bit; + [Write, Description("Token value")] String Token; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("ADOPermissionGroupSettings")] +class MSFT_ADOPermissionGroupSettings : OMI_BaseResource +{ + [Key, Description("Name of the group.")] String GroupName; + [Write, Description("Name of the DevOPS Organization.")] String OrganizationName; + [Write, Description("Descriptor for the group.")] String Descriptor; + [Write, Description("Allow permissions."), EmbeddedInstance("MSFT_ADOPermission")] string AllowPermissions[]; + [Write, Description("Deny permissions"), EmbeddedInstance("MSFT_ADOPermission")] string DenyPermissions[]; + + [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_ADOPermissionGroupSettings/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/readme.md new file mode 100644 index 0000000000..5cb632a8b1 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/readme.md @@ -0,0 +1,6 @@ + +# ADOPermissionGroupSettings + +## Description + +Manages permissions in Azure DevOPS. diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/settings.json new file mode 100644 index 0000000000..6509ef6453 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_ADOPermissionGroupSettings/settings.json @@ -0,0 +1,20 @@ +{ + "resourceName": "ADOPermissionGroupSettings", + "description": "Manages permissions in Azure DevOPS.", + "roles": { + "read": [], + "update": [] + }, + "permissions": { + "graph": { + "delegated": { + "read": [], + "update": [] + }, + "application": { + "read": [], + "update": [] + } + } + } +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 new file mode 100644 index 0000000000..8e8ef54b1a --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.psm1 @@ -0,0 +1,603 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $AppID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, + + [Parameter()] + [ValidateSet('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] + $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) + { + $migrationEndpoint = $Script:exportedInstances | Where-Object -FilterScript {$_.Identity -eq $Identity} + } + else + { + $migrationEndpoint = Get-MigrationEndpoint -Identity $Identity -ErrorAction Stop + } + if ($null -eq $migrationEndpoint) + { + return $nullResult + } + + $results = @{ + 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 + { + New-M365DSCLogEntry -Message 'Error retrieving data:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return $nullResult + } +} + +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $AppID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, + + [Parameter()] + [ValidateSet('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] + $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 + + $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') + { + New-MigrationEndpoint @newParams + } + # UPDATE + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Set-MigrationEndpoint @setParams + } + # REMOVE + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Remove-MigrationEndpoint -Identity $Identity + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Identity, + + [Parameter()] + [System.Boolean] + $AcceptUntrustedCertificates, + + [Parameter()] + [System.String] + $AppID, + + [Parameter()] + [System.String] + $AppSecretKeyVaultUrl, + + [Parameter()] + [System.String] + $Authentication, + + [Parameter()] + [ValidateSet('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] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).Clone() + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $ValuesToCheck)" + + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + -Source $($MyInvocation.MyCommand.Source) ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck $ValuesToCheck.Keys + + Write-Verbose -Message "Test-TargetResource returned $testResult" + + return $testResult +} + +function Export-TargetResource +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'ExchangeOnline' ` + -InboundParameters $PSBoundParameters + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + try + { + $Script:ExportMode = $true + [array] $Script:exportedInstances = Get-MigrationEndpoint -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.Identity + Write-Host " |---[$i/$($Script:exportedInstances.Count)] $displayedKey" -NoNewline + $params = @{ + Identity = $config.Identity + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + return $dscContent + } + catch + { + Write-Host $Global:M365DSCEmojiRedX + + New-M365DSCLogEntry -Message 'Error during Export:' ` + -Exception $_ ` + -Source $($MyInvocation.MyCommand.Source) ` + -TenantId $TenantId ` + -Credential $Credential + + return '' + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_EXOMigrationEndpoint/MSFT_EXOMigrationEndpoint.schema.mof new file mode 100644 index 0000000000..6f6e4c9692 --- /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{"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; + [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_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.psm1 new file mode 100644 index 0000000000..01d7114e5a --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.psm1 @@ -0,0 +1,855 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $AllowWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $ClipboardSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $SaveFilesToHost, + + [Parameter()] + [ValidateSet('install')] + [System.String] + $InstallWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('1', '2', '3')] + [System.String] + $ClipboardFileType, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowPersistence, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowVirtualGPU, + + [Parameter()] + [ValidateSet('0', '1', '2', '4', '8')] + [System.Int32[]] + $PrintingSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowCameraMicrophoneRedirection, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AuditApplicationGuard, + + [Parameter()] + [System.String[]] + $CertificateThumbprints, + + [Parameter()] + [System.String[]] + $EnterpriseIPRange, + + [Parameter()] + [System.String[]] + $EnterpriseCloudResources, + + [Parameter()] + [System.String[]] + $EnterpriseNetworkDomainNames, + + [Parameter()] + [System.String[]] + $EnterpriseProxyServers, + + [Parameter()] + [System.String[]] + $EnterpriseInternalProxyServers, + + [Parameter()] + [System.String[]] + $NeutralResources, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseProxyServersAreAuthoritative, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseIPRangesAreAuthoritative, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [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 + ) + + try + { + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -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 + + $nullResult = $PSBoundParameters + $nullResult.Ensure = 'Absent' + + $getValue = $null + #region resource generator code + $getValue = Get-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $Id -ErrorAction SilentlyContinue + + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune App And Browser Isolation Policy for Windows10 with Id {$Id}" + + if (-not [System.String]::IsNullOrEmpty($DisplayName)) + { + $getValue = Get-MgBetaDeviceManagementConfigurationPolicy ` + -Filter "Name eq '$DisplayName'" ` + -ErrorAction SilentlyContinue + } + } + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Intune App And Browser Isolation Policy for Windows10 with Name {$DisplayName}." + return $nullResult + } + $Id = $getValue.Id + Write-Verbose -Message "An Intune App And Browser Isolation Policy for Windows10 with Id {$Id} and Name {$DisplayName} was found" + + # Retrieve policy specific settings + [array]$settings = Get-MgBetaDeviceManagementConfigurationPolicySetting ` + -DeviceManagementConfigurationPolicyId $Id ` + -ExpandProperty 'settingDefinitions' ` + -ErrorAction Stop + + $policySettings = @{} + $policySettings = Export-IntuneSettingCatalogPolicySettings -Settings $settings -ReturnHashtable $policySettings + + $results = @{ + #region resource generator code + Description = $getValue.Description + DisplayName = $getValue.Name + RoleScopeTagIds = $getValue.RoleScopeTagIds + Id = $getValue.Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + #endregion + } + $results += $policySettings + + $assignmentsValues = Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $Id + $assignmentResult = @() + if ($assignmentsValues.Count -gt 0) + { + $assignmentResult += ConvertFrom-IntunePolicyAssignment -Assignments $assignmentsValues -IncludeDeviceFilter $true + } + $results.Add('Assignments', $assignmentResult) + + 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 + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $AllowWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $ClipboardSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $SaveFilesToHost, + + [Parameter()] + [ValidateSet('install')] + [System.String] + $InstallWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('1', '2', '3')] + [System.String] + $ClipboardFileType, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowPersistence, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowVirtualGPU, + + [Parameter()] + [ValidateSet('0', '1', '2', '4', '8')] + [System.Int32[]] + $PrintingSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowCameraMicrophoneRedirection, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AuditApplicationGuard, + + [Parameter()] + [System.String[]] + $CertificateThumbprints, + + [Parameter()] + [System.String[]] + $EnterpriseIPRange, + + [Parameter()] + [System.String[]] + $EnterpriseCloudResources, + + [Parameter()] + [System.String[]] + $EnterpriseNetworkDomainNames, + + [Parameter()] + [System.String[]] + $EnterpriseProxyServers, + + [Parameter()] + [System.String[]] + $EnterpriseInternalProxyServers, + + [Parameter()] + [System.String[]] + $NeutralResources, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseProxyServersAreAuthoritative, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseIPRangesAreAuthoritative, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [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 + ) + + #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 + + $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + $templateReferenceId = '9f667e40-8f3c-4f88-80d8-457f16906315_1' + $platforms = 'windows10' + $technologies = 'mdm' + + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating an Intune App And Browser Isolation Policy for Windows10 with Name {$DisplayName}" + $BoundParameters.Remove("Assignments") | Out-Null + + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` + -TemplateId $templateReferenceId + + $createParameters = @{ + Name = $DisplayName + Description = $Description + TemplateReference = @{ templateId = $templateReferenceId } + Platforms = $platforms + Technologies = $technologies + Settings = $settings + } + + #region resource generator code + $policy = New-MgBetaDeviceManagementConfigurationPolicy -BodyParameter $createParameters + + if ($policy.Id) + { + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $policy.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' + } + #endregion + } + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating the Intune App And Browser Isolation Policy for Windows10 with Id {$($currentInstance.Id)}" + $BoundParameters.Remove("Assignments") | Out-Null + + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` + -TemplateId $templateReferenceId + + Update-IntuneDeviceConfigurationPolicy ` + -DeviceConfigurationPolicyId $currentInstance.Id ` + -Name $DisplayName ` + -Description $Description ` + -TemplateReferenceId $templateReferenceId ` + -Platforms $platforms ` + -Technologies $technologies ` + -Settings $settings + + #region resource generator code + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $currentInstance.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' + #endregion + } + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing the Intune App And Browser Isolation Policy for Windows10 with Id {$($currentInstance.Id)}" + #region resource generator code + Remove-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $currentInstance.Id + #endregion + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region resource generator code + [Parameter()] + [System.String] + $Description, + + [Parameter(Mandatory = $true)] + [System.String] + $DisplayName, + + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $AllowWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('0', '1', '2', '3')] + [System.String] + $ClipboardSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $SaveFilesToHost, + + [Parameter()] + [ValidateSet('install')] + [System.String] + $InstallWindowsDefenderApplicationGuard, + + [Parameter()] + [ValidateSet('1', '2', '3')] + [System.String] + $ClipboardFileType, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowPersistence, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowVirtualGPU, + + [Parameter()] + [ValidateSet('0', '1', '2', '4', '8')] + [System.Int32[]] + $PrintingSettings, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AllowCameraMicrophoneRedirection, + + [Parameter()] + [ValidateSet('0', '1')] + [System.String] + $AuditApplicationGuard, + + [Parameter()] + [System.String[]] + $CertificateThumbprints, + + [Parameter()] + [System.String[]] + $EnterpriseIPRange, + + [Parameter()] + [System.String[]] + $EnterpriseCloudResources, + + [Parameter()] + [System.String[]] + $EnterpriseNetworkDomainNames, + + [Parameter()] + [System.String[]] + $EnterpriseProxyServers, + + [Parameter()] + [System.String[]] + $EnterpriseInternalProxyServers, + + [Parameter()] + [System.String[]] + $NeutralResources, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseProxyServersAreAuthoritative, + + [Parameter()] + [ValidateSet('1', '0')] + [System.String] + $EnterpriseIPRangesAreAuthoritative, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance[]] + $Assignments, + #endregion + + [Parameter()] + [System.String] + [ValidateSet('Absent', 'Present')] + $Ensure = 'Present', + + [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 + ) + + #Ensure the proper dependencies are installed in the current environment. + Confirm-M365DSCDependencies + + #region Telemetry + $ResourceName = $MyInvocation.MyCommand.ModuleName.Replace('MSFT_', '') + $CommandName = $MyInvocation.MyCommand + $data = Format-M365DSCTelemetryParameters -ResourceName $ResourceName ` + -CommandName $CommandName ` + -Parameters $PSBoundParameters + Add-M365DSCTelemetryEvent -Data $data + #endregion + + Write-Verbose -Message "Testing configuration of the Intune App And Browser Isolation Policy for Windows10 with Id {$Id} and Name {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + [Hashtable]$ValuesToCheck = @{} + $MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { + if ($_.Key -notlike '*Variable' -or $_.Key -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction')) + { + if ($null -ne $CurrentValues[$_.Key] -or $null -ne $PSBoundParameters[$_.Key]) + { + $ValuesToCheck.Add($_.Key, $null) + if (-not $PSBoundParameters.ContainsKey($_.Key)) + { + $PSBoundParameters.Add($_.Key, $null) + } + } + } + } + + if ($CurrentValues.Ensure -ne $Ensure) + { + Write-Verbose -Message "Test-TargetResource returned $false" + return $false + } + $testResult = $true + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) + { + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-not $testResult) + { + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } + } + + $ValuesToCheck.Remove('Id') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck + + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + + if ($testResult) + { + $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.String] + $Filter, + + [Parameter()] + [System.Management.Automation.PSCredential] + $Credential, + + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ApplicationSecret, + + [Parameter()] + [System.String] + $CertificateThumbprint, + + [Parameter()] + [Switch] + $ManagedIdentity, + + [Parameter()] + [System.String[]] + $AccessTokens + ) + + $ConnectionMode = New-M365DSCConnection -Workload 'MicrosoftGraph' ` + -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 + { + #region resource generator code + $policyTemplateID = "9f667e40-8f3c-4f88-80d8-457f16906315_1" + [array]$getValue = Get-MgBetaDeviceManagementConfigurationPolicy ` + -Filter $Filter ` + -All ` + -ErrorAction Stop | Where-Object ` + -FilterScript { + $_.TemplateReference.TemplateId -eq $policyTemplateID + } + #endregion + + $i = 1 + $dscContent = '' + if ($getValue.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $getValue) + { + $displayedKey = $config.Id + if (-not [String]::IsNullOrEmpty($config.displayName)) + { + $displayedKey = $config.displayName + } + elseif (-not [string]::IsNullOrEmpty($config.name)) + { + $displayedKey = $config.name + } + Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline + $params = @{ + Id = $config.Id + DisplayName = $config.Name + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + AccessTokens = $AccessTokens + } + + $Results = Get-TargetResource @Params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results + + if ($Results.Assignments) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject $Results.Assignments -CIMInstanceName DeviceManagementConfigurationPolicyAssignments + if ($complexTypeStringResult) + { + $Results.Assignments = $complexTypeStringResult + } + else + { + $Results.Remove('Assignments') | Out-Null + } + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + + if ($Results.Assignments) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "Assignments" -IsCIMArray:$true + } + + $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_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.schema.mof new file mode 100644 index 0000000000..834c947e27 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10.schema.mof @@ -0,0 +1,48 @@ +[ClassVersion("1.0.0.0")] +class MSFT_DeviceManagementConfigurationPolicyAssignments +{ + [Write, Description("The type of the target assignment."), ValueMap{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}, Values{"#microsoft.graph.groupAssignmentTarget","#microsoft.graph.allLicensedUsersAssignmentTarget","#microsoft.graph.allDevicesAssignmentTarget","#microsoft.graph.exclusionGroupAssignmentTarget","#microsoft.graph.configurationManagerCollectionAssignmentTarget"}] String dataType; + [Write, Description("The type of filter of the target assignment i.e. Exclude or Include. Possible values are:none, include, exclude."), ValueMap{"none","include","exclude"}, Values{"none","include","exclude"}] String deviceAndAppManagementAssignmentFilterType; + [Write, Description("The Id of the filter for the target assignment.")] String deviceAndAppManagementAssignmentFilterId; + [Write, Description("The group Id that is the target of the assignment.")] String groupId; + [Write, Description("The group Display Name that is the target of the assignment.")] String groupDisplayName; + [Write, Description("The collection Id that is the target of the assignment.(ConfigMgr)")] String collectionId; +}; + + +[ClassVersion("1.0.0.0"), FriendlyName("IntuneAppAndBrowserIsolationPolicyWindows10")] +class MSFT_IntuneAppAndBrowserIsolationPolicyWindows10 : OMI_BaseResource +{ + [Write, Description("Policy description")] String Description; + [Key, Description("Policy name")] String DisplayName; + [Write, Description("List of Scope Tags for this Entity instance.")] String RoleScopeTagIds[]; + [Write, Description("The unique identifier for an entity. Read-only.")] String Id; + [Write, Description("Turn on Microsoft Defender Application Guard (0: Disable Microsoft Defender Application Guard, 1: Enable Microsoft Defender Application Guard for Microsoft Edge ONLY, 2: Enable Microsoft Defender Application Guard for isolated Windows environments ONLY, 3: Enable Microsoft Defender Application Guard for Microsoft Edge AND isolated Windows environments)"), ValueMap{"0", "1", "2", "3"}, Values{"0", "1", "2", "3"}] String AllowWindowsDefenderApplicationGuard; + [Write, Description("Clipboard behavior settings (0: Completely turns Off the clipboard functionality for the Application Guard., 1: Turns On clipboard operation from an isolated session to the host., 2: Turns On clipboard operation from the host to an isolated session., 3: Turns On clipboard operation in both the directions.)"), ValueMap{"0", "1", "2", "3"}, Values{"0", "1", "2", "3"}] String ClipboardSettings; + [Write, Description("Allow files to download and save to the host operating system (0: The user cannot download files from Edge in the container to the host file system. When the policy is not configured, it is the same as disabled (0)., 1: Turns on the functionality to allow users to download files from Edge in the container to the host file system.)"), ValueMap{"0", "1"}, Values{"0", "1"}] String SaveFilesToHost; + [Write, Description("Install Windows defender application guard (install: Install)"), ValueMap{"install"}, Values{"install"}] String InstallWindowsDefenderApplicationGuard; + [Write, Description("Clipboard content options (1: Allow text copying., 2: Allow image copying., 3: Allow text and image copying.)"), ValueMap{"1", "2", "3"}, Values{"1", "2", "3"}] String ClipboardFileType; + [Write, Description("Allow data persistence (0: Application Guard discards user-downloaded files and other items (such as, cookies, Favorites, and so on) during machine restart or user log-off., 1: Application Guard saves user-downloaded files and other items (such as, cookies, Favorites, and so on) for use in future Application Guard sessions.)"), ValueMap{"0", "1"}, Values{"0", "1"}] String AllowPersistence; + [Write, Description("Allow hardware-accelerated rendering (0: Cannot access the vGPU and uses the CPU to support rendering graphics. When the policy is not configured, it is the same as disabled (0)., 1: Turns on the functionality to access the vGPU offloading graphics rendering from the CPU. This can create a faster experience when working with graphics intense websites or watching video within the container.)"), ValueMap{"0", "1"}, Values{"0", "1"}] String AllowVirtualGPU; + [Write, Description("Print Settings (0: Disables all print functionality., 1: Enables only XPS printing., 2: Enables only PDF printing., 4: Enables only local printing., 8: Enables only network printing.)"), ValueMap{"0", "1", "2", "4", "8"}, Values{"0", "1", "2", "4", "8"}] SInt32 PrintingSettings[]; + [Write, Description("Allow camera and microphone access (0: Microsoft Defender Application Guard cannot access the device's camera and microphone. When the policy is not configured, it is the same as disabled (0)., 1: Turns on the functionality to allow Microsoft Defender Application Guard to access the device's camera and microphone.)"), ValueMap{"0", "1"}, Values{"0", "1"}] String AllowCameraMicrophoneRedirection; + [Write, Description("Audit Application Guard (0: Audit event logs aren't collected for Application Guard., 1: Application Guard inherits its auditing policies from system and starts to audit security events for Application Guard container.)"), ValueMap{"0", "1"}, Values{"0", "1"}] String AuditApplicationGuard; + [Write, Description("Certificate Thumbprints")] String CertificateThumbprints[]; + [Write, Description("Enterprise IP Range")] String EnterpriseIPRange[]; + [Write, Description("Enterprise Cloud Resources")] String EnterpriseCloudResources[]; + [Write, Description("Enterprise Network Domain Names")] String EnterpriseNetworkDomainNames[]; + [Write, Description("Enterprise Proxy Servers")] String EnterpriseProxyServers[]; + [Write, Description("Enterprise Internal Proxy Servers")] String EnterpriseInternalProxyServers[]; + [Write, Description("Neutral Resources")] String NeutralResources[]; + [Write, Description("Enterprise Proxy Servers Are Authoritative (1: Enable, 0: Disable)"), ValueMap{"1", "0"}, Values{"1", "0"}] String EnterpriseProxyServersAreAuthoritative; + [Write, Description("Enterprise IP Ranges Are Authoritative (1: Enable, 0: Disable)"), ValueMap{"1", "0"}, Values{"1", "0"}] String EnterpriseIPRangesAreAuthoritative; + [Write, Description("Represents the assignment to the Intune policy."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; + [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; + [Write, Description("Credentials of the 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("Secret of the Azure Active Directory tenant used for authentication."), EmbeddedInstance("MSFT_Credential")] String ApplicationSecret; + [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_IntuneAppAndBrowserIsolationPolicyWindows10/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/readme.md new file mode 100644 index 0000000000..311864ce6b --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/readme.md @@ -0,0 +1,6 @@ + +# IntuneAppAndBrowserIsolationPolicyWindows10 + +## Description + +Intune App And Browser Isolation Policy for Windows10 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/settings.json new file mode 100644 index 0000000000..fe0c097e79 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneAppAndBrowserIsolationPolicyWindows10/settings.json @@ -0,0 +1,33 @@ +{ + "resourceName": "IntuneAppAndBrowserIsolationPolicyWindows10", + "description": "This resource configures an Intune App And Browser Isolation Policy for Windows10.", + "permissions": { + "graph": { + "application": { + "read": [ + { + "name": "DeviceManagementConfiguration.Read.All" + } + ], + "update": [ + { + "name": "DeviceManagementConfiguration.ReadWrite.All" + } + ] + }, + "delegated": { + "read": [ + { + "name": "DeviceManagementConfiguration.Read.All" + } + ], + "update": [ + { + "name": "DeviceManagementConfiguration.ReadWrite.All" + } + ] + } + } +} + +} diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.psm1 index 047fb4e9e6..a7a6ad3a6e 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.psm1 @@ -12,6 +12,10 @@ function Get-TargetResource [System.String] $DisplayName, + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + [Parameter()] [System.String] $Description, @@ -96,106 +100,74 @@ function Get-TargetResource if ($null -eq $policy) { - Write-Verbose -Message "No Endpoint Detection And Response Policy with Id {$Identity} was found" - $policyTemplateID = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' - $filter = "name eq '$DisplayName' and templateReference/TemplateId eq '$policyTemplateID'" - $policy = Get-MgBetaDeviceManagementConfigurationPolicy -Filter $filter -ErrorAction SilentlyContinue - if ($null -eq $policy) + Write-Verbose -Message "Could not find an Intune Endpoint Detection And Response Policy for Windows10 with Id {$Identity}" + + if (-not [System.String]::IsNullOrEmpty($DisplayName)) { - Write-Verbose -Message "No Endpoint Detection And Response Policy with displayName {$DisplayName} was found" - return $nullResult + $policy = Get-MgBetaDeviceManagementConfigurationPolicy ` + -Filter "Name eq '$DisplayName'" ` + -ErrorAction SilentlyContinue } } - $policy = Get-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $policy.Id -ExpandProperty 'settings' -ErrorAction SilentlyContinue - + if ($null -eq $policy) + { + Write-Verbose -Message "Could not find an Intune Endpoint Detection And Response Policy for Windows10 with Name {$DisplayName}." + return $nullResult + } $Identity = $policy.Id + Write-Verbose -Message "An Intune Endpoint Detection And Response Policy for Windows10 with Id {$Identity} and Name {$DisplayName} was found" - Write-Verbose -Message "Found Endpoint Detection And Response Policy with Id {$($policy.id)} and displayName {$($policy.Name)}" - - #Retrieve policy specific settings - $settings = @() - $settings += $policy.settings + # Retrieve policy specific settings + [array]$settings = Get-MgBetaDeviceManagementConfigurationPolicySetting ` + -DeviceManagementConfigurationPolicyId $Identity ` + -ExpandProperty 'settingDefinitions' ` + -ErrorAction Stop - $returnHashtable = @{} - $returnHashtable.Add('Identity', $Identity) - $returnHashtable.Add('DisplayName', $policy.name) - $returnHashtable.Add('Description', $policy.description) - - foreach ($setting in $settings.settingInstance) + $policySettings = @{} + $policySettings = Export-IntuneSettingCatalogPolicySettings -Settings $settings -ReturnHashtable $policySettings + if ($policySettings.ClientConfigurationPackageType -eq 'onboarding_fromconnector') { - $addToParameters = $true - $settingName = $setting.settingDefinitionId.Split('_') | Select-Object -Last 1 - - switch ($setting.AdditionalProperties.'@odata.type') - { - - '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' - { - $settingValue = $setting.AdditionalProperties.simpleSettingValue.value - } - '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' - { - $settingValue = $setting.AdditionalProperties.choiceSettingValue.value.split('_') | Select-Object -Last 1 - } - '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance' - { - $values = @() - foreach ($value in $setting.AdditionalProperties.groupSettingCollectionValue.children) - { - $settingName = $value.settingDefinitionId.split('_') | Select-Object -Last 1 - $settingValue = $value.choiceSettingValue.value.split('_') | Select-Object -Last 1 - $returnHashtable.Add($settingName, $settingValue) - $addToParameters = $false - } - } - '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionInstance' - { - $values = @() - foreach ($value in $setting.AdditionalProperties.simpleSettingCollectionValue.value) - { - $values += $value - } - $settingValue = $values - } - Default - { - $settingValue = $setting.value - } - } - - if ($addToParameters) - { - $returnHashtable.Add($settingName, $settingValue) - } - + $policySettings.Add('ConfigurationType', 'AutoFromConnector') } - - #Removing telemetryreportingfrequency as deprecated and doen't need to be evaluated adn enforced - $returnHashtable.Remove('telemetryreportingfrequency') - - $returnAssignments = @() - $currentAssignments = Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $Identity -All - - if ($null -ne $currentAssignments -and $currentAssignments.count -gt 0 ) + else { - $returnAssignments += ConvertFrom-IntunePolicyAssignment -Assignments ($currentAssignments) + $policySettings.Add('ConfigurationType', $policySettings.ClientConfigurationPackageType) } + $policySettings.Remove('ClientConfigurationPackageType') + $policySettings.Remove('onboarding') + $policySettings.Remove('offboarding') + $policySettings.Remove('onboarding_fromconnector') + + # Removing TelemetryReportingFrequency because it's deprecated and doesn't need to be evaluated and enforced + $policySettings.Remove('telemetryreportingfrequency') + + $results = @{ + #region resource generator code + Description = $policy.Description + DisplayName = $policy.Name + RoleScopeTagIds = $policy.RoleScopeTagIds + Identity = $policy.Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + #endregion + } + $results += $policySettings - $returnHashtable.Add('Assignments', $returnAssignments) - - Write-Verbose -Message "Found Endpoint Protection Policy {$($policy.name)}" - - $returnHashtable.Add('Ensure', 'Present') - $returnHashtable.Add('Credential', $Credential) - $returnHashtable.Add('ApplicationId', $ApplicationId) - $returnHashtable.Add('TenantId', $TenantId) - $returnHashtable.Add('ApplicationSecret', $ApplicationSecret) - $returnHashtable.Add('CertificateThumbprint', $CertificateThumbprint) - $returnHashtable.Add('ManagedIdentity', $ManagedIdentity.IsPresent) - $returnHashtable.Add("AccessTokens", $AccessTokens) + $assignmentsValues = Get-MgBetaDeviceManagementConfigurationPolicyAssignment -DeviceManagementConfigurationPolicyId $Identity + $assignmentResult = @() + if ($assignmentsValues.Count -gt 0) + { + $assignmentResult += ConvertFrom-IntunePolicyAssignment -Assignments $assignmentsValues -IncludeDeviceFilter $true + } + $results.Add('Assignments', $assignmentResult) - return $returnHashtable + return $results } catch { @@ -222,6 +194,10 @@ function Set-TargetResource [System.String] $DisplayName, + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + [Parameter()] [System.String] $Description, @@ -291,14 +267,35 @@ function Set-TargetResource #endregion $currentPolicy = Get-TargetResource @PSBoundParameters - $PSBoundParameters.Remove('Ensure') | Out-Null - $PSBoundParameters.Remove('Credential') | Out-Null - $PSBoundParameters.Remove('ApplicationId') | Out-Null - $PSBoundParameters.Remove('TenantId') | Out-Null - $PSBoundParameters.Remove('ApplicationSecret') | Out-Null - $PSBoundParameters.Remove('CertificateThumbprint') | Out-Null - $PSBoundParameters.Remove('ManagedIdentity') | Out-Null - $PSBoundParameters.Remove('AccessTokens') | Out-Null + $BoundParameters = Remove-M365DSCAuthenticationParameter -BoundParameters $PSBoundParameters + + switch ($ConfigurationType) + { + 'AutoFromConnector' + { + $BoundParameters.Add('ClientConfigurationPackageType', 'onboarding_fromconnector') + $BoundParameters.Add('onboarding_fromconnector', $ConfigurationBlob) + $BoundParameters.Remove('ConfigurationBlob') | Out-Null + } + 'Onboard' + { + $BoundParameters.Add('ClientConfigurationPackageType', 'onboard') + $BoundParameters.Add('onboarding', $ConfigurationBlob) + $BoundParameters.Remove('ConfigurationBlob') | Out-Null + } + 'Offboard' + { + $BoundParameters.Add('ClientConfigurationPackageType', 'offboard') + $BoundParameters.Add('offboarding', $ConfigurationBlob) + $BoundParameters.Remove('ConfigurationBlob') | Out-Null + } + } + + if ([System.String]::IsNullOrEmpty($ConfigurationBlob)) + { + throw "ConfigurationBlob is required for configurationType '$($DSCParams.ConfigurationType)'" + } + $BoundParameters.Remove('ConfigurationType') | Out-Null $templateReferenceId = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' $platforms = 'windows10' @@ -306,82 +303,64 @@ function Set-TargetResource if ($Ensure -eq 'Present' -and $currentPolicy.Ensure -eq 'Absent') { - Write-Verbose -Message "Creating new Endpoint Protection Policy {$DisplayName}" - $PSBoundParameters.Remove('Assignments') | Out-Null + Write-Verbose -Message "Creating an Intune Endpoint Protection And Response Policy for Windows10 with Name {$DisplayName}" + $BoundParameters.Remove('Assignments') | Out-Null - $settings = @() - $formattedSettings = Get-IntuneSettingCatalogPolicySetting ` - -DSCParams ([System.Collections.Hashtable]$PSBoundParameters) ` + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` -TemplateId $templateReferenceId - if ($null -ne $formattedSettings) - { - $settings += $formattedSettings - } - $createParameters = @{ - name = $DisplayName - description = $Description - templateReference = @{templateId = $templateReferenceId } - platforms = $platforms - technologies = $technologies - settings = $settings + Name = $DisplayName + Description = $Description + TemplateReference = @{ templateId = $templateReferenceId } + Platforms = $platforms + Technologies = $technologies + Settings = $settings } - write-verbose ($createParameters|convertto-json -depth 100) + #region resource generator code $policy = New-MgBetaDeviceManagementConfigurationPolicy -bodyParameter $createParameters - $assignmentsHash = @() - if ($null -ne $Assignments -and $Assignments.count -gt 0 ) + if ($policy.Id) { - $assignmentsHash += ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments + Update-DeviceConfigurationPolicyAssignment ` + -DeviceConfigurationPolicyId $policy.Id ` + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' } - - Update-DeviceConfigurationPolicyAssignment ` - -DeviceConfigurationPolicyId $policy.id ` - -Targets $assignmentsHash - + #endregion } elseif ($Ensure -eq 'Present' -and $currentPolicy.Ensure -eq 'Present') { - Write-Verbose -Message "Updating existing Endpoint Protection Policy {$($currentPolicy.DisplayName)}" - $PSBoundParameters.Remove('Assignments') | Out-Null + Write-Verbose -Message "Updating the Intune Endpoint Protection And Response Policy for Windows10 {$($currentPolicy.DisplayName)}" + $BoundParameters.Remove('Assignments') | Out-Null - #format settings from PSBoundParameters for update - $settings = @() - $formattedSettings = Get-IntuneSettingCatalogPolicySetting ` - -DSCParams ([System.Collections.Hashtable]$PSBoundParameters) ` + $settings = Get-IntuneSettingCatalogPolicySetting ` + -DSCParams ([System.Collections.Hashtable]$BoundParameters) ` -TemplateId $templateReferenceId - if ($null -ne $formattedSettings) - { - $settings += $formattedSettings - } - - Update-DeviceManagementConfigurationPolicy ` - -DeviceManagementConfigurationPolicyId $currentPolicy.Identity ` - -DisplayName $DisplayName ` + Update-IntuneDeviceConfigurationPolicy ` + -DeviceConfigurationPolicyId $currentPolicy.Identity ` + -Name $DisplayName ` -Description $Description ` - -TemplateReference $templateReferenceId ` + -TemplateReferenceId $templateReferenceId ` -Platforms $platforms ` -Technologies $technologies ` -Settings $settings - #region update policy assignments - $assignmentsHash = @() - if ($null -ne $Assignments -and $Assignments.count -gt 0 ) - { - $assignmentsHash += ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments - } - + #region resource generator code + $assignmentsHash = ConvertTo-IntunePolicyAssignment -IncludeDeviceFilter:$true -Assignments $Assignments Update-DeviceConfigurationPolicyAssignment ` -DeviceConfigurationPolicyId $currentPolicy.Identity ` - -Targets $assignmentsHash + -Targets $assignmentsHash ` + -Repository 'deviceManagement/configurationPolicies' #endregion } elseif ($Ensure -eq 'Absent' -and $currentPolicy.Ensure -eq 'Present') { - Write-Verbose -Message "Removing Endpoint Protection Policy {$($currentPolicy.DisplayName)}" + Write-Verbose -Message "Removing the Intune Endpoint Protection And Response Policy for Windows 10 with Id {$($currentPolicy.Identity)}" Remove-MgBetaDeviceManagementConfigurationPolicy -DeviceManagementConfigurationPolicyId $currentPolicy.Identity } } @@ -400,6 +379,10 @@ function Test-TargetResource [System.String] $DisplayName, + [Parameter()] + [System.String[]] + $RoleScopeTagIds, + [Parameter()] [System.String] $Description, @@ -467,34 +450,69 @@ function Test-TargetResource -Parameters $PSBoundParameters Add-M365DSCTelemetryEvent -Data $data #endregion - Write-Verbose -Message "Testing configuration of Endpoint Protection Policy {$DisplayName}" + Write-Verbose -Message "Testing configuration of the Intune Endpoint Protection And Response Policy for Windows10 with Id {$Identity} and Name {$DisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters + [Hashtable]$ValuesToCheck = @{} + $MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { + if ($_.Key -notlike '*Variable' -or $_.Key -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction')) + { + if ($null -ne $CurrentValues[$_.Key] -or $null -ne $PSBoundParameters[$_.Key]) + { + $ValuesToCheck.Add($_.Key, $null) + if (-not $PSBoundParameters.ContainsKey($_.Key)) + { + $PSBoundParameters.Add($_.Key, $null) + } + } + } + } - Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" - Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" + if ($CurrentValues.Ensure -ne $Ensure) + { + Write-Verbose -Message "Test-TargetResource returned $false" + return $false + } + $testResult = $true + + #Compare Cim instances + foreach ($key in $PSBoundParameters.Keys) + { + $source = $PSBoundParameters.$key + $target = $CurrentValues.$key + if ($null -ne $source -and $source.GetType().Name -like '*CimInstance*') + { + $testResult = Compare-M365DSCComplexObject ` + -Source ($source) ` + -Target ($target) + + if (-not $testResult) + { + break + } + + $ValuesToCheck.Remove($key) | Out-Null + } + } - $ValuesToCheck = ([hashtable]$PSBoundParameters).clone() $ValuesToCheck.Remove('Identity') | Out-Null $ValuesToCheck.Remove('ConfigurationBlob') | Out-Null + $ValuesToCheck = Remove-M365DSCAuthenticationParameter -BoundParameters $ValuesToCheck - $source = $PSBoundParameters.Assignments - $target = $CurrentValues.Assignments - $ValuesToCheck.Remove('Assignments') | Out-Null - - $testResult = Compare-M365DSCIntunePolicyAssignment -Source $source -Target $target + Write-Verbose -Message "Current Values: $(Convert-M365DscHashtableToString -Hashtable $CurrentValues)" + Write-Verbose -Message "Target Values: $(Convert-M365DscHashtableToString -Hashtable $PSBoundParameters)" if ($testResult) { - $TestResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` + $testResult = Test-M365DSCParameterState -CurrentValues $CurrentValues ` -Source $($MyInvocation.MyCommand.Source) ` -DesiredValues $PSBoundParameters ` -ValuesToCheck $ValuesToCheck.Keys } - Write-Verbose -Message "Test-TargetResource returned $TestResult" + Write-Verbose -Message "Test-TargetResource returned $testResult" - return $TestResult + return $testResult } function Export-TargetResource @@ -558,9 +576,12 @@ function Export-TargetResource { $policyTemplateID = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' [array]$policies = Get-MgBetaDeviceManagementConfigurationPolicy ` - -All:$true ` + -All ` -Filter $Filter ` - -ErrorAction Stop | Where-Object -FilterScript { $_.TemplateReference.TemplateId -eq $policyTemplateID } ` + -ErrorAction Stop | Where-Object ` + -FilterScript { + $_.TemplateReference.TemplateId -eq $policyTemplateID + } if ($policies.Length -eq 0) { @@ -593,48 +614,38 @@ function Export-TargetResource } $Results = Get-TargetResource @params + $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` + -Results $Results - if ($Results.Ensure -eq 'Present') + if ($Results.Assignments) { - $Results = Update-M365DSCExportAuthenticationResults -ConnectionMode $ConnectionMode ` - -Results $Results - - if ($Results.Assignments) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject ([Array]$Results.Assignments) -CIMInstanceName DeviceManagementConfigurationPolicyAssignments + if ($complexTypeStringResult) { - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString -ComplexObject ([Array]$Results.Assignments) -CIMInstanceName DeviceManagementConfigurationPolicyAssignments - if ($complexTypeStringResult) - { - $Results.Assignments = $complexTypeStringResult - } - else - { - $Results.Remove('Assignments') | Out-Null - } + $Results.Assignments = $complexTypeStringResult } - - $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` - -ConnectionMode $ConnectionMode ` - -ModulePath $PSScriptRoot ` - -Results $Results ` - -Credential $Credential - - if ($Results.Assignments) + else { - $isCIMArray = $false - if ($Results.Assignments.getType().Fullname -like '*[[\]]') - { - $isCIMArray = $true - } - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName 'Assignments' -IsCIMArray:$isCIMArray + $Results.Remove('Assignments') | Out-Null } + } - $dscContent += $currentDSCBlock - Save-M365DSCPartialExport -Content $currentDSCBlock ` - -FileName $Global:PartialExportFileName + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential - Write-Host $Global:M365DSCEmojiGreenCheckMark - $i++ + if ($Results.Assignments) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "Assignments" -IsCIMArray:$true } + + $dscContent += $currentDSCBlock + Save-M365DSCPartialExport -Content $currentDSCBlock ` + -FileName $Global:PartialExportFileName + $i++ + Write-Host $Global:M365DSCEmojiGreenCheckMark } return $dscContent } @@ -661,278 +672,4 @@ function Export-TargetResource } } -function Get-IntuneSettingCatalogPolicySetting -{ - [CmdletBinding()] - [OutputType([System.Array])] - param( - [Parameter(Mandatory = 'true')] - [System.Collections.Hashtable] - $DSCParams, - [Parameter(Mandatory = 'true')] - [System.String] - $TemplateId - ) - - $DSCParams.Remove('Identity') | Out-Null - $DSCParams.Remove('DisplayName') | Out-Null - $DSCParams.Remove('Description') | Out-Null - - #Prepare setting definitions mapping - $settingDefinitions = Get-MgBetaDeviceManagementConfigurationPolicyTemplateSettingTemplate -DeviceManagementConfigurationPolicyTemplateId $TemplateId - $settingInstances = @() - foreach ($settingDefinition in $settingDefinitions.SettingInstanceTemplate) - { - - $settingInstance = @{} - $settingName = $settingDefinition.SettingDefinitionId.split('_') | Select-Object -Last 1 - $settingType = $settingDefinition.AdditionalProperties.'@odata.type'.replace('InstanceTemplate', 'Instance') - $settingInstance.Add('settingDefinitionId', $settingDefinition.settingDefinitionId) - $settingInstance.Add('@odata.type', $settingType) - if (-Not [string]::IsNullOrEmpty($settingDefinition.settingInstanceTemplateId)) - { - $settingInstance.Add('settingInstanceTemplateReference', @{'settingInstanceTemplateId' = $settingDefinition.settingInstanceTemplateId }) - } - $settingValueName = $settingType.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $settingValueName = $settingValueName.Substring(0, 1).ToLower() + $settingValueName.Substring(1, $settingValueName.length - 1 ) - $settingValueType = $settingDefinition.AdditionalProperties."$($settingValueName)Template".'@odata.type' - if ($null -ne $settingValueType) - { - $settingValueType = $settingValueType.replace('ValueTemplate', 'Value') - } - $settingValueTemplateId = $settingDefinition.AdditionalProperties."$($settingValueName)Template".settingValueTemplateId - $settingValue = Get-IntuneSettingCatalogPolicySettingInstanceValue ` - -DSCParams $DSCParams ` - -SettingDefinition $settingDefinition ` - -SettingName $settingName ` - -SettingType $settingType ` - -SettingValueName $settingValueName ` - -SettingValueType $settingValueType ` - -SettingValueTemplateId $settingValueTemplateId - - if ($null -ne $settingValue) { - $childSettingType = "" - switch ($DSCParams['ConfigurationType']) - { - 'AutoFromConnector' - { - $childSettingType = 'onboarding_fromconnector' - } - 'Onboard' - { - $childSettingType = 'onboarding' - } - 'Offboard' - { - $childSettingType = 'offboarding' - } - } - - if ($settingName -eq 'configurationType') - { - if ([System.String]::IsNullOrEmpty($DSCParams['ConfigurationBlob'])) - { - throw "ConfigurationBlob is required for configurationType '$($DSCParams['ConfigurationType'])'" - } - - $children = @() - $children += @{ - '@odata.type' = "#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance" - settingDefinitionId = "device_vendor_msft_windowsadvancedthreatprotection_$($childSettingType)" - simpleSettingValue = @{ - '@odata.type' = "#microsoft.graph.deviceManagementConfigurationSecretSettingValue" - value = $DSCParams['ConfigurationBlob'] - valueState = "NotEncrypted" - } - } - $settingValue.choiceSettingValue.Add("children", $children) - } - $settingInstance += ($settingValue) - $settingInstances += @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSetting' - 'settingInstance' = $settingInstance - } - } else { - Continue - } - } - - return $settingInstances -} - -function Get-IntuneSettingCatalogPolicySettingInstanceValue -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param( - [Parameter(Mandatory = 'true')] - [System.Collections.Hashtable] - $DSCParams, - - [Parameter()] - $SettingDefinition, - - [Parameter()] - [System.String] - $SettingType, - - [Parameter()] - [System.String] - $SettingName, - - [Parameter()] - [System.String] - $SettingValueName, - - [Parameter()] - [System.String] - $SettingValueType, - - [Parameter()] - [System.String] - $SettingValueTemplateId - ) - - $settingValueReturn = @{} - switch ($settingType) - { - '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance' - { - $groupSettingCollectionValue = @{} - $groupSettingCollectionValueChildren = @() - - $groupSettingCollectionDefinitionChildren = $SettingDefinition.AdditionalProperties.groupSettingCollectionValueTemplate.children - foreach ($childDefinition in $groupSettingCollectionDefinitionChildren) - { - $childSettingName = $childDefinition.settingDefinitionId.split('_') | Select-Object -Last 1 - $childSettingType = $childDefinition.'@odata.type'.replace('InstanceTemplate', 'Instance') - $childSettingValueName = $childSettingType.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $childSettingValueType = "#microsoft.graph.deviceManagementConfiguration$($childSettingValueName)" - $childSettingValueName = $childSettingValueName.Substring(0, 1).ToLower() + $childSettingValueName.Substring(1, $childSettingValueName.length - 1 ) - $childSettingValueTemplateId = $childDefinition.$childSettingValueName.settingValueTemplateId - $childSettingValue = Get-IntuneSettingCatalogPolicySettingInstanceValue ` - -DSCParams $DSCParams ` - -SettingDefinition $childDefinition ` - -SettingName $childSettingName ` - -SettingType $childDefinition.'@odata.type' ` - -SettingValueName $childSettingValueName ` - -SettingValueType $childSettingValueType ` - -SettingValueTemplateId $childSettingValueTemplateId - - if ($null -ne $childSettingValue) - { - $childSettingValue.add('settingDefinitionId', $childDefinition.settingDefinitionId) - $childSettingValue.add('@odata.type', $childSettingType ) - $groupSettingCollectionValueChildren += $childSettingValue - } - } - $groupSettingCollectionValue.add('children', $groupSettingCollectionValueChildren) - $settingValueReturn.Add('groupSettingCollectionValue', @($groupSettingCollectionValue)) - } - '#microsoft.graph.deviceManagementConfigurationSimpleSettingCollectionInstance' - { - $values = @() - foreach ( $key in $DSCParams.Keys) - { - if ($settingName -eq ($key.tolower())) - { - $values = $DSCParams[$key] - break - } - } - $settingValueCollection = @() - foreach ($v in $values) - { - $settingValueCollection += @{ - value = $v - '@odata.type' = $settingValueType - } - } - $settingValueReturn.Add($settingValueName, $settingValueCollection) - } - Default - { - $value = $null - foreach ( $key in $DSCParams.Keys) - { - if ($settingName -eq ($key.tolower())) - { - $value = "$($SettingDefinition.settingDefinitionId)_$($DSCParams[$key])" - break - } - } - $settingValue = @{} - - if (-Not [string]::IsNullOrEmpty($settingValueType)) - { - $settingValue.add('@odata.type', $settingValueType) - } - if (-Not [string]::IsNullOrEmpty($settingValueTemplateId)) - { - $settingValue.Add('settingValueTemplateReference', @{'settingValueTemplateId' = $settingValueTemplateId }) - } - $settingValue.add('value', $value) - if ($null -eq $value) - { - return $null - } - $settingValueReturn.Add($settingValueName, $settingValue) - } - } - return $settingValueReturn -} - -function Update-DeviceManagementConfigurationPolicy -{ - [CmdletBinding()] - param ( - [Parameter(Mandatory = 'true')] - [System.String] - $DeviceManagementConfigurationPolicyId, - - [Parameter(Mandatory = 'true')] - [System.String] - $DisplayName, - - [Parameter()] - [System.String] - $Description, - - [Parameter()] - [System.String] - $TemplateReferenceId, - - [Parameter()] - [System.String] - $Platforms, - - [Parameter()] - [System.String] - $Technologies, - - [Parameter()] - [System.Array] - $Settings - ) - - $templateReference = @{ - 'templateId' = $TemplateReferenceId - } - - $Uri = "https://graph.microsoft.com/beta/deviceManagement/ConfigurationPolicies/$DeviceManagementConfigurationPolicyId" - $policy = [ordered]@{ - 'name' = $DisplayName - 'description' = $Description - 'platforms' = $Platforms - 'technologies' = $Technologies - 'templateReference' = $templateReference - 'settings' = $Settings - } - #write-verbose (($policy|ConvertTo-Json -Depth 20)) - Invoke-MgGraphRequest -Method PUT ` - -Uri $Uri ` - -ContentType 'application/json' ` - -Body ($policy | ConvertTo-Json -Depth 20) 4> $null -} - Export-ModuleMember -Function *-TargetResource diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.schema.mof index 6b2b758d61..f4dc9d7295 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10/MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10.schema.mof @@ -14,6 +14,7 @@ class MSFT_IntuneEndpointDetectionAndResponsePolicyWindows10 : OMI_BaseResource { [Write, Description("Identity of the endpoint detection and response policy for Windows 10.")] String Identity; [Key, Description("Display name of the endpoint detection and response policy for Windows 10.")] String DisplayName; + [Write, Description("List of Scope Tags for this Entity instance.")] String RoleScopeTagIds[]; [Write, Description("Description of the endpoint detection and response policy for Windows 10.")] String Description; [Write, Description("Assignments of the endpoint detection and response policy for Windows 10."), EmbeddedInstance("MSFT_DeviceManagementConfigurationPolicyAssignments")] String Assignments[]; [Write, Description("Return or set Windows Defender Advanced Threat Protection Sample Sharing configuration parameter: 0 - none, 1 - All"), ValueMap{"0", "1"}, Values{"0", "1"}] String SampleSharing; diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADDeviceRegistrationPolicy/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADDeviceRegistrationPolicy/2-Update.ps1 new file mode 100644 index 0000000000..255c5e3155 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADDeviceRegistrationPolicy/2-Update.ps1 @@ -0,0 +1,43 @@ +<# +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 + { + AADDeviceRegistrationPolicy "MyDeviceRegistrationPolicy" + { + ApplicationId = $ApplicationId; + AzureADAllowedToJoin = "Selected"; + AzureADAllowedToJoinGroups = @(); + AzureADAllowedToJoinUsers = @("AlexW@M365x73318397.OnMicrosoft.com"); + AzureAdJoinLocalAdminsRegisteringGroups = @(); + AzureAdJoinLocalAdminsRegisteringMode = "Selected"; + AzureAdJoinLocalAdminsRegisteringUsers = @("AllanD@M365x73318397.OnMicrosoft.com"); + CertificateThumbprint = $CertificateThumbprint; + IsSingleInstance = "Yes"; + LocalAdminPasswordIsEnabled = $False; + LocalAdminsEnableGlobalAdmins = $True; + MultiFactorAuthConfiguration = $False; + TenantId = $TenantId; + UserDeviceQuota = 50; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/ADOPermissionGroupSettings/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/ADOPermissionGroupSettings/2-Update.ps1 new file mode 100644 index 0000000000..fe74d94ba6 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/ADOPermissionGroupSettings/2-Update.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()] + [PSCredential] + $Credential + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + ADOPermissionGroupSettings "ADOPermissionGroupSettings-O365DSC-DEV" + { + AllowPermissions = @( + MSFT_ADOPermission { + NamespaceId = '5a27515b-ccd7-42c9-84f1-54c998f03866' + DisplayName = 'Edit identity information' + Bit = '2' + Token = 'f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + } + ); + Credential = $Credential; + DenyPermissions = @(); + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + GroupName = "[O365DSC-DEV]\My Test Group"; + OrganizationName = "O365DSC-DEV"; + } + } +} 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 new file mode 100644 index 0000000000..58211df214 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/1-Create.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"; + 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"; + } + } +} 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..85ec1ba902 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/2-Update.ps1 @@ -0,0 +1,43 @@ +<# +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"; + 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"; + } + } +} 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..e1e47e2730 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/EXOMigrationEndpoint/3-Remove.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"; + 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"; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/1-Create.ps1 new file mode 100644 index 0000000000..b985c55712 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/1-Create.ps1 @@ -0,0 +1,51 @@ +<# +This example creates a new Device Remediation. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneAppAndBrowserIsolationPolicyWindows10 'ConfigureAppAndBrowserIsolationPolicyWindows10' + { + Assignments = @( + MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } + ); + AllowCameraMicrophoneRedirection = "1"; + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + ClipboardFileType = "1"; + ClipboardSettings = "0"; + Description = 'Description' + DisplayName = "App and Browser Isolation"; + Ensure = "Present"; + Id = '00000000-0000-0000-0000-000000000000' + InstallWindowsDefenderApplicationGuard = "install"; + SaveFilesToHost = "0"; + RoleScopeTagIds = @("0"); + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/2-Update.ps1 new file mode 100644 index 0000000000..8f3133d7cf --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/2-Update.ps1 @@ -0,0 +1,51 @@ +<# +This example updates a new Device Remediation. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneAppAndBrowserIsolationPolicyWindows10 'ConfigureAppAndBrowserIsolationPolicyWindows10' + { + Assignments = @( + MSFT_DeviceManagementConfigurationPolicyAssignments{ + deviceAndAppManagementAssignmentFilterType = 'none' + dataType = '#microsoft.graph.groupAssignmentTarget' + groupId = '11111111-1111-1111-1111-111111111111' + } + ); + AllowCameraMicrophoneRedirection = "0"; # Updated property + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + ClipboardFileType = "1"; + ClipboardSettings = "0"; + Description = 'Description' + DisplayName = "App and Browser Isolation"; + Ensure = "Present"; + Id = '00000000-0000-0000-0000-000000000000' + InstallWindowsDefenderApplicationGuard = "install"; + SaveFilesToHost = "0"; + RoleScopeTagIds = @("0"); + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/3-Remove.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/3-Remove.ps1 new file mode 100644 index 0000000000..a6a52ed29b --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneAppAndBrowserIsolationPolicyWindows10/3-Remove.ps1 @@ -0,0 +1,34 @@ +<# +This example removes a Device Remediation. +#> + +Configuration Example +{ + param( + [Parameter()] + [System.String] + $ApplicationId, + + [Parameter()] + [System.String] + $TenantId, + + [Parameter()] + [System.String] + $CertificateThumbprint + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + IntuneAppAndBrowserIsolationPolicyWindows10 'ConfigureAppAndBrowserIsolationPolicyWindows10' + { + Id = '00000000-0000-0000-0000-000000000000' + DisplayName = 'App and Browser Isolation' + Ensure = 'Absent' + ApplicationId = $ApplicationId; + TenantId = $TenantId; + CertificateThumbprint = $CertificateThumbprint; + } + } +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/1-Create.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/1-Create.ps1 index 2cf142bdf2..85a7af0f70 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/1-Create.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/1-Create.ps1 @@ -31,6 +31,9 @@ Configuration Example ApplicationId = $ApplicationId; TenantId = $TenantId; CertificateThumbprint = $CertificateThumbprint; + ConfigurationBlob = "Blob" + ConfigurationType = "onboard" + SampleSharing = 1 } } } diff --git a/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/2-Update.ps1 index 21679df4b0..e68894c238 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/2-Update.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/IntuneEndpointDetectionAndResponsePolicyWindows10/2-Update.ps1 @@ -31,6 +31,9 @@ Configuration Example ApplicationId = $ApplicationId; TenantId = $TenantId; CertificateThumbprint = $CertificateThumbprint; + ConfigurationBlob = "Blob" + ConfigurationType = "onboard" + SampleSharing = 1 } } } diff --git a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 index 962544bf28..8d1e1f69d7 100644 --- a/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 +++ b/Modules/Microsoft365DSC/Modules/M365DSCDRGUtil.psm1 @@ -501,7 +501,6 @@ function Get-M365DSCDRGSimpleObjectTypeToString [Parameter()] [System.String] $Space = ' ' - ) $returnValue = '' @@ -837,250 +836,6 @@ function Convert-M365DSCDRGComplexTypeToHashtable return [hashtable]$results } -function Get-SettingCatalogSettingValue -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable],[System.Collections.Hashtable[]])] - param ( - [Parameter()] - $SettingValue, - [Parameter()] - $SettingValueType - - ) - - switch -Wildcard ($SettingValueType) - { - '*ChoiceSettingInstance' - { - $complexValue = @{} - $complexValue.Add('odataType',$SettingValue.'@odata.type') - $complexValue.Add('Value',$SettingValue.value) - $children = @() - foreach($child in $SettingValue.children) - { - $complexChild = @{} - $complexChild.Add('SettingDefinitionId', $child.settingDefinitionId) - $complexChild.Add('odataType', $child.'@odata.type') - $valueName = $child.'@odata.type'.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $valueName = Get-StringFirstCharacterToLower -Value $valueName - $rawValue = $child.$valueName - $childSettingValue = Get-SettingCatalogSettingValue -SettingValue $rawValue -SettingValueType $child.'@odata.type' - $complexChild.Add($valueName,$childSettingValue) - $children += $complexChild - } - $complexValue.Add('Children',$children) - } - '*ChoiceSettingCollectionInstance' - { - $complexCollection = @() - foreach($item in $SettingValue) - { - $complexValue = @{} - $complexValue.Add('Value',$item.value) - $children = @() - foreach($child in $item.children) - { - $complexChild = @{} - $complexChild.Add('SettingDefinitionId', $child.settingDefinitionId) - $complexChild.Add('odataType', $child.'@odata.type') - $valueName = $child.'@odata.type'.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $valueName = Get-StringFirstCharacterToLower -Value $valueName - $rawValue = $child.$valueName - $childSettingValue = Get-SettingCatalogSettingValue -SettingValue $rawValue -SettingValueType $child.'@odata.type' - $complexChild.Add($valueName,$childSettingValue) - $children += $complexChild - } - $complexValue.Add('Children',$children) - $complexCollection += $complexValue - } - return ,([hashtable[]]$complexCollection) - } - '*SimpleSettingInstance' - { - $complexValue = @{} - $complexValue.Add('odataType',$SettingValue.'@odata.type') - $valueName = 'IntValue' - $value = $SettingValue.value - if($SettingValue.'@odata.type' -ne '#microsoft.graph.deviceManagementConfigurationIntegerSettingValue') - { - $valueName = 'StringValue' - } - $complexValue.Add($valueName,$value) - if($SettingValue.'@odata.type' -eq '#microsoft.graph.deviceManagementConfigurationSecretSettingValue') - { - $complexValue.Add('ValueState',$SettingValue.valueState) - } - } - '*SimpleSettingCollectionInstance' - { - $complexCollection = @() - - foreach($item in $SettingValue) - { - $complexValue = @{} - $complexValue.Add('odataType',$item.'@odata.type') - $valueName = 'IntValue' - $value = $item.value - if($item.'@odata.type' -ne '#microsoft.graph.deviceManagementConfigurationIntegerSettingValue') - { - $valueName = 'StringValue' - } - $complexValue.Add($valueName,$value) - if($item.'@odata.type' -eq '#microsoft.graph.deviceManagementConfigurationSecretSettingValue') - { - $complexValue.Add('ValueState',$item.valueState) - } - $complexCollection += $complexValue - } - return ,([hashtable[]]$complexCollection) - } - '*GroupSettingInstance' - { - $complexValue = @{} - $complexValue.Add('odataType',$SettingValue.'@odata.type') - $children = @() - foreach($child in $SettingValue.children) - { - $complexChild = @{} - $complexChild.Add('SettingDefinitionId', $child.settingDefinitionId) - $complexChild.Add('odataType', $child.'@odata.type') - $valueName = $child.'@odata.type'.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $valueName = Get-StringFirstCharacterToLower -Value $valueName - $rawValue = $child.$valueName - $settingValue = Get-SettingCatalogSettingValue -SettingValue $rawValue -SettingValueType $child.'@odata.type' - $complexChild.Add($valueName,$settingValue) - $children += $complexChild - } - $complexValue.Add('Children',$children) - } - '*GroupSettingCollectionInstance' - { - $complexCollection = @() - foreach($groupSettingValue in $SettingValue) - { - $complexValue = @{} - #$complexValue.Add('odataType',$SettingValue.'@odata.type') - $children = @() - foreach($child in $groupSettingValue.children) - { - $complexChild = @{} - $complexChild.Add('SettingDefinitionId', $child.settingDefinitionId) - $complexChild.Add('odataType', $child.'@odata.type') - $valueName = $child.'@odata.type'.replace('#microsoft.graph.deviceManagementConfiguration', '').replace('Instance', 'Value') - $valueName = Get-StringFirstCharacterToLower -Value $valueName - $rawValue = $child.$valueName - $settingValue = Get-SettingCatalogSettingValue -SettingValue $rawValue -SettingValueType $child.'@odata.type' - $complexChild.Add($valueName,$settingValue) - $children += $complexChild - } - $complexValue.Add('Children',$children) - $complexCollection += $complexValue - } - return ,([hashtable[]]$complexCollection) - } - } - return $complexValue -} - -function Get-SettingCatalogPolicySettingsFromTemplate -{ - [CmdletBinding()] - [OutputType([System.Array])] - param - ( - [Parameter(Mandatory = $true)] - [System.Collections.Hashtable] - $DSCParams, - - [Parameter(Mandatory = $true)] - [System.String] - $templateReferenceId - ) - - $DSCParams.Remove('Identity') | Out-Null - $DSCParams.Remove('DisplayName') | Out-Null - $DSCParams.Remove('Description') | Out-Null - - $settings = @() - - $templateSettings = Get-MgDeviceManagementConfigurationPolicyTemplateSettingTemplate -DeviceManagementConfigurationPolicyTemplateId $templateReferenceId - - $simpleSettings = @() - $simpleSettings += $templateSettings.SettingInstanceTemplate | Where-Object -FilterScript ` - { $_.AdditionalProperties.'@odata.type' -ne '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstanceTemplate' } - foreach ($templateSetting in $simpleSettings) - { - $setting = @{} - $settingKey = $DSCParams.keys | Where-Object -FilterScript { $templateSetting.settingDefinitionId -like "*$($_)" } - if ((-not [String]::IsNullOrEmpty($settingKey)) -and $DSCParams."$settingKey") - { - $setting.Add('@odata.type', '#microsoft.graph.deviceManagementConfigurationSetting') - $myFormattedSetting = Format-M365DSCParamsToSettingInstance -DSCParams @{$settingKey = $DSCParams."$settingKey" } ` - -TemplateSetting $templateSetting - - $setting.Add('settingInstance', $myFormattedSetting) - $settings += $setting - $DSCParams.Remove($settingKey) | Out-Null - } - } - - #Prepare attacksurfacereductionrules groupCollectionTemplateSettings - $groupCollectionTemplateSettings = @() - $groupCollectionTemplateSettings += $templateSettings.SettingInstanceTemplate | Where-Object -FilterScript ` - { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstanceTemplate' } - - foreach ($groupCollectionTemplateSetting in $groupCollectionTemplateSettings) - { - $setting = @{} - $setting.Add('@odata.type', '#microsoft.graph.deviceManagementConfigurationSetting') - $settingInstance = [ordered]@{} - $settingInstance.Add('@odata.type', '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance') - $settingInstance.Add('settingDefinitionId', $groupCollectionTemplateSetting.settingDefinitionId) - $settingInstance.Add('settingInstanceTemplateReference', @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSettingInstanceTemplateReference' - 'settingInstanceTemplateId' = $groupCollectionTemplateSetting.settingInstanceTemplateId - }) - $groupSettingCollectionValues = @() - $groupSettingCollectionValueChildren = @() - $groupSettingCollectionValue = @{} - $groupSettingCollectionValue.Add('@odata.type', '#microsoft.graph.deviceManagementConfigurationGroupSettingValue') - - $settingValueTemplateId = $groupCollectionTemplateSetting.AdditionalProperties.groupSettingCollectionValueTemplate.settingValueTemplateId - if (-Not [string]::IsNullOrEmpty($settingValueTemplateId)) - { - $groupSettingCollectionValue.Add('settingValueTemplateReference', @{'settingValueTemplateId' = $SettingValueTemplateId }) - } - - foreach ($key in $DSCParams.keys) - { - $templateValue = $groupCollectionTemplateSetting.AdditionalProperties.groupSettingCollectionValueTemplate.children | Where-Object ` - -FilterScript { $_.settingDefinitionId -like "*$key" } - if ($templateValue) - { - $groupSettingCollectionValueChild = Format-M365DSCParamsToSettingInstance ` - -DSCParams @{$key = $DSCParams."$key" } ` - -TemplateSetting $templateValue ` - -IncludeSettingValueTemplateId $false ` - -IncludeSettingInstanceTemplateId $false - - $groupSettingCollectionValueChildren += $groupSettingCollectionValueChild - } - } - $groupSettingCollectionValue.Add('children', $groupSettingCollectionValueChildren) - $groupSettingCollectionValues += $groupSettingCollectionValue - $settingInstance.Add('groupSettingCollectionValue', $groupSettingCollectionValues) - $setting.Add('settingInstance', $settingInstance) - - if ($setting.settingInstance.groupSettingCollectionValue.children.count -gt 0) - { - $settings += $setting - } - } - - return $settings -} - function ConvertFrom-IntunePolicyAssignment { [CmdletBinding()] @@ -1965,6 +1720,11 @@ function Get-IntuneSettingCatalogPolicySettingInstanceValue $settingValue = @{} if (-not [string]::IsNullOrEmpty($SettingValueType)) { + if ($SettingDefinition.AdditionalProperties.valueDefinition.isSecret) + { + $SettingValueType = "#microsoft.graph.deviceManagementConfigurationSecretSettingValue" + $settingValue.Add('valueState', 'NotEncrypted') + } $settingValue.Add('@odata.type', $SettingValueType) } if (-not [string]::IsNullOrEmpty($settingValueTemplateId)) diff --git a/Modules/Microsoft365DSC/SchemaDefinition.json b/Modules/Microsoft365DSC/SchemaDefinition.json index 7ddbbc82c7..b836530747 100644 --- a/Modules/Microsoft365DSC/SchemaDefinition.json +++ b/Modules/Microsoft365DSC/SchemaDefinition.json @@ -2904,6 +2904,106 @@ } ] }, + { + "ClassName": "MSFT_AADDeviceRegistrationPolicy", + "Parameters": [ + { + "CIMType": "String", + "Name": "IsSingleInstance", + "Option": "Key" + }, + { + "CIMType": "Boolean", + "Name": "AzureADJoinIsAdminConfigurable", + "Option": "Write" + }, + { + "CIMType": "UInt32", + "Name": "UserDeviceQuota", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "AzureADAllowedToJoin", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AzureADAllowedToJoinUsers", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AzureADAllowedToJoinGroups", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "MultiFactorAuthConfiguration", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "LocalAdminsEnableGlobalAdmins", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "AzureAdJoinLocalAdminsRegisteringMode", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AzureAdJoinLocalAdminsRegisteringGroups", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AzureAdJoinLocalAdminsRegisteringUsers", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "LocalAdminPasswordIsEnabled", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "Credential", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "ApplicationId", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "TenantId", + "Option": "Write" + }, + { + "CIMType": "MSFT_Credential", + "Name": "ApplicationSecret", + "Option": "Write" + }, + { + "CIMType": "String", + "Name": "CertificateThumbprint", + "Option": "Write" + }, + { + "CIMType": "Boolean", + "Name": "ManagedIdentity", + "Option": "Write" + }, + { + "CIMType": "String[]", + "Name": "AccessTokens", + "Option": "Write" + } + ] + }, { "ClassName": "MSFT_AccessPackageResourceRoleScope", "Parameters": [ @@ -5874,6 +5974,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": [ @@ -12359,6 +12544,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": [ @@ -33652,6 +33967,11 @@ "Name": "DisplayName", "Option": "Key" }, + { + "CIMType": "String[]", + "Name": "RoleScopeTagIds", + "Option": "Write" + }, { "CIMType": "String", "Name": "Description", diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 index 674cb2f4c3..394e108f0e 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.AAD.Update.Tests.ps1 @@ -612,6 +612,23 @@ CertificateThumbprint = $CertificateThumbprint Ensure = "Present"; } + AADDeviceRegistrationPolicy 'MyDeviceRegistrationPolicy' + { + ApplicationId = $ApplicationId; + AzureADAllowedToJoin = "Selected"; + AzureADAllowedToJoinGroups = @(); + AzureADAllowedToJoinUsers = @("AlexW@M365x73318397.OnMicrosoft.com"); + AzureAdJoinLocalAdminsRegisteringGroups = @(); + AzureAdJoinLocalAdminsRegisteringMode = "Selected"; + AzureAdJoinLocalAdminsRegisteringUsers = @("AllanD@M365x73318397.OnMicrosoft.com"); + CertificateThumbprint = $CertificateThumbprint; + IsSingleInstance = "Yes"; + LocalAdminPasswordIsEnabled = $False; + LocalAdminsEnableGlobalAdmins = $True; + MultiFactorAuthConfiguration = $False; + TenantId = $TenantId; + UserDeviceQuota = 50; + } AADEntitlementManagementAccessPackage 'myAccessPackage' { AccessPackagesIncompatibleWith = @(); 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" 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" 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" diff --git a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 index f60efd6f58..d61fd36960 100644 --- a/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 +++ b/Tests/Integration/Microsoft365DSC/M365DSCIntegration.INTUNE.Create.Tests.ps1 @@ -2288,6 +2288,9 @@ ApplicationId = $ApplicationId; TenantId = $TenantId; CertificateThumbprint = $CertificateThumbprint; + ConfigurationBlob = "Blob" + ConfigurationType = "onboard" + SampleSharing = 1 } IntuneExploitProtectionPolicyWindows10SettingCatalog 'myWindows10ExploitProtectionPolicy' { diff --git a/Tests/QA/Graph.PermissionList.txt b/Tests/QA/Graph.PermissionList.txt index 3acae21c4a..bb13a7818d 100644 --- a/Tests/QA/Graph.PermissionList.txt +++ b/Tests/QA/Graph.PermissionList.txt @@ -1 +1 @@ -AccessReview.Read.All,AccessReview.ReadWrite.All,AccessReview.ReadWrite.Membership,AdministrativeUnit.Read.All,AdministrativeUnit.ReadWrite.All,Agreement.Read.All,AppCatalog.ReadWrite.All,AppCertTrustConfiguration.Read.All,AppCertTrustConfiguration.ReadWrite.All,Application.Read.All,Application.ReadWrite.All,Application.ReadWrite.OwnedBy,Application-RemoteDesktopConfig.ReadWrite.All,AppRoleAssignment.ReadWrite.All,BrowserSiteLists.Read.All,BrowserSiteLists.ReadWrite.All,Calendars.Read,Calendars.ReadBasic,Calendars.ReadWrite,Channel.Delete.All,ChannelMember.ReadWrite.All,ChannelSettings.Read.All,ChannelSettings.ReadWrite.All,CloudPC.Read.All,CloudPC.ReadWrite.All,CrossTenantUserProfileSharing.Read.All,CrossTenantUserProfileSharing.ReadWrite.All,CustomSecAttributeDefinition.Read.All,CustomSecAttributeDefinition.ReadWrite.All,CustomSecAttributeProvisioning.Read.All,CustomSecAttributeProvisioning.ReadWrite.All,DelegatedPermissionGrant.ReadWrite.All,Device.Read.All,Device.ReadWrite.All,DeviceManagement.Scripts.Read.All,DeviceManagement.Scripts.ReadWrite.All,DeviceManagementApps.Read.All,DeviceManagementApps.ReadWrite.All,DeviceManagementConfiguration.Read.All,DeviceManagementConfiguration.ReadWrite.All,DeviceManagementManagedDevices.Read.All,DeviceManagementManagedDevices.ReadWrite.All,DeviceManagementRBAC.Read.All,DeviceManagementRBAC.ReadWrite.All,DeviceManagementServiceConfig.Read.All,DeviceManagementServiceConfig.ReadWrite.All,Directory.Read.All,Directory.ReadWrite.All,DirectoryRecommendations.Read.All,DirectoryRecommendations.ReadWrite.All,Domain.Read.All,Domain.ReadWrite.All,EntitlementManagement.Read.All,EntitlementManagement.ReadWrite.All,Group.Create,Group.Read.All,Group.ReadWrite.All,Group-Conversation.Read.All,Group-Conversation.ReadWrite.All,GroupMember.Read.All,GroupMember.ReadWrite.All,IdentityProvider.Read.All,IdentityProvider.ReadWrite.All,Organization.Read.All,Organization.ReadWrite.All,OrganizationalBranding.Read.All,OrganizationalBranding.ReadWrite.All,OrgContact.Read.All,OrgSettings-AppsAndServices.Read.All,OrgSettings-DynamicsVoice.Read.All,OrgSettings-Forms.Read.All,OrgSettings-Microsoft365Install.Read.All,OrgSettings-Todo.Read.All,PeopleSettings.Read.All,PeopleSettings.ReadWrite.All,Policy.Read.All,Policy.Read.ApplicationConfiguration,Policy.Read.ConditionalAccess,Policy.ReadWrite.ApplicationConfiguration,Policy.ReadWrite.AuthenticationMethod,Policy.ReadWrite.Authorization,Policy.ReadWrite.ConditionalAccess,ProfilePhoto.Read.All,ProfilePhoto.ReadWrite.All,ReportSettings.Read.All,RoleEligibilitySchedule.Read.Directory,RoleManagement.Read.All,RoleManagement.Read.CloudPC,RoleManagement.Read.Directory,RoleManagement.Read.Exchange,RoleManagement.ReadWrite.CloudPC,RoleManagement.ReadWrite.Directory,RoleManagement.ReadWrite.Exchange,RoleManagementPolicy.Read.Directory,SharePointTenantSettings.Read.All,Synchronization.Read.All,Synchronization.ReadWrite.All,Tasks.Read.All,TeamSettings.ReadWrite.All,User.Read.All,User.ReadWrite.All,EntitlementManagement.Read.All,ExternalConnection.Read.All,ExternalConnection.ReadWrite.All, +AccessReview.Read.All,AccessReview.ReadWrite.All,AccessReview.ReadWrite.Membership,AdministrativeUnit.Read.All,AdministrativeUnit.ReadWrite.All,Agreement.Read.All,AppCatalog.ReadWrite.All,AppCertTrustConfiguration.Read.All,AppCertTrustConfiguration.ReadWrite.All,Application.Read.All,Application.ReadWrite.All,Application.ReadWrite.OwnedBy,Application-RemoteDesktopConfig.ReadWrite.All,AppRoleAssignment.ReadWrite.All,BrowserSiteLists.Read.All,BrowserSiteLists.ReadWrite.All,Calendars.Read,Calendars.ReadBasic,Calendars.ReadWrite,Channel.Delete.All,ChannelMember.ReadWrite.All,ChannelSettings.Read.All,ChannelSettings.ReadWrite.All,CloudPC.Read.All,CloudPC.ReadWrite.All,CrossTenantUserProfileSharing.Read.All,CrossTenantUserProfileSharing.ReadWrite.All,CustomSecAttributeDefinition.Read.All,CustomSecAttributeDefinition.ReadWrite.All,CustomSecAttributeProvisioning.Read.All,CustomSecAttributeProvisioning.ReadWrite.All,DelegatedPermissionGrant.ReadWrite.All,Device.Read.All,Device.ReadWrite.All,DeviceManagement.Scripts.Read.All,DeviceManagement.Scripts.ReadWrite.All,DeviceManagementApps.Read.All,DeviceManagementApps.ReadWrite.All,DeviceManagementConfiguration.Read.All,DeviceManagementConfiguration.ReadWrite.All,DeviceManagementManagedDevices.Read.All,DeviceManagementManagedDevices.ReadWrite.All,DeviceManagementRBAC.Read.All,DeviceManagementRBAC.ReadWrite.All,DeviceManagementServiceConfig.Read.All,DeviceManagementServiceConfig.ReadWrite.All,Directory.Read.All,Directory.ReadWrite.All,DirectoryRecommendations.Read.All,DirectoryRecommendations.ReadWrite.All,Domain.Read.All,Domain.ReadWrite.All,EntitlementManagement.Read.All,EntitlementManagement.ReadWrite.All,Group.Create,Group.Read.All,Group.ReadWrite.All,Group-Conversation.Read.All,Group-Conversation.ReadWrite.All,GroupMember.Read.All,GroupMember.ReadWrite.All,IdentityProvider.Read.All,IdentityProvider.ReadWrite.All,Organization.Read.All,Organization.ReadWrite.All,OrganizationalBranding.Read.All,OrganizationalBranding.ReadWrite.All,OrgContact.Read.All,OrgSettings-AppsAndServices.Read.All,OrgSettings-DynamicsVoice.Read.All,OrgSettings-Forms.Read.All,OrgSettings-Microsoft365Install.Read.All,OrgSettings-Todo.Read.All,PeopleSettings.Read.All,PeopleSettings.ReadWrite.All,Policy.Read.All,Policy.Read.ApplicationConfiguration,Policy.Read.ConditionalAccess,Policy.ReadWrite.ApplicationConfiguration,Policy.ReadWrite.AuthenticationMethod,Policy.ReadWrite.Authorization,Policy.ReadWrite.ConditionalAccess,ProfilePhoto.Read.All,ProfilePhoto.ReadWrite.All,ReportSettings.Read.All,RoleEligibilitySchedule.Read.Directory,RoleManagement.Read.All,RoleManagement.Read.CloudPC,RoleManagement.Read.Directory,RoleManagement.Read.Exchange,RoleManagement.ReadWrite.CloudPC,RoleManagement.ReadWrite.Directory,RoleManagement.ReadWrite.Exchange,RoleManagementPolicy.Read.Directory,SharePointTenantSettings.Read.All,Synchronization.Read.All,Synchronization.ReadWrite.All,Tasks.Read.All,TeamSettings.ReadWrite.All,User.Read.All,User.ReadWrite.All,EntitlementManagement.Read.All,ExternalConnection.Read.All,ExternalConnection.ReadWrite.All,UserAuthenticationMethod.Read.All,Policy.Read.DeviceConfiguration, diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADDeviceRegistrationPolicy.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADDeviceRegistrationPolicy.Tests.ps1 new file mode 100644 index 0000000000..5a438157f0 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADDeviceRegistrationPolicy.Tests.ps1 @@ -0,0 +1,227 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "AADDeviceRegistrationPolicy" -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 Update-MgBetaDirectoryAttributeSet -MockWith { + } + + Mock -CommandName Remove-MgBetaDirectoryAttributeSet -MockWith { + } + + Mock -CommandName Get-MgUser -MockWith { + return @{ + id = '12345-12345-12345-12345-12345' + UserPrincipalName = "john.smith@contoso.com" + } + } + + Mock -CommandName Invoke-MgGraphRequest -MockWith { + return $null + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AzureADAllowedToJoin = "None"; + AzureADAllowedToJoinGroups = @(); + AzureADAllowedToJoinUsers = @(); + AzureAdJoinLocalAdminsRegisteringGroups = @(); + AzureAdJoinLocalAdminsRegisteringMode = "Selected"; + AzureAdJoinLocalAdminsRegisteringUsers = @("john.smith@contoso.com"); + IsSingleInstance = "Yes"; + LocalAdminPasswordIsEnabled = $False; + LocalAdminsEnableGlobalAdmins = $True; + MultiFactorAuthConfiguration = $False; + UserDeviceQuota = 50; + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyDeviceRegistrationPolicy -MockWith { + return @{ + AzureAdJoin = @{ + IsAdminConfigurable = $true + AllowedToJoin = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + LocalAdmins = @{ + EnableGlobalAdmins = $true + RegisteringUsers = @{ + AdditionalProperties = @{ + "@odata.type" = "#microsoft.graph.enumeratedDeviceRegistrationMembership" + users = @('12345-12345-12345-12345-12345') + groups = @() + } + } + } + } + AzureADRegistration = @{ + IsAdminConfigurable = $false + AllowedToRegister = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + } + Description = "Tenant-wide policy that manages initial provisioning controls using quota restrictions, additional authentication and authorization checks" + DisplayName = "Device Registration Policy" + Id = "deviceRegistrationPolicy" + LocalAdminPassword = @{ + IsEnabled = $false + } + MultiFactorAuthConfiguration = "notRequired" + UserDeviceQuota = 50 + } + } + } + + 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 = @{ + AzureADAllowedToJoin = "Selected"; + AzureADAllowedToJoinGroups = @(); + AzureADAllowedToJoinUsers = @("john.smith@contoso.com"); + AzureAdJoinLocalAdminsRegisteringGroups = @(); + AzureAdJoinLocalAdminsRegisteringMode = "Selected"; + AzureAdJoinLocalAdminsRegisteringUsers = @("john.smith@contoso.com"); + IsSingleInstance = "Yes"; + LocalAdminPasswordIsEnabled = $False; + LocalAdminsEnableGlobalAdmins = $False; # drift + MultiFactorAuthConfiguration = $False; + UserDeviceQuota = 50; + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyDeviceRegistrationPolicy -MockWith { + return @{ + AzureAdJoin = @{ + IsAdminConfigurable = $true + AllowedToJoin = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + LocalAdmins = @{ + EnableGlobalAdmins = $true + RegisteringUsers = @{ + users = @() + groups = @() + "@odata.type" = "#microsoft.graph.enumeratedDeviceRegistrationMembership" + } + } + } + AzureADRegistration = @{ + IsAdminConfigurable = $false + AllowedToRegister = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + } + Description = "Tenant-wide policy that manages initial provisioning controls using quota restrictions, additional authentication and authorization checks" + DisplayName = "Device Registration Policy" + Id = "deviceRegistrationPolicy" + LocalAdminPassword = @{ + IsEnabled = $false + } + MultiFactorAuthConfiguration = "notRequired" + UserDeviceQuota = 50 + } + } + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Invoke-MgGraphRequest -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaPolicyDeviceRegistrationPolicy -MockWith { + return @{ + AzureAdJoin = @{ + IsAdminConfigurable = $true + AllowedToJoin = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + LocalAdmins = @{ + EnableGlobalAdmins = $true + RegisteringUsers = @{ + users = @() + groups = @() + "@odata.type" = "#microsoft.graph.enumeratedDeviceRegistrationMembership" + } + } + } + AzureADRegistration = @{ + IsAdminConfigurable = $false + AllowedToRegister = @{ + "@odata.type" = "#microsoft.graph.allDeviceRegistrationMembership" + } + } + Description = "Tenant-wide policy that manages initial provisioning controls using quota restrictions, additional authentication and authorization checks" + DisplayName = "Device Registration Policy" + Id = "deviceRegistrationPolicy" + LocalAdminPassword = @{ + IsEnabled = $false + } + MultiFactorAuthConfiguration = "notRequired" + UserDeviceQuota = 50 + } + } + } + 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.ADOPermissionGroupSettings.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ADOPermissionGroupSettings.Tests.ps1 new file mode 100644 index 0000000000..2ac94144c9 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.ADOPermissionGroupSettings.Tests.ps1 @@ -0,0 +1,169 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$CurrentScriptPath = $PSCommandPath.Split('\') +$CurrentScriptName = $CurrentScriptPath[$CurrentScriptPath.Length -1] +$ResourceName = $CurrentScriptName.Split('.')[1] +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource $ResourceName -GenericStubModule $GenericStubPath + +Describe -Name $Global:DscHelper.DescribeHeader -Fixture { + InModuleScope -ModuleName $Global:DscHelper.ModuleName -ScriptBlock { + Invoke-Command -ScriptBlock $Global:DscHelper.InitializeScript -NoNewScope + BeforeAll { + + $secpasswd = ConvertTo-SecureString (New-Guid | Out-String) -AsPlainText -Force + $Credential = New-Object System.Management.Automation.PSCredential ('tenantadmin@mydomain.com', $secpasswd) + + Mock -CommandName Confirm-M365DSCDependencies -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + } + # Test contexts + + Context -Name "The instance exists and values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AllowPermissions = @( + (New-Ciminstance -className MSFT_ADOPermission -Property @{ + NamespaceId = '5a27515b-ccd7-42c9-84f1-54c998f03866' + DisplayName = 'Edit identity information' + Bit = '2' + Token = 'f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + } -ClientOnly) + ); + Credential = $Credential; + DenyPermissions = @(); + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + GroupName = "[O365DSC-DEV]\My Test Group"; + OrganizationName = "O365DSC-DEV"; + } + + Mock -CommandName Invoke-M365DSCAzureDevOPSWebRequest -MockWith { + return @{ + value = @{ + token ='f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + acesDictionary = @( + @{ + descriptor = @{ + Allow = 2 + Deny = 0 + } + } + ) + } + principalName = "[O365DSC-DEV]\My Test Group" + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + } + } + } + + 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 = @{ + AllowPermissions = @( + (New-Ciminstance -className MSFT_ADOPermission -Property @{ + NamespaceId = '5a27515b-ccd7-42c9-84f1-54c998f03866' + DisplayName = 'Edit identity information' + Bit = '8' # Drift + Token = 'f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + } -ClientOnly) + ); + Credential = $Credential; + DenyPermissions = @(); + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + GroupName = "[O365DSC-DEV]\My Test Group"; + OrganizationName = "O365DSC-DEV"; + } + + Mock -CommandName Invoke-M365DSCAzureDevOPSWebRequest -MockWith { + return @{ + value = @{ + token ='f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + acesDictionary = @( + @{ + descriptor = @{ + Allow = 2 + Deny = 0 + } + } + ) + principalName = "[O365DSC-DEV]\My Test Group" + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + } + } + } + } + + It 'Should return false from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should call the Set method' { + Set-TargetResource @testParams + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential; + } + + Mock -CommandName Invoke-M365DSCAzureDevOPSWebRequest -MockWith { + return @{ + value = @{ + token ='f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + acesDictionary = @( + @{ + descriptor = @{ + Allow = 2 + Deny = 0 + } + } + ) + principalName = "[O365DSC-DEV]\My Test Group" + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + AccountName = 'O365DSC-Dev' + } + } + } + } + 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.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.IntuneAppAndBrowserIsolationPolicyWindows10.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneAppAndBrowserIsolationPolicyWindows10.Tests.ps1 new file mode 100644 index 0000000000..c72f26f30e --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneAppAndBrowserIsolationPolicyWindows10.Tests.ps1 @@ -0,0 +1,347 @@ +[CmdletBinding()] +param( +) +$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` + -ChildPath '..\..\Unit' ` + -Resolve +$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Microsoft365.psm1' ` + -Resolve) +$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\Stubs\Generic.psm1' ` + -Resolve) +Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` + -ChildPath '\UnitTestHelper.psm1' ` + -Resolve) + +$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` + -DscResource "IntuneAppAndBrowserIsolationPolicyWindows10" -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 Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + + Mock -CommandName Update-MgBetaDeviceManagementConfigurationPolicy -MockWith { + } + + Mock -CommandName New-MgBetaDeviceManagementConfigurationPolicy -MockWith { + } + + Mock -CommandName Remove-MgBetaDeviceManagementConfigurationPolicy -MockWith { + } + + Mock -CommandName Update-IntuneDeviceConfigurationPolicy -MockWith { + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { + return @{ + Id = '12345-12345-12345-12345-12345' + Description = 'My Test' + Name = 'Test' + RoleScopeTagIds = @("FakeStringValue") + TemplateReference = @{ + TemplateId = '9f667e40-8f3c-4f88-80d8-457f16906315_1' + } + } + } + + Mock -CommandName Get-IntuneSettingCatalogPolicySetting -MockWith { + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { + return @( + @{ + Id = '0' + SettingDefinitions = @( + @{ + Id = 'device_vendor_msft_windowsdefenderapplicationguard_installwindowsdefenderapplicationguard' + Name = 'InstallWindowsDefenderApplicationGuard' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + }, + @{ + Id = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowwindowsdefenderapplicationguard' + Name = 'AllowWindowsDefenderApplicationGuard' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + }, + @{ + Id = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowpersistence' + Name = 'AllowPersistence' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + }, + @{ + Id = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowvirtualgpu' + Name = 'AllowVirtualGPU' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + }, + @{ + Id = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowcameramicrophoneredirection' + Name = 'AllowCameraMicrophoneRedirection' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + } + ) + Settinginstance = @{ + SettingDefinitionId = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowwindowsdefenderapplicationguard' + SettingInstanceTemplateReference = @{ + SettingInstanceTemplateId = '1f2529c7-4b06-4ae6-bebc-210f7135676f' + } + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + choiceSettingValue = @{ + children = @( + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowpersistence' + choiceSettingValue = @{ + children = @() + value = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowpersistence_0' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowvirtualgpu' + choiceSettingValue = @{ + children = @() + value = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowvirtualgpu_0' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowcameramicrophoneredirection' + choiceSettingValue = @{ + children = @() + value = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowcameramicrophoneredirection_1' + } + }, + @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + settingDefinitionId = 'device_vendor_msft_windowsdefenderapplicationguard_installwindowsdefenderapplicationguard' + choiceSettingValue = @{ + children = @() + value = 'device_vendor_msft_windowsdefenderapplicationguard_installwindowsdefenderapplicationguard_install' + } + } + ) + value = 'device_vendor_msft_windowsdefenderapplicationguard_settings_allowwindowsdefenderapplicationguard_1' + } + } + } + } + ) + } + + Mock -CommandName Update-DeviceConfigurationPolicyAssignment -MockWith { + } + + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" + } + + # Mock Write-Host to hide output during the tests + Mock -CommandName Write-Host -MockWith { + } + $Script:exportedInstances =$null + $Script:ExportMode = $false + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicyAssignment -MockWith { + return @(@{ + Id = '12345-12345-12345-12345-12345' + Source = 'direct' + SourceId = '12345-12345-12345-12345-12345' + Target = @{ + DeviceAndAppManagementAssignmentFilterId = '12345-12345-12345-12345-12345' + DeviceAndAppManagementAssignmentFilterType = 'none' + AdditionalProperties = @( + @{ + '@odata.type' = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + } + ) + } + }) + } + + } + # Test contexts + Context -Name "The IntuneAppAndBrowserIsolationPolicyWindows10 should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + AllowCameraMicrophoneRedirection = "1"; + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + InstallWindowsDefenderApplicationGuard = "install"; + Description = "My Test" + Id = "12345-12345-12345-12345-12345" + DisplayName = "Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = "Present" + Credential = $Credential; + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -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 the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName New-MgBetaDeviceManagementConfigurationPolicy -Exactly 1 + } + } + + Context -Name "The IntuneAppAndBrowserIsolationPolicyWindows10 exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + AllowCameraMicrophoneRedirection = "1"; + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + InstallWindowsDefenderApplicationGuard = "install"; + Description = "My Test" + Id = "12345-12345-12345-12345-12345" + DisplayName = "Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = 'Absent' + Credential = $Credential; + } + } + + It 'Should return Values from the Get method' { + (Get-TargetResource @testParams).Ensure | Should -Be 'Present' + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $false + } + + It 'Should Remove the group from the Set method' { + Set-TargetResource @testParams + Should -Invoke -CommandName Remove-MgBetaDeviceManagementConfigurationPolicy -Exactly 1 + } + } + Context -Name "The IntuneAppAndBrowserIsolationPolicyWindows10 Exists and Values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + AllowCameraMicrophoneRedirection = "1"; + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + InstallWindowsDefenderApplicationGuard = "install"; + Description = "My Test" + Id = "12345-12345-12345-12345-12345" + DisplayName = "Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = 'Present' + Credential = $Credential; + } + } + + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The IntuneAppAndBrowserIsolationPolicyWindows10 exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + Assignments = [CimInstance[]]@( + (New-CimInstance -ClassName MSFT_DeviceManagementConfigurationPolicyAssignments -Property @{ + DataType = '#microsoft.graph.exclusionGroupAssignmentTarget' + groupId = '26d60dd1-fab6-47bf-8656-358194c1a49d' + deviceAndAppManagementAssignmentFilterType = 'none' + } -ClientOnly) + ) + AllowCameraMicrophoneRedirection = "0"; # Updated property + AllowPersistence = "0"; + AllowVirtualGPU = "0"; + AllowWindowsDefenderApplicationGuard = "1"; + InstallWindowsDefenderApplicationGuard = "install"; + Description = "My Test" + Id = "12345-12345-12345-12345-12345" + DisplayName = "Test" + RoleScopeTagIds = @("FakeStringValue") + Ensure = 'Present' + Credential = $Credential; + } + } + + 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 Update-IntuneDeviceConfigurationPolicy -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + } + 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.IntuneEndpointDetectionAndResponsePolicyWindows10.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneEndpointDetectionAndResponsePolicyWindows10.Tests.ps1 index fc863b5c09..e9801b6c53 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneEndpointDetectionAndResponsePolicyWindows10.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.IntuneEndpointDetectionAndResponsePolicyWindows10.Tests.ps1 @@ -44,12 +44,101 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Remove-MgBetaDeviceManagementConfigurationPolicy -MockWith { } - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicyTemplate -MockWith { + Mock -CommandName Update-IntuneDeviceConfigurationPolicy -MockWith { + } + + Mock -CommandName Get-IntuneSettingCatalogPolicySetting -MockWith { + } + + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { return @{ - TemplateId = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' + Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' + Description = 'My Test Description' + Name = 'My Test' + Platforms = "windows10" + Technologies = "mdm,microsoftSense" + TemplateReference = @{ + TemplateId = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' + } } } + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { + return @( + @{ + Id = 0 + SettingDefinitions = @( + @{ + Id = 'device_vendor_msft_windowsadvancedthreatprotection_onboarding' + Name = 'Onboarding' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingDefinition' + valueDefinition = @{ + isSecret = $true + } + } + } + @{ + Id = 'device_vendor_msft_windowsadvancedthreatprotection_configurationtype' + Name = 'ClientConfigurationPackageType' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + } + ) + SettingInstance = @{ + SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configurationtype' + SettingInstanceTemplateReference = @{ + SettingInstanceTemplateId = '23ab0ea3-1b12-429a-8ed0-7390cf699160' + } + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + choiceSettingValue = @{ + children = @( + @{ + settingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_onboarding' + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance' + simpleSettingValue = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationSecretSettingValue' + value = '84db67dd-caf8-4f86-bf00-b8897972d51f' + valueState = 'encryptedValueToken' + } + } + ) + value = 'device_vendor_msft_windowsadvancedthreatprotection_configurationtype_onboard' + } + value = "TEST" + } + } + } + @{ + Id = 1 + SettingDefinitions = @( + @{ + Id = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' + Name = 'SampleSharing' + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' + } + } + ) + SettingInstance = @{ + SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' + SettingInstanceTemplateReference = @{ + SettingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' + } + AdditionalProperties = @{ + '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' + choiceSettingValue = @{ + children = @() + value = "device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing_0" + } + } + } + } + ) + } + Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicyAssignment -MockWith { return @(@{ Id = '12345-12345-12345-12345-12345' @@ -69,18 +158,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } Mock -CommandName Update-DeviceConfigurationPolicyAssignment -MockWith { } - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicyTemplateSettingTemplate -MockWith { - return @{ - Id = '12345-12345-12345-12345-12345' - SettingInstanceTemplate = @{ - settingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' - settingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingDefinition' - } - } - } - } # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { @@ -105,6 +182,8 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisplayName = 'My Test' Ensure = 'Present' Identity = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' + ConfigurationBlob = "FakeValue" + ConfigurationType = "onboard" sampleSharing = "0" } @@ -141,39 +220,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisplayName = 'My Test' Ensure = 'Present' Identity = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - sampleSharing = "0" - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { - return @{ - Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - Description = 'My Test Description' - Name = 'My Test' - } - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { - return @{ - Id = 0 - SettingDefinitions = $null - SettingInstance = @{ - SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' - SettingInstanceTemplateReference = @{ - SettingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' - } - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' - choiceSettingValue = @{ - children = @() - value = "device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing_1" - } - } - - } - AdditionalProperties = $null - } - } - Mock -CommandName Update-DeviceManagementConfigurationPolicy -MockWith { + ConfigurationBlob = "FakeValue" + ConfigurationType = "onboard" + sampleSharing = "1" # Drift } } @@ -187,7 +236,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { It 'Should update the instance from the Set method' { Set-TargetResource @testParams - Should -Invoke -CommandName Update-DeviceManagementConfigurationPolicy -Exactly 1 + Should -Invoke -CommandName Update-IntuneDeviceConfigurationPolicy -Exactly 1 } } @@ -206,32 +255,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DeviceAndAppManagementAssignmentFilterType = 'none' } -ClientOnly) ) - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { - return @{ - Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - Description = 'My Test Description' - Name = 'My Test' - Settings = @{ - Id = 0 - SettingDefinitions = $null - SettingInstance = @{ - SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' - SettingInstanceTemplateReference = @{ - SettingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' - } - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' - choiceSettingValue = @{ - children = @() - value = "device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing_0" - } - } - } - AdditionalProperties = $null - } - } + ConfigurationBlob = "FakeValue" + ConfigurationType = "onboard" + sampleSharing = "0" } } @@ -254,35 +280,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { DisplayName = 'My Test' Ensure = 'Absent' Identity = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { - return @{ - Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - Description = 'My Test Description' - Name = 'My Test' - } - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { - return @{ - Id = 0 - SettingDefinitions = $null - SettingInstance = @{ - SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' - SettingInstanceTemplateReference = @{ - SettingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' - } - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' - choiceSettingValue = @{ - children = @() - value = "device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing_0" - } - } - } - AdditionalProperties = $null - } + ConfigurationBlob = "FakeValue" + ConfigurationType = "onboard" + sampleSharing = "1" } } @@ -307,38 +307,6 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { $testParams = @{ Credential = $Credential } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicy -MockWith { - return @{ - Id = '619bd4a4-3b3b-4441-bd6f-3f4c0c444870' - Description = 'My Test Description' - Name = 'My Test' - TemplateReference = @{ - TemplateId = '0385b795-0f2f-44ac-8602-9f65bf6adede_1' - } - } - } - - Mock -CommandName Get-MgBetaDeviceManagementConfigurationPolicySetting -MockWith { - return @{ - Id = 0 - SettingDefinitions = $null - SettingInstance = @{ - SettingDefinitionId = 'device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing' - SettingInstanceTemplateReference = @{ - SettingInstanceTemplateId = '6998c81e-2814-4f5e-b492-a6159128a97b' - } - AdditionalProperties = @{ - '@odata.type' = '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance' - choiceSettingValue = @{ - children = @() - value = "device_vendor_msft_windowsadvancedthreatprotection_configuration_samplesharing_0" - } - } - } - AdditionalProperties = $null - } - } } It 'Should Reverse Engineer resource from the Export method' { diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index 9a27e57934..0542d9871e 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -18,6 +18,12 @@ function Invoke-AzRest } #endregion +function Get-MgBetaPolicyDeviceRegistrationPolicy +{ + [CmdletBinding()] + param() +} + #region Microsoft.Graph.Beta.Applications function Get-MgBetaApplication { @@ -3356,6 +3362,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()] diff --git a/docs/docs/resources/azure-ad/AADDeviceRegistrationPolicy.md b/docs/docs/resources/azure-ad/AADDeviceRegistrationPolicy.md new file mode 100644 index 0000000000..9d62cc0431 --- /dev/null +++ b/docs/docs/resources/azure-ad/AADDeviceRegistrationPolicy.md @@ -0,0 +1,105 @@ +# AADDeviceRegistrationPolicy + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **IsSingleInstance** | Key | String | Only valid value is 'Yes'. | `Yes` | +| **AzureADJoinIsAdminConfigurable** | Write | Boolean | Determines whether or not administrators can configure Azure AD Join. | | +| **UserDeviceQuota** | Write | UInt32 | Specifies the maximum number of devices that a user can have within your organization before blocking new device registrations. The default value is set to 50. If this property isn't specified during the policy update operation, it's automatically reset to 0 to indicate that users aren't allowed to join any devices. | | +| **AzureADAllowedToJoin** | Write | String | Scope that a device registration policy applies to. | `All`, `Selected`, `None` | +| **AzureADAllowedToJoinUsers** | Write | StringArray[] | List of users that this policy applies to. | | +| **AzureADAllowedToJoinGroups** | Write | StringArray[] | List of groups that this policy applies to. | | +| **MultiFactorAuthConfiguration** | Write | Boolean | Specifies the authentication policy for a user to complete registration using Microsoft Entra join or Microsoft Entra registered within your organization. | | +| **LocalAdminsEnableGlobalAdmins** | Write | Boolean | Indicates whether global administrators are local administrators on all Microsoft Entra-joined devices. This setting only applies to future registrations. Default is true. | | +| **AzureAdJoinLocalAdminsRegisteringMode** | Write | String | Scope that a device registration policy applies to for local admins. | `All`, `Selected`, `None` | +| **AzureAdJoinLocalAdminsRegisteringGroups** | Write | StringArray[] | List of groups that this policy applies to. | | +| **AzureAdJoinLocalAdminsRegisteringUsers** | Write | StringArray[] | List of users that this policy applies to. | | +| **LocalAdminPasswordIsEnabled** | Write | Boolean | Specifies whether this policy scope is configurable by the admin. The default value is false. An admin can set it to true to enable Local Admin Password Solution (LAPS) within their organzation. | | +| **Credential** | Write | PSCredential | Credentials of the 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. | | +| **ApplicationSecret** | Write | PSCredential | Secret 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 + +Represents the policy scope that controls quota restrictions, additional authentication, and authorization policies to register device identities to your organization. + +## Permissions + +### Microsoft Graph + +To authenticate with the Microsoft Graph API, this resource required the following permissions: + +#### Delegated permissions + +- **Read** + + - None + +- **Update** + + - None + +#### Application permissions + +- **Read** + + - Policy.Read.DeviceConfiguration + +- **Update** + + - Policy.ReadWrite.DeviceConfiguration + +## 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 + { + AADDeviceRegistrationPolicy "MyDeviceRegistrationPolicy" + { + ApplicationId = $ApplicationId; + AzureADAllowedToJoin = "Selected"; + AzureADAllowedToJoinGroups = @(); + AzureADAllowedToJoinUsers = @("AlexW@M365x73318397.OnMicrosoft.com"); + AzureAdJoinLocalAdminsRegisteringGroups = @(); + AzureAdJoinLocalAdminsRegisteringMode = "Selected"; + AzureAdJoinLocalAdminsRegisteringUsers = @("AllanD@M365x73318397.OnMicrosoft.com"); + CertificateThumbprint = $CertificateThumbprint; + IsSingleInstance = "Yes"; + LocalAdminPasswordIsEnabled = $False; + LocalAdminsEnableGlobalAdmins = $True; + MultiFactorAuthConfiguration = $False; + TenantId = $TenantId; + UserDeviceQuota = 50; + } + } +} +``` + diff --git a/docs/docs/resources/azure-ad/ADOPermissionGroupSettings.md b/docs/docs/resources/azure-ad/ADOPermissionGroupSettings.md new file mode 100644 index 0000000000..ed460c2a8b --- /dev/null +++ b/docs/docs/resources/azure-ad/ADOPermissionGroupSettings.md @@ -0,0 +1,98 @@ +# ADOPermissionGroupSettings + +## Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **GroupName** | Key | String | Name of the group. | | +| **OrganizationName** | Write | String | Name of the DevOPS Organization. | | +| **Descriptor** | Write | String | Descriptor for the group. | | +| **AllowPermissions** | Write | MSFT_ADOPermission[] | Allow permissions. | | +| **DenyPermissions** | Write | MSFT_ADOPermission[] | Deny permissions | | +| **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. | | + +### MSFT_ADOPermission + +#### Parameters + +| Parameter | Attribute | DataType | Description | Allowed Values | +| --- | --- | --- | --- | --- | +| **NamespaceId** | Write | String | Id of the associate security namespace. | | +| **DisplayName** | Write | String | Display name of the permission scope. | | +| **Bit** | Write | UInt32 | Bit mask for the permission | | +| **Token** | Write | String | Token value | | + + +## Description + +Manages permissions in Azure DevOPS. + +## Permissions + +### Microsoft Graph + +To authenticate with the Microsoft Graph API, this resource required the following permissions: + +#### Delegated permissions + +- **Read** + + - None + +- **Update** + + - None + +#### Application permissions + +- **Read** + + - None + +- **Update** + + - None + +## 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()] + [PSCredential] + $Credential + ) + Import-DscResource -ModuleName Microsoft365DSC + node localhost + { + ADOPermissionGroupSettings "ADOPermissionGroupSettings-O365DSC-DEV" + { + AllowPermissions = @( + MSFT_ADOPermission { + NamespaceId = '5a27515b-ccd7-42c9-84f1-54c998f03866' + DisplayName = 'Edit identity information' + Bit = '2' + Token = 'f6492b10-7ae8-4641-8208-ff5c364a6154\dbe6034e-8fbe-4d6e-a7f3-07a7e70816c9' + } + ); + Credential = $Credential; + DenyPermissions = @(); + Descriptor = "vssgp.Uy0xLTktMTU1MTM3NDI0NS0yNzEyNzI0MzgtMzkwMDMyNjIxNC0yMTgxNjI3NzQwLTkxMDg0NDI0NC0xLTgyODcyNzAzNC0yOTkzNjA0MTcxLTI5MjUwMjk4ODgtNTY0MDg1OTcy"; + GroupName = "[O365DSC-DEV]\My Test Group"; + OrganizationName = "O365DSC-DEV"; + } + } +} +``` + 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"; + } + } +} +``` + diff --git a/docs/docs/resources/intune/IntuneEndpointDetectionAndResponsePolicyWindows10.md b/docs/docs/resources/intune/IntuneEndpointDetectionAndResponsePolicyWindows10.md index 9893c32f98..92a2428a6d 100644 --- a/docs/docs/resources/intune/IntuneEndpointDetectionAndResponsePolicyWindows10.md +++ b/docs/docs/resources/intune/IntuneEndpointDetectionAndResponsePolicyWindows10.md @@ -6,6 +6,7 @@ | --- | --- | --- | --- | --- | | **Identity** | Write | String | Identity of the endpoint detection and response policy for Windows 10. | | | **DisplayName** | Key | String | Display name of the endpoint detection and response policy for Windows 10. | | +| **RoleScopeTagIds** | Write | StringArray[] | List of Scope Tags for this Entity instance. | | | **Description** | Write | String | Description of the endpoint detection and response policy for Windows 10. | | | **Assignments** | Write | MSFT_DeviceManagementConfigurationPolicyAssignments[] | Assignments of the endpoint detection and response policy for Windows 10. | | | **SampleSharing** | Write | String | Return or set Windows Defender Advanced Threat Protection Sample Sharing configuration parameter: 0 - none, 1 - All | `0`, `1` | @@ -100,6 +101,9 @@ Configuration Example ApplicationId = $ApplicationId; TenantId = $TenantId; CertificateThumbprint = $CertificateThumbprint; + ConfigurationBlob = "Blob" + ConfigurationType = "onboard" + SampleSharing = 1 } } } @@ -139,6 +143,9 @@ Configuration Example ApplicationId = $ApplicationId; TenantId = $TenantId; CertificateThumbprint = $CertificateThumbprint; + ConfigurationBlob = "Blob" + ConfigurationType = "onboard" + SampleSharing = 1 } } }