DSCResources/MSFT_AzureRoleEligibilityScheduleSettings/MSFT_AzureRoleEligibilityScheduleSettings.psm1
|
Confirm-M365DSCModuleDependency -ModuleName 'MSFT_AzureRoleEligibilityScheduleSettings' function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $RoleDefinitionDisplayName, [Parameter(Mandatory = $true)] [System.String] $ScopeId, [Parameter()] [System.String] $PolicyId, [Parameter()] [System.String] $ActivationMaxDuration, [Parameter()] [System.Boolean] $ActivationReqJustification, [Parameter()] [System.Boolean] $ActivationReqTicket, [Parameter()] [System.Boolean] $ActivationReqMFA, [Parameter()] [System.Boolean] $ApprovaltoActivate, [Parameter()] [System.String[]] $ActivateApprover, [Parameter()] [System.Boolean] $ActivationReqAuthContext, [Parameter()] [System.String] $ActivationAuthContextId, [Parameter()] [System.Boolean] $PermanentEligibleAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireEligibleAssignment, [Parameter()] [System.Boolean] $PermanentActiveAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireActiveAssignment, [Parameter()] [System.Boolean] $AssignmentReqMFA, [Parameter()] [System.Boolean] $AssignmentReqJustification, [Parameter()] [System.Boolean] $EligibilityAssignmentReqMFA, [Parameter()] [System.Boolean] $EligibilityAssignmentReqJustification, [Parameter()] [System.Boolean] $EligibleAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationApproveNotificationOnlyCritical, [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()] [System.String] $CertificatePath, [Parameter()] [System.Management.Automation.PSCredential] $CertificatePassword, [Parameter()] [Switch] $ManagedIdentity, [Parameter()] [System.String[]] $AccessTokens ) Write-Verbose -Message "Getting configuration of Azure Role Eligibility Schedule Settings for Role {$RoleDefinitionDisplayName} at Scope {$ScopeId}" if ($null -eq $Script:exportedInstance) { $null = New-M365DSCConnection -Workload 'Azure' ` -InboundParameters $PSBoundParameters $null = 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 $nullReturn = $PSBoundParameters $apiVersion = '2020-10-01' $uri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$ScopeId/providers/Microsoft.Authorization/roleManagementPolicyAssignments?api-version=$apiVersion" $response = Invoke-AzRestMethod -Uri $uri -Method GET $assignments = (ConvertFrom-Json $response.Content).value if ($null -eq $assignments -or $assignments.Count -eq 0) { Write-Verbose -Message "No role management policy assignments found at scope {$ScopeId}." return $nullReturn } $assignment = $assignments | Where-Object { $_.properties.roleDefinitionDisplayName -eq $RoleDefinitionDisplayName -or $_.properties.policyAssignmentProperties.roleDefinition.displayName -eq $RoleDefinitionDisplayName } if ($null -eq $assignment) { $roleDefUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$ScopeId/providers/Microsoft.Authorization/roleDefinitions?api-version=$apiVersion&`$filter=roleName eq '$RoleDefinitionDisplayName'" $roleDefResponse = Invoke-AzRestMethod -Uri $roleDefUri -Method GET $roleDefinitions = (ConvertFrom-Json $roleDefResponse.Content).value if ($null -ne $roleDefinitions -and $roleDefinitions.Count -gt 0) { $roleDefId = $roleDefinitions[0].id $assignment = $assignments | Where-Object { $_.properties.roleDefinitionId -eq $roleDefId } } } if ($null -eq $assignment) { Write-Verbose -Message "Could not find role management policy assignment for role {$RoleDefinitionDisplayName} at scope {$ScopeId}." return $nullReturn } $policyIdValue = $assignment.properties.policyId.Split('/')[-1] $policyUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$ScopeId/providers/Microsoft.Authorization/roleManagementPolicies/$($policyIdValue)?api-version=$apiVersion" $policyResponse = Invoke-AzRestMethod -Uri $policyUri -Method GET $policy = ConvertFrom-Json $policyResponse.Content if ($null -eq $policy -or $null -eq $policy.properties -or $null -eq $policy.properties.rules) { Write-Verbose -Message "Could not retrieve role management policy {$policyIdValue} at scope {$ScopeId}." return $nullReturn } $rules = $policy.properties.rules } else { $rules = $Script:exportedInstance.rules $policyIdValue = $Script:exportedInstance.policyId } $nullReturn = $PSBoundParameters if ($null -eq $rules -or $rules.Count -eq 0) { Write-Verbose -Message 'No Policy Rules found, returning null' return $nullReturn } try { # Extract activation settings $ActivationMaxDuration = ($rules | Where-Object { $_.id -eq 'Expiration_EndUser_Assignment' }).maximumDuration $ActivationReqJustification = (($rules | Where-Object { $_.id -eq 'Enablement_EndUser_Assignment' }).enabledRules) -contains 'Justification' $ActivationReqTicket = (($rules | Where-Object { $_.id -eq 'Enablement_EndUser_Assignment' }).enabledRules) -contains 'Ticketing' $ActivationReqMFA = (($rules | Where-Object { $_.id -eq 'Enablement_EndUser_Assignment' }).enabledRules) -contains 'MultiFactorAuthentication' $ApprovaltoActivate = ($rules | Where-Object { $_.id -eq 'Approval_EndUser_Assignment' }).setting.isApprovalRequired $ActivationReqAuthContext = ($rules | Where-Object { $_.id -eq 'AuthenticationContext_EndUser_Assignment' }).isEnabled $ActivationAuthContextId = ($rules | Where-Object { $_.id -eq 'AuthenticationContext_EndUser_Assignment' }).claimValue [string[]]$ActivateApprover = @() $approverEntries = ($rules | Where-Object { $_.id -eq 'Approval_EndUser_Assignment' }).setting.approvalStages if ($null -ne $approverEntries -and $approverEntries.Count -gt 0) { foreach ($approver in $approverEntries[0].primaryApprovers) { if (-not [System.String]::IsNullOrEmpty($approver.id)) { $directoryObject = Get-MgBetaDirectoryObjectById -Ids $approver.id -ErrorAction SilentlyContinue if ($null -ne $directoryObject) { $odataType = $directoryObject['@odata.type'] if (-not [System.String]::IsNullOrEmpty($odataType) -and $odataType.Split('.').Count -ge 3) { $objectType = $odataType.Split('.')[2] if ($objectType -eq 'user') { $ActivateApprover += $directoryObject['userPrincipalName'] } else { $ActivateApprover += $directoryObject['displayName'] } } else { Write-Verbose -Message "Could not determine type for approver with Id {$($approver.id)}" } } else { Write-Verbose -Message "Could not resolve approver with Id {$($approver.id)}" } } } } # Extract eligible assignment settings $PermanentEligibleAssignmentisExpirationRequired = ($rules | Where-Object { $_.id -eq 'Expiration_Admin_Eligibility' }).isExpirationRequired $ExpireEligibleAssignment = ($rules | Where-Object { $_.id -eq 'Expiration_Admin_Eligibility' }).maximumDuration # Extract active assignment settings $PermanentActiveAssignmentisExpirationRequired = ($rules | Where-Object { $_.id -eq 'Expiration_Admin_Assignment' }).isExpirationRequired $ExpireActiveAssignment = ($rules | Where-Object { $_.id -eq 'Expiration_Admin_Assignment' }).maximumDuration $AssignmentReqMFA = (($rules | Where-Object { $_.id -eq 'Enablement_Admin_Assignment' }).enabledRules) -contains 'MultiFactorAuthentication' $AssignmentReqJustification = (($rules | Where-Object { $_.id -eq 'Enablement_Admin_Assignment' }).enabledRules) -contains 'Justification' # Extract eligible assignment enablement settings $EligibilityAssignmentReqMFA = (($rules | Where-Object { $_.id -eq 'Enablement_Admin_Eligibility' }).enabledRules) -contains 'MultiFactorAuthentication' $EligibilityAssignmentReqJustification = (($rules | Where-Object { $_.id -eq 'Enablement_Admin_Eligibility' }).enabledRules) -contains 'Justification' # Extract notification settings for eligible assignments $EligibleAlertNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Eligibility' }).isDefaultRecipientsEnabled [string[]]$EligibleAlertNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Eligibility' }).notificationRecipients $EligibleAlertNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Eligibility' }).notificationLevel) -eq 'Critical' $EligibleAssigneeNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Eligibility' }).isDefaultRecipientsEnabled [string[]]$EligibleAssigneeNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Eligibility' }).notificationRecipients $EligibleAssigneeNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Eligibility' }).notificationLevel) -eq 'Critical' $EligibleApproveNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Eligibility' }).isDefaultRecipientsEnabled [string[]]$EligibleApproveNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Eligibility' }).notificationRecipients $EligibleApproveNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Eligibility' }).notificationLevel) -eq 'Critical' # Extract notification settings for active assignments $ActiveAlertNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActiveAlertNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Assignment' }).notificationRecipients $ActiveAlertNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Admin_Admin_Assignment' }).notificationLevel) -eq 'Critical' $ActiveAssigneeNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActiveAssigneeNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Assignment' }).notificationRecipients $ActiveAssigneeNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Requestor_Admin_Assignment' }).notificationLevel) -eq 'Critical' $ActiveApproveNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActiveApproveNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Assignment' }).notificationRecipients $ActiveApproveNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Approver_Admin_Assignment' }).notificationLevel) -eq 'Critical' # Extract notification settings for activation $ActivationAlertNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_EndUser_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActivationAlertNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Admin_EndUser_Assignment' }).notificationRecipients $ActivationAlertNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Admin_EndUser_Assignment' }).notificationLevel) -eq 'Critical' $ActivationAssigneeNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_EndUser_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActivationAssigneeNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Requestor_EndUser_Assignment' }).notificationRecipients $ActivationAssigneeNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Requestor_EndUser_Assignment' }).notificationLevel) -eq 'Critical' $ActivationApproveNotificationDefaultRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_EndUser_Assignment' }).isDefaultRecipientsEnabled [string[]]$ActivationApproveNotificationAdditionalRecipient = ($rules | Where-Object { $_.id -eq 'Notification_Approver_EndUser_Assignment' }).notificationRecipients $ActivationApproveNotificationOnlyCritical = (($rules | Where-Object { $_.id -eq 'Notification_Approver_EndUser_Assignment' }).notificationLevel) -eq 'Critical' Write-Verbose -Message "Found configuration for Role {$RoleDefinitionDisplayName} at Scope {$ScopeId}" $result = @{ RoleDefinitionDisplayName = $RoleDefinitionDisplayName ScopeId = $ScopeId PolicyId = $policyIdValue ActivationMaxDuration = $ActivationMaxDuration ActivationReqJustification = $ActivationReqJustification ActivationReqTicket = $ActivationReqTicket ActivationReqMFA = $ActivationReqMFA ApprovaltoActivate = $ApprovaltoActivate ActivateApprover = [System.String[]]$ActivateApprover ActivationReqAuthContext = $ActivationReqAuthContext ActivationAuthContextId = $ActivationAuthContextId PermanentEligibleAssignmentisExpirationRequired = $PermanentEligibleAssignmentisExpirationRequired ExpireEligibleAssignment = $ExpireEligibleAssignment PermanentActiveAssignmentisExpirationRequired = $PermanentActiveAssignmentisExpirationRequired ExpireActiveAssignment = $ExpireActiveAssignment AssignmentReqMFA = $AssignmentReqMFA AssignmentReqJustification = $AssignmentReqJustification EligibilityAssignmentReqMFA = $EligibilityAssignmentReqMFA EligibilityAssignmentReqJustification = $EligibilityAssignmentReqJustification EligibleAlertNotificationDefaultRecipient = $EligibleAlertNotificationDefaultRecipient EligibleAlertNotificationAdditionalRecipient = [System.String[]]$EligibleAlertNotificationAdditionalRecipient EligibleAlertNotificationOnlyCritical = $EligibleAlertNotificationOnlyCritical EligibleAssigneeNotificationDefaultRecipient = $EligibleAssigneeNotificationDefaultRecipient EligibleAssigneeNotificationAdditionalRecipient = [System.String[]]$EligibleAssigneeNotificationAdditionalRecipient EligibleAssigneeNotificationOnlyCritical = $EligibleAssigneeNotificationOnlyCritical EligibleApproveNotificationDefaultRecipient = $EligibleApproveNotificationDefaultRecipient EligibleApproveNotificationAdditionalRecipient = [System.String[]]$EligibleApproveNotificationAdditionalRecipient EligibleApproveNotificationOnlyCritical = $EligibleApproveNotificationOnlyCritical ActiveAlertNotificationDefaultRecipient = $ActiveAlertNotificationDefaultRecipient ActiveAlertNotificationAdditionalRecipient = [System.String[]]$ActiveAlertNotificationAdditionalRecipient ActiveAlertNotificationOnlyCritical = $ActiveAlertNotificationOnlyCritical ActiveAssigneeNotificationDefaultRecipient = $ActiveAssigneeNotificationDefaultRecipient ActiveAssigneeNotificationAdditionalRecipient = [System.String[]]$ActiveAssigneeNotificationAdditionalRecipient ActiveAssigneeNotificationOnlyCritical = $ActiveAssigneeNotificationOnlyCritical ActiveApproveNotificationDefaultRecipient = $ActiveApproveNotificationDefaultRecipient ActiveApproveNotificationAdditionalRecipient = [System.String[]]$ActiveApproveNotificationAdditionalRecipient ActiveApproveNotificationOnlyCritical = $ActiveApproveNotificationOnlyCritical ActivationAlertNotificationDefaultRecipient = $ActivationAlertNotificationDefaultRecipient ActivationAlertNotificationAdditionalRecipient = [System.String[]]$ActivationAlertNotificationAdditionalRecipient ActivationAlertNotificationOnlyCritical = $ActivationAlertNotificationOnlyCritical ActivationAssigneeNotificationDefaultRecipient = $ActivationAssigneeNotificationDefaultRecipient ActivationAssigneeNotificationAdditionalRecipient = [System.String[]]$ActivationAssigneeNotificationAdditionalRecipient ActivationAssigneeNotificationOnlyCritical = $ActivationAssigneeNotificationOnlyCritical ActivationApproveNotificationDefaultRecipient = $ActivationApproveNotificationDefaultRecipient ActivationApproveNotificationAdditionalRecipient = [System.String[]]$ActivationApproveNotificationAdditionalRecipient ActivationApproveNotificationOnlyCritical = $ActivationApproveNotificationOnlyCritical ApplicationId = $ApplicationId TenantId = $TenantId CertificateThumbprint = $CertificateThumbprint ApplicationSecret = $ApplicationSecret Credential = $Credential ManagedIdentity = $ManagedIdentity.IsPresent AccessTokens = $AccessTokens } return $result } catch { New-M365DSCLogEntry -Message 'Error retrieving data:' ` -Exception $_ ` -Source $($MyInvocation.MyCommand.Source) ` -TenantId $TenantId ` -Credential $Credential throw } } function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $RoleDefinitionDisplayName, [Parameter(Mandatory = $true)] [System.String] $ScopeId, [Parameter()] [System.String] $PolicyId, [Parameter()] [System.String] $ActivationMaxDuration, [Parameter()] [System.Boolean] $ActivationReqJustification, [Parameter()] [System.Boolean] $ActivationReqTicket, [Parameter()] [System.Boolean] $ActivationReqMFA, [Parameter()] [System.Boolean] $ApprovaltoActivate, [Parameter()] [System.String[]] $ActivateApprover, [Parameter()] [System.Boolean] $ActivationReqAuthContext, [Parameter()] [System.String] $ActivationAuthContextId, [Parameter()] [System.Boolean] $PermanentEligibleAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireEligibleAssignment, [Parameter()] [System.Boolean] $PermanentActiveAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireActiveAssignment, [Parameter()] [System.Boolean] $AssignmentReqMFA, [Parameter()] [System.Boolean] $AssignmentReqJustification, [Parameter()] [System.Boolean] $EligibilityAssignmentReqMFA, [Parameter()] [System.Boolean] $EligibilityAssignmentReqJustification, [Parameter()] [System.Boolean] $EligibleAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationApproveNotificationOnlyCritical, [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()] [System.String] $CertificatePath, [Parameter()] [System.Management.Automation.PSCredential] $CertificatePassword, [Parameter()] [Switch] $ManagedIdentity, [Parameter()] [System.String[]] $AccessTokens ) Write-Verbose -Message "Setting configuration of Azure Role Eligibility Schedule Settings for Role {$RoleDefinitionDisplayName} at Scope {$ScopeId}" try { #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 $policyIdValue = $currentInstance.PolicyId if ([System.String]::IsNullOrEmpty($policyIdValue)) { throw "Could not find role management policy for role {$RoleDefinitionDisplayName} at scope {$ScopeId}" } # Get the full policy to retrieve all current rules $apiVersion = '2020-10-01' $policyUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$ScopeId/providers/Microsoft.Authorization/roleManagementPolicies/$($policyIdValue)?api-version=$apiVersion" $policyResponse = Invoke-AzRestMethod -Uri $policyUri -Method GET $policy = ConvertFrom-Json $policyResponse.Content $rules = $policy.properties.rules $ruleModified = $false foreach ($currentRule in $rules) { $params = @{} if ($currentRule.id -eq 'Notification_Admin_Admin_Eligibility') { if ($PSBoundParameters.ContainsKey('EligibleAlertNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('EligibleAlertNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('EligibleAlertNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as eligible to this role: Role assignment alert' $onlyCritical = if ($PSBoundParameters.ContainsKey('EligibleAlertNotificationOnlyCritical')) { $EligibleAlertNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('EligibleAlertNotificationDefaultRecipient')) { $EligibleAlertNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('EligibleAlertNotificationAdditionalRecipient')) { @($EligibleAlertNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Admin' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Requestor_Admin_Eligibility') { if ($PSBoundParameters.ContainsKey('EligibleAssigneeNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('EligibleAssigneeNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('EligibleAssigneeNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as eligible to this role: Notification to the assigned user (assignee)' $onlyCritical = if ($PSBoundParameters.ContainsKey('EligibleAssigneeNotificationOnlyCritical')) { $EligibleAssigneeNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('EligibleAssigneeNotificationDefaultRecipient')) { $EligibleAssigneeNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('EligibleAssigneeNotificationAdditionalRecipient')) { @($EligibleAssigneeNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Requestor' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Approver_Admin_Eligibility') { if ($PSBoundParameters.ContainsKey('EligibleApproveNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('EligibleApproveNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('EligibleApproveNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as eligible to this role: Request to approve a role assignment renewal/extension' $onlyCritical = if ($PSBoundParameters.ContainsKey('EligibleApproveNotificationOnlyCritical')) { $EligibleApproveNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('EligibleApproveNotificationDefaultRecipient')) { $EligibleApproveNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('EligibleApproveNotificationAdditionalRecipient')) { @($EligibleApproveNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Approver' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Admin_Admin_Assignment') { if ($PSBoundParameters.ContainsKey('ActiveAlertNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActiveAlertNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActiveAlertNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as active to this role: Role assignment alert' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActiveAlertNotificationOnlyCritical')) { $ActiveAlertNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActiveAlertNotificationDefaultRecipient')) { $ActiveAlertNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActiveAlertNotificationAdditionalRecipient')) { @($ActiveAlertNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Admin' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Requestor_Admin_Assignment') { if ($PSBoundParameters.ContainsKey('ActiveAssigneeNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActiveAssigneeNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActiveAssigneeNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as active to this role: Notification to the assigned user (assignee)' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActiveAssigneeNotificationOnlyCritical')) { $ActiveAssigneeNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActiveAssigneeNotificationDefaultRecipient')) { $ActiveAssigneeNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActiveAssigneeNotificationAdditionalRecipient')) { @($ActiveAssigneeNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Requestor' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Approver_Admin_Assignment') { if ($PSBoundParameters.ContainsKey('ActiveApproveNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActiveApproveNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActiveApproveNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when members are assigned as active to this role: Request to approve a role assignment renewal/extension' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActiveApproveNotificationOnlyCritical')) { $ActiveApproveNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActiveApproveNotificationDefaultRecipient')) { $ActiveApproveNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActiveApproveNotificationAdditionalRecipient')) { @($ActiveApproveNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Approver' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Admin_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationAlertNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActivationAlertNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActivationAlertNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when eligible members activate this role: Role activation alert' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActivationAlertNotificationOnlyCritical')) { $ActivationAlertNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActivationAlertNotificationDefaultRecipient')) { $ActivationAlertNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActivationAlertNotificationAdditionalRecipient')) { @($ActivationAlertNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Admin' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Requestor_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationAssigneeNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActivationAssigneeNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActivationAssigneeNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when eligible members activate this role: Notification to activated user (requestor)' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActivationAssigneeNotificationOnlyCritical')) { $ActivationAssigneeNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActivationAssigneeNotificationDefaultRecipient')) { $ActivationAssigneeNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActivationAssigneeNotificationAdditionalRecipient')) { @($ActivationAssigneeNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Requestor' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Notification_Approver_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationApproveNotificationOnlyCritical') ` -or $PSBoundParameters.ContainsKey('ActivationApproveNotificationDefaultRecipient') ` -or $PSBoundParameters.ContainsKey('ActivationApproveNotificationAdditionalRecipient')) { Write-Verbose -Message 'Handle Send notifications when eligible members activate this role: Notification to approvers' $onlyCritical = if ($PSBoundParameters.ContainsKey('ActivationApproveNotificationOnlyCritical')) { $ActivationApproveNotificationOnlyCritical } else { $currentRule.notificationLevel -eq 'Critical' } $defaultRecipient = if ($PSBoundParameters.ContainsKey('ActivationApproveNotificationDefaultRecipient')) { $ActivationApproveNotificationDefaultRecipient } else { $currentRule.isDefaultRecipientsEnabled } $additionalRecipient = if ($PSBoundParameters.ContainsKey('ActivationApproveNotificationAdditionalRecipient')) { @($ActivationApproveNotificationAdditionalRecipient) } else { @($currentRule.notificationRecipients) } $notificationLevel = if ($onlyCritical) { 'Critical' } else { 'All' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id notificationType = 'Email' recipientType = 'Approver' notificationLevel = $notificationLevel isDefaultRecipientsEnabled = $defaultRecipient notificationRecipients = [System.Collections.ArrayList]@($additionalRecipient) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Expiration_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationMaxDuration')) { Write-Verbose -Message 'Handle Activation: Activation maximum duration (hours)' $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id maximumDuration = $ActivationMaxDuration target = $currentRule.target } } } elseif ($currentRule.id -eq 'Enablement_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationReqJustification') ` -or $PSBoundParameters.ContainsKey('ActivationReqTicket') ` -or $PSBoundParameters.ContainsKey('ActivationReqMFA')) { Write-Verbose -Message 'Handle Activation: Require justification / ticket / MFA on activation' $reqJustification = if ($PSBoundParameters.ContainsKey('ActivationReqJustification')) { $ActivationReqJustification } else { ($currentRule.enabledRules) -contains 'Justification' } $reqTicket = if ($PSBoundParameters.ContainsKey('ActivationReqTicket')) { $ActivationReqTicket } else { ($currentRule.enabledRules) -contains 'Ticketing' } $reqMFA = if ($PSBoundParameters.ContainsKey('ActivationReqMFA')) { $ActivationReqMFA } else { ($currentRule.enabledRules) -contains 'MultiFactorAuthentication' } [String[]]$enabledrules = @() if ($reqJustification) { $enabledrules += 'Justification' } if ($reqTicket) { $enabledrules += 'Ticketing' } if ($reqMFA) { $enabledrules += 'MultiFactorAuthentication' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id enabledRules = [System.Collections.ArrayList]@($enabledrules) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Approval_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ApprovaltoActivate') ` -and $PSBoundParameters.ContainsKey('ActivateApprover')) { Write-Verbose -Message 'Handle Activation: Require approval to activate / Approvers' $primaryApprovers = @() if ($ActivateApprover.Count -gt 0) { foreach ($item in $ActivateApprover) { $Filter = "UserPrincipalName eq '$($item -replace "'", "''")'" $user = Get-MgUser -Filter $Filter -ErrorAction SilentlyContinue if ($null -ne $user) { $primaryApprovers += @{ id = $user.Id userType = 'User' isBackup = $false } } else { Write-Verbose -Message "User '$item' not found, trying with group" $Filter = "displayName eq '$($item -replace "'", "''")'" $group = Get-MgGroup -Filter $Filter -ErrorAction SilentlyContinue if ($null -ne $group) { $primaryApprovers += @{ id = $group.Id userType = 'Group' isBackup = $false } } else { throw "Approver '$item' not found as user or group. Cannot add as approver." } } } } $approvalStages = @{ approvalStageTimeOutInDays = 1 isApproverJustificationRequired = $true escalationTimeInMinutes = 0 isEscalationEnabled = $false primaryApprovers = [System.Collections.ArrayList]@($primaryApprovers) escalationApprovers = [System.Collections.ArrayList]@() } $setting = @{ isApprovalRequired = $ApprovaltoActivate isApprovalRequiredForExtension = $false isRequestorJustificationRequired = $true approvalMode = 'SingleStage' approvalStages = [System.Collections.ArrayList]@($approvalStages) } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id setting = $setting target = $currentRule.target } } } elseif ($currentRule.id -eq 'Expiration_Admin_Eligibility') { if ($PSBoundParameters.ContainsKey('PermanentEligibleAssignmentisExpirationRequired') ` -and $PSBoundParameters.ContainsKey('ExpireEligibleAssignment')) { Write-Verbose -Message 'Handle Assignment: Allow permanent eligible assignment / Expire eligible assignments after' $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id isExpirationRequired = $PermanentEligibleAssignmentisExpirationRequired maximumDuration = $ExpireEligibleAssignment target = $currentRule.target } } } elseif ($currentRule.id -eq 'Expiration_Admin_Assignment') { if ($PSBoundParameters.ContainsKey('PermanentActiveAssignmentisExpirationRequired') ` -and $PSBoundParameters.ContainsKey('ExpireActiveAssignment')) { Write-Verbose -Message 'Handle Assignment: Allow permanent active assignment / Expire active assignments after' $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id isExpirationRequired = $PermanentActiveAssignmentisExpirationRequired maximumDuration = $ExpireActiveAssignment target = $currentRule.target } } } elseif ($currentRule.id -eq 'Enablement_Admin_Assignment') { if ($PSBoundParameters.ContainsKey('AssignmentReqJustification') ` -or $PSBoundParameters.ContainsKey('AssignmentReqMFA')) { Write-Verbose -Message 'Handle Assignment: Require MFA / justification on active assignment' $reqJustification = if ($PSBoundParameters.ContainsKey('AssignmentReqJustification')) { $AssignmentReqJustification } else { ($currentRule.enabledRules) -contains 'Justification' } $reqMFA = if ($PSBoundParameters.ContainsKey('AssignmentReqMFA')) { $AssignmentReqMFA } else { ($currentRule.enabledRules) -contains 'MultiFactorAuthentication' } [String[]]$enabledrules = @() if ($reqJustification) { $enabledrules += 'Justification' } if ($reqMFA) { $enabledrules += 'MultiFactorAuthentication' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id enabledRules = [System.Collections.ArrayList]@($enabledrules) target = $currentRule.target } } } elseif ($currentRule.id -eq 'Enablement_Admin_Eligibility') { if ($PSBoundParameters.ContainsKey('EligibilityAssignmentReqJustification') ` -or $PSBoundParameters.ContainsKey('EligibilityAssignmentReqMFA')) { Write-Verbose -Message 'Handle Assignment: Require MFA / justification on eligible assignment' $reqJustification = if ($PSBoundParameters.ContainsKey('EligibilityAssignmentReqJustification')) { $EligibilityAssignmentReqJustification } else { ($currentRule.enabledRules) -contains 'Justification' } $reqMFA = if ($PSBoundParameters.ContainsKey('EligibilityAssignmentReqMFA')) { $EligibilityAssignmentReqMFA } else { ($currentRule.enabledRules) -contains 'MultiFactorAuthentication' } [String[]]$enabledrules = @() if ($reqJustification) { $enabledrules += 'Justification' } if ($reqMFA) { $enabledrules += 'MultiFactorAuthentication' } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id enabledRules = [System.Collections.ArrayList]@($enabledrules) target = $currentRule.target } } } elseif ($currentRule.id -eq 'AuthenticationContext_EndUser_Assignment') { if ($PSBoundParameters.ContainsKey('ActivationReqAuthContext')) { Write-Verbose -Message 'Handle Activation: Require authentication context' $claimValue = $currentRule.claimValue if ($PSBoundParameters.ContainsKey('ActivationAuthContextId')) { $claimValue = $ActivationAuthContextId } $params = @{ ruleType = $currentRule.ruleType id = $currentRule.id isEnabled = $ActivationReqAuthContext claimValue = $claimValue target = $currentRule.target } } } if ($params.Count -gt 0) { # Replace the rule in the array with the updated version for ($i = 0; $i -lt $policy.properties.rules.Count; $i++) { if ($policy.properties.rules[$i].id -eq $currentRule.id) { $policy.properties.rules[$i] = $params $ruleModified = $true break } } } } if ($ruleModified) { $updateBody = @{ properties = @{ rules = [System.Collections.ArrayList]@($policy.properties.rules) } } $payload = ConvertTo-Json $updateBody -Depth 20 -Compress Write-Verbose -Message "Updating policy {$policyIdValue} at scope {$ScopeId}" $null = Invoke-AzRestMethod -Uri $policyUri -Method PATCH -Payload $payload } } catch { New-M365DSCLogEntry -Message 'Error updating data:' ` -Exception $_ ` -Source $($MyInvocation.MyCommand.Source) ` -TenantId $TenantId ` -Credential $Credential throw } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $RoleDefinitionDisplayName, [Parameter(Mandatory = $true)] [System.String] $ScopeId, [Parameter()] [System.String] $PolicyId, [Parameter()] [System.String] $ActivationMaxDuration, [Parameter()] [System.Boolean] $ActivationReqJustification, [Parameter()] [System.Boolean] $ActivationReqTicket, [Parameter()] [System.Boolean] $ActivationReqMFA, [Parameter()] [System.Boolean] $ApprovaltoActivate, [Parameter()] [System.String[]] $ActivateApprover, [Parameter()] [System.Boolean] $ActivationReqAuthContext, [Parameter()] [System.String] $ActivationAuthContextId, [Parameter()] [System.Boolean] $PermanentEligibleAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireEligibleAssignment, [Parameter()] [System.Boolean] $PermanentActiveAssignmentisExpirationRequired, [Parameter()] [System.String] $ExpireActiveAssignment, [Parameter()] [System.Boolean] $AssignmentReqMFA, [Parameter()] [System.Boolean] $AssignmentReqJustification, [Parameter()] [System.Boolean] $EligibilityAssignmentReqMFA, [Parameter()] [System.Boolean] $EligibilityAssignmentReqJustification, [Parameter()] [System.Boolean] $EligibleAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $EligibleApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $EligibleApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $EligibleApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActiveApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActiveApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActiveApproveNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAlertNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAlertNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAlertNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationAssigneeNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationAssigneeNotificationOnlyCritical, [Parameter()] [System.Boolean] $ActivationApproveNotificationDefaultRecipient, [Parameter()] [System.String[]] $ActivationApproveNotificationAdditionalRecipient, [Parameter()] [System.Boolean] $ActivationApproveNotificationOnlyCritical, [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()] [System.String] $CertificatePath, [Parameter()] [System.Management.Automation.PSCredential] $CertificatePassword, [Parameter()] [Switch] $ManagedIdentity, [Parameter()] [System.String[]] $AccessTokens ) #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 $result = Test-M365DSCTargetResource -DesiredValues $PSBoundParameters ` -ResourceName $($MyInvocation.MyCommand.Source).Replace('MSFT_', '') return $result } 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()] [System.String] $CertificatePath, [Parameter()] [System.Management.Automation.PSCredential] $CertificatePassword, [Parameter()] [Switch] $ManagedIdentity, [Parameter()] [System.String[]] $AccessTokens ) $ConnectionMode = New-M365DSCConnection -Workload 'Azure' ` -InboundParameters $PSBoundParameters $null = 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 { $apiVersion = '2020-10-01' if ($Filter -eq 'ModifiedOnly') { Write-Verbose -Message 'ModifiedOnly filter specified: only policies with lastModifiedDateTime set (customised from defaults) will be exported.' } else { Write-Verbose -Message 'No ModifiedOnly filter: all policies including unchanged defaults will be exported.' } # Collect all scopes to enumerate $scopes = @() # Add subscriptions $subUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)subscriptions?api-version=2022-12-01" $subResponse = Invoke-AzRestMethod -Uri $subUri -Method GET $subscriptions = (ConvertFrom-Json $subResponse.Content).value foreach ($sub in $subscriptions) { $scopes += @{ ScopeId = "subscriptions/$($sub.subscriptionId)" DisplayName = $sub.displayName ScopeType = 'Subscription' } # Add resource groups under each subscription $rgUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)subscriptions/$($sub.subscriptionId)/resourcegroups?api-version=2021-04-01" $rgResponse = Invoke-AzRestMethod -Uri $rgUri -Method GET $resourceGroups = (ConvertFrom-Json $rgResponse.Content).value foreach ($rg in $resourceGroups) { $scopes += @{ ScopeId = "subscriptions/$($sub.subscriptionId)/resourceGroups/$($rg.name)" DisplayName = $rg.name ScopeType = 'ResourceGroup' } } } # Add management groups $mgUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)providers/Microsoft.Management/managementGroups?api-version=2021-04-01" $mgResponse = Invoke-AzRestMethod -Uri $mgUri -Method GET $managementGroups = (ConvertFrom-Json $mgResponse.Content).value foreach ($mg in $managementGroups) { $scopes += @{ ScopeId = "providers/Microsoft.Management/managementGroups/$($mg.name)" DisplayName = $mg.properties.displayName ScopeType = 'ManagementGroup' } } [System.Collections.Generic.List[hashtable]] $exportedInstances = [System.Collections.Generic.List[hashtable]]::new() $dscContent = [System.Text.StringBuilder]::new() Write-M365DSCHost -Message "`r`n" -DeferWrite $j = 1 foreach ($scopeInfo in $scopes) { $currentScope = $scopeInfo.ScopeId Write-M365DSCHost -Message " |---[$j/$($scopes.Count)] $($scopeInfo.ScopeType): $($scopeInfo.DisplayName)`r`n" -DeferWrite # Get role management policy assignments for this scope $assignUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$currentScope/providers/Microsoft.Authorization/roleManagementPolicyAssignments?api-version=$apiVersion" $assignResponse = Invoke-AzRestMethod -Uri $assignUri -Method GET $assignments = (ConvertFrom-Json $assignResponse.Content).value if ($null -eq $assignments -or $assignments.Count -eq 0) { $j++ continue } # Bulk-fetch all role management policies for this scope in a single API call $bulkPolicyUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$currentScope/providers/Microsoft.Authorization/roleManagementPolicies?api-version=$apiVersion" $bulkPolicyResponse = Invoke-AzRestMethod -Uri $bulkPolicyUri -Method GET $allPolicies = $null if ($null -ne $bulkPolicyResponse -and -not [System.String]::IsNullOrEmpty($bulkPolicyResponse.Content)) { $allPolicies = (ConvertFrom-Json $bulkPolicyResponse.Content).value } if ($null -eq $allPolicies) { Write-Verbose -Message "Could not retrieve role management policies at scope {$currentScope}. Skipping." $j++ continue } # Build a lookup hashtable keyed by policy name for fast matching $policyLookup = @{} foreach ($pol in $allPolicies) { $policyName = $pol.name $policyLookup[$policyName] = $pol } # Phase 1: Collect valid (filtered) instances for this scope $scopeInstances = [System.Collections.Generic.List[hashtable]]::new() foreach ($assignment in $assignments) { $roleDisplayName = $null if ($null -ne $assignment.properties.policyAssignmentProperties -and $null -ne $assignment.properties.policyAssignmentProperties.roleDefinition) { $roleDisplayName = $assignment.properties.policyAssignmentProperties.roleDefinition.displayName } if ([System.String]::IsNullOrEmpty($roleDisplayName)) { $roleDefId = $assignment.properties.roleDefinitionId if (-not [System.String]::IsNullOrEmpty($roleDefId)) { $roleDefUri = "$((Get-MSCloudLoginConnectionProfile -Workload Azure).ManagementUrl)$roleDefId`?api-version=$apiVersion" $roleDefResponse = Invoke-AzRestMethod -Uri $roleDefUri -Method GET $roleDef = ConvertFrom-Json $roleDefResponse.Content $roleDisplayName = $roleDef.properties.roleName } } if ([System.String]::IsNullOrEmpty($roleDisplayName)) { continue } $assignmentPolicyId = $assignment.properties.policyId.Split('/')[-1] # Look up policy from bulk-fetched results instead of individual API call $policyContent = $policyLookup[$assignmentPolicyId] if ($null -eq $policyContent -or $null -eq $policyContent.properties -or $null -eq $policyContent.properties.rules) { Write-Verbose -Message "Policy {$assignmentPolicyId} not found in bulk response for scope {$currentScope}. Skipping." continue } # When the 'ModifiedOnly' sentinel filter is specified, skip policies that have # not been customised from Azure defaults (lastModifiedDateTime is null). # Without this filter, all policies (including default/unchanged) are exported. $lastModifiedDateTime = $policyContent.properties.lastModifiedDateTime if ($Filter -eq 'ModifiedOnly' -and $null -eq $lastModifiedDateTime) { Write-Verbose -Message "ModifiedOnly filter active: Policy {$assignmentPolicyId} has not been modified from Azure defaults. Skipping." continue } $scopeInstances.Add(@{ RoleDisplayName = $roleDisplayName PolicyId = $assignmentPolicyId Rules = $policyContent.properties.rules }) } # Add scope instances to the global exported instances collection foreach ($inst in $scopeInstances) { $exportedInstances.Add($inst) } # Phase 2: Export collected instances $i = 1 foreach ($instance in $scopeInstances) { if ($null -ne $Global:M365DSCExportResourceInstancesCount) { $Global:M365DSCExportResourceInstancesCount++ } Write-M365DSCHost -Message " |---[$i/$($scopeInstances.Count)] $($instance.RoleDisplayName)" -DeferWrite $Params = @{ RoleDefinitionDisplayName = $instance.RoleDisplayName ScopeId = $currentScope Credential = $Credential ApplicationId = $ApplicationId TenantId = $TenantId ApplicationSecret = $ApplicationSecret CertificateThumbprint = $CertificateThumbprint CertificatePath = $CertificatePath CertificatePassword = $CertificatePassword ManagedIdentity = $ManagedIdentity.IsPresent AccessTokens = $AccessTokens } $Script:exportedInstance = @{ rules = $instance.Rules policyId = $instance.PolicyId } $Results = Get-TargetResource @Params $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` -ConnectionMode $ConnectionMode ` -ModulePath $PSScriptRoot ` -Results $Results ` -Credential $Credential [void]$dscContent.Append($currentDSCBlock) Save-M365DSCPartialExport -Content $currentDSCBlock ` -FileName $Global:PartialExportFileName Write-M365DSCHost -Message $Global:M365DSCEmojiGreenCheckMark -CommitWrite $i++ } $j++ } return $dscContent.ToString() } catch { New-M365DSCLogEntry -Message 'Error during Export:' ` -Exception $_ ` -Source $($MyInvocation.MyCommand.Source) ` -TenantId $TenantId ` -Credential $Credential throw } } Export-ModuleMember -Function *-TargetResource |