From e1cd7081c70a0a48167d16c5a675332e1b26bc48 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Fri, 20 Dec 2024 17:04:26 +0100 Subject: [PATCH 01/11] wip --- ...FT_AADGroupEligibilityScheduleRequest.psm1 | 1183 +++++++++++++++ ...GroupEligibilityScheduleRequest.schema.mof | 148 ++ .../readme.md | 6 + .../settings.json | 29 + ...DGroupEligibilityScheduleRequest.Tests.ps1 | 1290 +++++++++++++++++ Tests/Unit/Stubs/Microsoft365.psm1 | 462 ++++++ 6 files changed, 3118 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 new file mode 100644 index 0000000000..8beb002bfd --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 @@ -0,0 +1,1183 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $TargetScheduleId, + + [Parameter()] + [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] + [System.String] + $Action, + + [Parameter()] + [System.Boolean] + $IsValidationOnly, + + [Parameter()] + [System.String] + $Justification, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $TicketInfo, + + [Parameter()] + [System.String] + $ApprovalId, + + [Parameter()] + [System.String] + $CompletedDateTime, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $CreatedBy, + + [Parameter()] + [System.String] + $CustomData, + + [Parameter()] + [System.String] + $Id, + + #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 + ) + + Write-Verbose -Message "Getting configuration of the Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" + + 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 + if (-not $PSBoundParameters.ContainsKey('Id') -or [string]::IsNullOrEmpty($Id)) { + $Group = Get-MgGroup -Filter "displayName eq '$GroupDisplayName'" -ErrorAction SilentlyContinue + if([string]::IsNullOrEmpty($GroupId)){ + Write-Verbose -Message "Could not find an Azure AD Group with DisplayName {$GroupDisplayName}." + return $nullResult + } + elseif($Group.Length -gt 1){ + Write-Verbose -Message "Found multiple Azure AD Groups with DisplayName {$GroupDisplayName}." + return $nullResult + } + else{ + $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Filter "groupId eq '$($Group.Id)'" -ErrorAction SilentlyContinue + } + } + else{ + $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -PrivilegedAccessGroupEligibilityScheduleRequestId $Id -ErrorAction SilentlyContinue + } + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Azure AD Group Eligibility Schedule Request with Id {$Id}." + return $nullResult + } + $Id = $getValue.Id + Write-Verbose -Message "An Azure AD Group Eligibility Schedule Request with Id {$Id} for Group {$($group.DisplayName)} was found" + + #region resource generator code + $complexScheduleInfo = @{} + $complexExpiration = @{} + $complexExpiration.Add('Duration', $getValue.additionalProperties.scheduleInfo.expiration.duration) + if ($null -ne $getValue.additionalProperties.scheduleInfo.expiration.endDateTime) + { + $complexExpiration.Add('EndDateTime', ([DateTimeOffset]$getValue.additionalProperties.scheduleInfo.expiration.endDateTime).ToString('')) + } + if ($null -ne $getValue.additionalProperties.scheduleInfo.expiration.type) + { + $complexExpiration.Add('Type', $getValue.additionalProperties.scheduleInfo.expiration.type.ToString()) + } + if ($complexExpiration.values.Where({$null -ne $_}).Count -eq 0) + { + $complexExpiration = $null + } + $complexScheduleInfo.Add('Expiration',$complexExpiration) + $complexRecurrence = @{} + $complexPattern = @{} + $complexPattern.Add('DayOfMonth', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.dayOfMonth) + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.daysOfWeek) + { + $complexPattern.Add('DaysOfWeek', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.daysOfWeek.ToString()) + } + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.firstDayOfWeek) + { + $complexPattern.Add('FirstDayOfWeek', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.firstDayOfWeek.ToString()) + } + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.index) + { + $complexPattern.Add('Index', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.index.ToString()) + } + $complexPattern.Add('Interval', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.interval) + $complexPattern.Add('Month', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.month) + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.type) + { + $complexPattern.Add('Type', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.type.ToString()) + } + if ($complexPattern.values.Where({$null -ne $_}).Count -eq 0) + { + $complexPattern = $null + } + $complexRecurrence.Add('Pattern',$complexPattern) + $complexRange = @{} + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.endDate) + { + $complexRange.Add('EndDate', ([DateTime]$getValue.additionalProperties.scheduleInfo.recurrence.range.endDate).ToString('')) + } + $complexRange.Add('NumberOfOccurrences', $getValue.additionalProperties.scheduleInfo.recurrence.range.numberOfOccurrences) + $complexRange.Add('RecurrenceTimeZone', $getValue.additionalProperties.scheduleInfo.recurrence.range.recurrenceTimeZone) + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.startDate) + { + $complexRange.Add('StartDate', ([DateTime]$getValue.additionalProperties.scheduleInfo.recurrence.range.startDate).ToString('')) + } + if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.type) + { + $complexRange.Add('Type', $getValue.additionalProperties.scheduleInfo.recurrence.range.type.ToString()) + } + if ($complexRange.values.Where({$null -ne $_}).Count -eq 0) + { + $complexRange = $null + } + $complexRecurrence.Add('Range',$complexRange) + if ($complexRecurrence.values.Where({$null -ne $_}).Count -eq 0) + { + $complexRecurrence = $null + } + $complexScheduleInfo.Add('Recurrence',$complexRecurrence) + if ($null -ne $getValue.AdditionalProperties.scheduleInfo.startDateTime) + { + $complexScheduleInfo.Add('StartDateTime', ([DateTimeOffset]$getValue.AdditionalProperties.scheduleInfo.startDateTime).ToString('o')) + } + if ($complexScheduleInfo.values.Where({$null -ne $_}).Count -eq 0) + { + $complexScheduleInfo = $null + } + + $complexTicketInfo = @{} + $complexTicketInfo.Add('TicketNumber', $getValue.AdditionalProperties.ticketInfo.ticketNumber) + $complexTicketInfo.Add('TicketSystem', $getValue.AdditionalProperties.ticketInfo.ticketSystem) + if ($complexTicketInfo.values.Where({$null -ne $_}).Count -eq 0) + { + $complexTicketInfo = $null + } + + $complexCreatedBy = @{} + $complexApplication = @{} + $complexApplication.Add('id', $getValue.createdBy.application.id) + $complexApplication.Add('displayName', $getValue.createdBy.application.displayName) + if ($complexApplication.values.Where({$null -ne $_}).Count -eq 0) + { + $complexApplication = $null + } + $complexCreatedBy.Add('Application',$complexApplication) + $complexDevice = @{} + $complexDevice.Add('id', $getValue.createdBy.device.id) + $complexDevice.Add('displayName', $getValue.createdBy.device.displayName) + if ($complexDevice.values.Where({$null -ne $_}).Count -eq 0) + { + $complexDevice = $null + } + $complexCreatedBy.Add('Device',$complexDevice) + $complexUser = @{} + $complexUser.Add('id', $getValue.createdBy.user.id) + $complexUser.Add('displayName', $getValue.createdBy.user.displayName) + if ($complexUser.values.Where({$null -ne $_}).Count -eq 0) + { + $complexUser = $null + } + $complexCreatedBy.Add('User',$complexUser) + $complexConversation = @{} + if ($null -ne $getValue.createdBy.conversation.conversationIdentityType) + { + $complexConversation.Add('ConversationIdentityType', $getValue.createdBy.conversation.conversationIdentityType.ToString()) + } + $complexConversation.Add('DisplayName', $getValue.createdBy.conversation.displayName) + $complexConversation.Add('Id', $getValue.createdBy.conversation.id) + $complexConversation.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.conversation.azureCommunicationServicesResourceId) + $complexConversation.Add('ApplicationType', $getValue.createdBy.conversation.applicationType) + $complexConversation.Add('Hidden', $getValue.createdBy.conversation.hidden) + $complexConversation.Add('TenantId', $getValue.createdBy.conversation.tenantId) + $complexConversation.Add('Email', $getValue.createdBy.conversation.email) + if ($null -ne $getValue.createdBy.conversation.initiatorType) + { + $complexConversation.Add('InitiatorType', $getValue.createdBy.conversation.initiatorType.ToString()) + } + $complexDetails = @{} + if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) + { + $complexDetails = $null + } + $complexConversation.Add('Details',$complexDetails) + $complexConversation.Add('IdentityType', $getValue.createdBy.conversation.identityType) + $complexConversation.Add('AppId', $getValue.createdBy.conversation.appId) + $complexConversation.Add('LoginName', $getValue.createdBy.conversation.loginName) + if ($null -ne $getValue.createdBy.conversation.applicationIdentityType) + { + $complexConversation.Add('ApplicationIdentityType', $getValue.createdBy.conversation.applicationIdentityType.ToString()) + } + if ($null -ne $getValue.createdBy.conversation.userIdentityType) + { + $complexConversation.Add('UserIdentityType', $getValue.createdBy.conversation.userIdentityType.ToString()) + } + $complexConversation.Add('IpAddress', $getValue.createdBy.conversation.ipAddress) + $complexConversation.Add('UserPrincipalName', $getValue.createdBy.conversation.userPrincipalName) + if ($null -ne $getValue.createdBy.conversation.'@odata.type') + { + $complexConversation.Add('odataType', $getValue.createdBy.conversation.'@odata.type'.ToString()) + } + if ($complexConversation.values.Where({$null -ne $_}).Count -eq 0) + { + $complexConversation = $null + } + $complexCreatedBy.Add('Conversation',$complexConversation) + $complexApplicationInstance = @{} + $complexApplicationInstance.Add('Type', $getValue.createdBy.applicationInstance.type) + if ($complexApplicationInstance.values.Where({$null -ne $_}).Count -eq 0) + { + $complexApplicationInstance = $null + } + $complexCreatedBy.Add('ApplicationInstance',$complexApplicationInstance) + $complexAssertedIdentity = @{} + $complexAssertedIdentity.Add('Type', $getValue.createdBy.assertedIdentity.type) + if ($complexAssertedIdentity.values.Where({$null -ne $_}).Count -eq 0) + { + $complexAssertedIdentity = $null + } + $complexCreatedBy.Add('AssertedIdentity',$complexAssertedIdentity) + $complexAzureCommunicationServicesUser = @{} + $complexAzureCommunicationServicesUser.Add('Type', $getValue.createdBy.azureCommunicationServicesUser.type) + if ($complexAzureCommunicationServicesUser.values.Where({$null -ne $_}).Count -eq 0) + { + $complexAzureCommunicationServicesUser = $null + } + $complexCreatedBy.Add('AzureCommunicationServicesUser',$complexAzureCommunicationServicesUser) + $complexEncrypted = @{} + $complexEncrypted.Add('Type', $getValue.createdBy.encrypted.type) + if ($complexEncrypted.values.Where({$null -ne $_}).Count -eq 0) + { + $complexEncrypted = $null + } + $complexCreatedBy.Add('Encrypted',$complexEncrypted) + if ($null -ne $getValue.CreatedBy.endpointType) + { + $complexCreatedBy.Add('EndpointType', $getValue.CreatedBy.endpointType.ToString()) + } + $complexGuest = @{} + $complexGuest.Add('Type', $getValue.createdBy.guest.type) + if ($complexGuest.values.Where({$null -ne $_}).Count -eq 0) + { + $complexGuest = $null + } + $complexCreatedBy.Add('Guest',$complexGuest) + $complexOnPremises = @{} + $complexOnPremises.Add('Type', $getValue.createdBy.onPremises.type) + if ($complexOnPremises.values.Where({$null -ne $_}).Count -eq 0) + { + $complexOnPremises = $null + } + $complexCreatedBy.Add('OnPremises',$complexOnPremises) + $complexPhone = @{} + $complexPhone.Add('Type', $getValue.createdBy.phone.type) + if ($complexPhone.values.Where({$null -ne $_}).Count -eq 0) + { + $complexPhone = $null + } + $complexCreatedBy.Add('Phone',$complexPhone) + $complexGroup = @{} + $complexGroup.Add('Type', $getValue.createdBy.group.type) + if ($complexGroup.values.Where({$null -ne $_}).Count -eq 0) + { + $complexGroup = $null + } + $complexCreatedBy.Add('Group',$complexGroup) + $complexSiteGroup = @{} + $complexSiteGroup.Add('LoginName', $getValue.createdBy.siteGroup.loginName) + $complexSiteGroup.Add('DisplayName', $getValue.createdBy.siteGroup.displayName) + $complexSiteGroup.Add('Id', $getValue.createdBy.siteGroup.id) + $complexSiteGroup.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.siteGroup.azureCommunicationServicesResourceId) + $complexSiteGroup.Add('ApplicationType', $getValue.createdBy.siteGroup.applicationType) + $complexSiteGroup.Add('Hidden', $getValue.createdBy.siteGroup.hidden) + $complexSiteGroup.Add('TenantId', $getValue.createdBy.siteGroup.tenantId) + $complexSiteGroup.Add('Email', $getValue.createdBy.siteGroup.email) + if ($null -ne $getValue.createdBy.siteGroup.initiatorType) + { + $complexSiteGroup.Add('InitiatorType', $getValue.createdBy.siteGroup.initiatorType.ToString()) + } + $complexDetails = @{} + if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) + { + $complexDetails = $null + } + $complexSiteGroup.Add('Details',$complexDetails) + $complexSiteGroup.Add('IdentityType', $getValue.createdBy.siteGroup.identityType) + $complexSiteGroup.Add('AppId', $getValue.createdBy.siteGroup.appId) + if ($null -ne $getValue.createdBy.siteGroup.applicationIdentityType) + { + $complexSiteGroup.Add('ApplicationIdentityType', $getValue.createdBy.siteGroup.applicationIdentityType.ToString()) + } + if ($null -ne $getValue.createdBy.siteGroup.conversationIdentityType) + { + $complexSiteGroup.Add('ConversationIdentityType', $getValue.createdBy.siteGroup.conversationIdentityType.ToString()) + } + if ($null -ne $getValue.createdBy.siteGroup.userIdentityType) + { + $complexSiteGroup.Add('UserIdentityType', $getValue.createdBy.siteGroup.userIdentityType.ToString()) + } + $complexSiteGroup.Add('IpAddress', $getValue.createdBy.siteGroup.ipAddress) + $complexSiteGroup.Add('UserPrincipalName', $getValue.createdBy.siteGroup.userPrincipalName) + if ($null -ne $getValue.createdBy.siteGroup.'@odata.type') + { + $complexSiteGroup.Add('odataType', $getValue.createdBy.siteGroup.'@odata.type'.ToString()) + } + if ($complexSiteGroup.values.Where({$null -ne $_}).Count -eq 0) + { + $complexSiteGroup = $null + } + $complexCreatedBy.Add('SiteGroup',$complexSiteGroup) + $complexSiteUser = @{} + $complexSiteUser.Add('LoginName', $getValue.createdBy.siteUser.loginName) + $complexSiteUser.Add('DisplayName', $getValue.createdBy.siteUser.displayName) + $complexSiteUser.Add('Id', $getValue.createdBy.siteUser.id) + $complexSiteUser.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.siteUser.azureCommunicationServicesResourceId) + $complexSiteUser.Add('ApplicationType', $getValue.createdBy.siteUser.applicationType) + $complexSiteUser.Add('Hidden', $getValue.createdBy.siteUser.hidden) + $complexSiteUser.Add('TenantId', $getValue.createdBy.siteUser.tenantId) + $complexSiteUser.Add('Email', $getValue.createdBy.siteUser.email) + if ($null -ne $getValue.createdBy.siteUser.initiatorType) + { + $complexSiteUser.Add('InitiatorType', $getValue.createdBy.siteUser.initiatorType.ToString()) + } + $complexDetails = @{} + if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) + { + $complexDetails = $null + } + $complexSiteUser.Add('Details',$complexDetails) + $complexSiteUser.Add('IdentityType', $getValue.createdBy.siteUser.identityType) + $complexSiteUser.Add('AppId', $getValue.createdBy.siteUser.appId) + if ($null -ne $getValue.createdBy.siteUser.applicationIdentityType) + { + $complexSiteUser.Add('ApplicationIdentityType', $getValue.createdBy.siteUser.applicationIdentityType.ToString()) + } + if ($null -ne $getValue.createdBy.siteUser.conversationIdentityType) + { + $complexSiteUser.Add('ConversationIdentityType', $getValue.createdBy.siteUser.conversationIdentityType.ToString()) + } + if ($null -ne $getValue.createdBy.siteUser.userIdentityType) + { + $complexSiteUser.Add('UserIdentityType', $getValue.createdBy.siteUser.userIdentityType.ToString()) + } + $complexSiteUser.Add('IpAddress', $getValue.createdBy.siteUser.ipAddress) + $complexSiteUser.Add('UserPrincipalName', $getValue.createdBy.siteUser.userPrincipalName) + if ($null -ne $getValue.createdBy.siteUser.'@odata.type') + { + $complexSiteUser.Add('odataType', $getValue.createdBy.siteUser.'@odata.type'.ToString()) + } + if ($complexSiteUser.values.Where({$null -ne $_}).Count -eq 0) + { + $complexSiteUser = $null + } + $complexCreatedBy.Add('SiteUser',$complexSiteUser) + if ($null -ne $getValue.CreatedBy.'@odata.type') + { + $complexCreatedBy.Add('odataType', $getValue.CreatedBy.'@odata.type'.ToString()) + } + if ($complexCreatedBy.values.Where({$null -ne $_}).Count -eq 0) + { + $complexCreatedBy = $null + } + #endregion + + #region resource generator code + $enumAccessId = $null + if ($null -ne $getValue.AdditionalProperties.accessId) + { + $enumAccessId = $getValue.AdditionalProperties.accessId.ToString() + } + + $enumAction = $null + if ($null -ne $getValue.AdditionalProperties.action) + { + $enumAction = $getValue.AdditionalProperties.action.ToString() + } + #endregion + + #region resource generator code + $dateCompletedDateTime = $null + if ($null -ne $getValue.CompletedDateTime) + { + $dateCompletedDateTime = ([DateTimeOffset]$getValue.CompletedDateTime).ToString('o') + } + #endregion + + $results = @{ + #region resource generator code + AccessId = $enumAccessId + GroupId = $getValue.groupId + GroupDisplayName = $group.DisplayName + PrincipalId = $getValue.principalId + TargetScheduleId = $getValue.targetScheduleId + Action = $enumAction + IsValidationOnly = $getValue.isValidationOnly + Justification = $getValue.justification + ScheduleInfo = $complexScheduleInfo + TicketInfo = $complexTicketInfo + ApprovalId = $getValue.ApprovalId + CompletedDateTime = $dateCompletedDateTime + CreatedBy = $complexCreatedBy + CustomData = $getValue.CustomData + Id = $getValue.Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + #endregion + } + + 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()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $TargetScheduleId, + + [Parameter()] + [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] + [System.String] + $Action, + + [Parameter()] + [System.Boolean] + $IsValidationOnly, + + [Parameter()] + [System.String] + $Justification, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $TicketInfo, + + [Parameter()] + [System.String] + $ApprovalId, + + [Parameter()] + [System.String] + $CompletedDateTime, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $CreatedBy, + + [Parameter()] + [System.String] + $CustomData, + + [Parameter()] + [System.String] + $Id, + + #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 + ) + + Write-Verbose -Message "Setting configuration of the Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" + + #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 + + + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating an Azure AD Group Eligibility Schedule Request with DisplayName {$DisplayName}" + + $createParameters = ([Hashtable]$BoundParameters).Clone() + $createParameters = Rename-M365DSCCimInstanceParameter -Properties $createParameters + $createParameters.Remove('Id') | Out-Null + + $keys = (([Hashtable]$createParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $createParameters.$key -and $createParameters.$key.GetType().Name -like '*CimInstance*') + { + $createParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $createParameters.$key + } + } + #region resource generator code + $createParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest") + $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $createParameters + #endregion + } + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating the Azure AD Group Eligibility Schedule Request with Id {$($currentInstance.Id)}" + + $updateParameters = ([Hashtable]$BoundParameters).Clone() + $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters + + $updateParameters.Remove('Id') | Out-Null + + $keys = (([Hashtable]$updateParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $pdateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') + { + $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.PrivilegedAccessGroupEligibilityScheduleRequestId + } + } + + #region resource generator code + $UpdateParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest") + Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ` + -PrivilegedAccessGroupEligibilityScheduleRequestId $currentInstance.Id ` + -BodyParameter $UpdateParameters + #endregion + } + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing the Azure AD Group Eligibility Schedule Request with Id {$($currentInstance.Id)}" + #region resource generator code + Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -PrivilegedAccessGroupEligibilityScheduleRequestId $currentInstance.Id + #endregion + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region resource generator code + [Parameter()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $TargetScheduleId, + + [Parameter()] + [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] + [System.String] + $Action, + + [Parameter()] + [System.Boolean] + $IsValidationOnly, + + [Parameter()] + [System.String] + $Justification, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $TicketInfo, + + [Parameter()] + [System.String] + $ApprovalId, + + [Parameter()] + [System.String] + $CompletedDateTime, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $CreatedBy, + + [Parameter()] + [System.String] + $CustomData, + + [Parameter()] + [System.String] + $Id, + + #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 Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + + 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 $ValuesToCheck)" + + 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 + $groups = Get-MgGroup -Filter "MailEnabled eq false and NOT(groupTypes/any(x:x eq 'DynamicMembership'))" -Property "displayname,Id" -CountVariable CountVar -ConsistencyLevel eventual -ErrorAction Stop + foreach ($group in $groups) + { + $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ` + -Filter "groupId eq '$($group.Id)'" ` + -All ` + -ErrorAction Stop + if($null -eq $getValue) + { + continue + } + #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 + " / " + $group.DisplayName + Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline + $params = @{ + Id = $config.Id + GroupDisplayName = $group.DisplayName + 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 ($null -ne $Results.ScheduleInfo) + { + $complexMapping = @( + @{ + Name = 'ScheduleInfo' + CimInstanceName = 'MicrosoftGraphRequestSchedule' + IsRequired = $False + } + @{ + Name = 'Expiration' + CimInstanceName = 'MicrosoftGraphExpirationPattern' + IsRequired = $False + } + @{ + Name = 'Recurrence' + CimInstanceName = 'MicrosoftGraphPatternedRecurrence1' + IsRequired = $False + } + @{ + Name = 'Pattern' + CimInstanceName = 'MicrosoftGraphRecurrencePattern1' + IsRequired = $False + } + @{ + Name = 'Range' + CimInstanceName = 'MicrosoftGraphRecurrenceRange1' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.ScheduleInfo ` + -CIMInstanceName 'MicrosoftGraphrequestSchedule' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.ScheduleInfo = $complexTypeStringResult + } + else + { + $Results.Remove('ScheduleInfo') | Out-Null + } + } + if ($null -ne $Results.TicketInfo) + { + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.TicketInfo ` + -CIMInstanceName 'MicrosoftGraphticketInfo' + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.TicketInfo = $complexTypeStringResult + } + else + { + $Results.Remove('TicketInfo') | Out-Null + } + } + if ($null -ne $Results.CreatedBy) + { + $complexMapping = @( + @{ + Name = 'CreatedBy' + CimInstanceName = 'MicrosoftGraphIdentitySet' + IsRequired = $False + } + @{ + Name = 'Application' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Device' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'User' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Conversation' + CimInstanceName = 'MicrosoftGraphTeamworkConversationIdentity' + IsRequired = $False + } + @{ + Name = 'Details' + CimInstanceName = 'MicrosoftGraphDetailsInfo' + IsRequired = $False + } + @{ + Name = 'ApplicationInstance' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'AssertedIdentity' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'AzureCommunicationServicesUser' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Encrypted' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Guest' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'OnPremises' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Phone' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'Group' + CimInstanceName = 'MicrosoftGraphIdentity' + IsRequired = $False + } + @{ + Name = 'SiteGroup' + CimInstanceName = 'MicrosoftGraphSharePointIdentity' + IsRequired = $False + } + @{ + Name = 'Details' + CimInstanceName = 'MicrosoftGraphDetailsInfo' + IsRequired = $False + } + @{ + Name = 'SiteUser' + CimInstanceName = 'MicrosoftGraphSharePointIdentity' + IsRequired = $False + } + @{ + Name = 'Details' + CimInstanceName = 'MicrosoftGraphDetailsInfo' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.CreatedBy ` + -CIMInstanceName 'MicrosoftGraphidentitySet' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.CreatedBy = $complexTypeStringResult + } + else + { + $Results.Remove('CreatedBy') | Out-Null + } + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + if ($Results.ScheduleInfo) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "ScheduleInfo" -IsCIMArray:$False + } + if ($Results.TicketInfo) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "TicketInfo" -IsCIMArray:$False + } + if ($Results.CreatedBy) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "CreatedBy" -IsCIMArray:$False + } + + $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_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof new file mode 100644 index 0000000000..e3f303d040 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof @@ -0,0 +1,148 @@ +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRequestSchedule +{ + [Write, Description("When the eligible or active assignment expires."), EmbeddedInstance("MSFT_MicrosoftGraphExpirationPattern")] String Expiration; + [Write, Description("The frequency of the eligible or active assignment. This property is currently unsupported in PIM."), EmbeddedInstance("MSFT_MicrosoftGraphPatternedRecurrence1")] String Recurrence; + [Write, Description("When the eligible or active assignment becomes active.")] String StartDateTime; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphExpirationPattern +{ + [Write, Description("The requestor's desired duration of access represented in ISO 8601 format for durations. For example, PT3H refers to three hours. If specified in a request, endDateTime should not be present and the type property should be set to afterDuration.")] String Duration; + [Write, Description("Timestamp of date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z.")] String EndDateTime; + [Write, Description("The requestor's desired expiration pattern type. The possible values are: notSpecified, noExpiration, afterDateTime, afterDuration."), ValueMap{"notSpecified","noExpiration","afterDateTime","afterDuration"}, Values{"notSpecified","noExpiration","afterDateTime","afterDuration"}] String Type; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphPatternedRecurrence1 +{ + [Write, Description("The frequency of an event. For access reviews: Do not specify this property for a one-time access review. Only interval, dayOfMonth, and type (weekly, absoluteMonthly) properties of recurrencePattern are supported."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrencePattern1")] String Pattern; + [Write, Description("The duration of an event."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrenceRange1")] String Range; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRecurrencePattern1 +{ + [Write, Description("The day of the month on which the event occurs. Required if type is absoluteMonthly or absoluteYearly.")] UInt32 DayOfMonth; + [Write, Description("A collection of the days of the week on which the event occurs. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. If type is relativeMonthly or relativeYearly, and daysOfWeek specifies more than one day, the event falls on the first day that satisfies the pattern. Required if type is weekly, relativeMonthly, or relativeYearly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String DaysOfWeek[]; + [Write, Description("The first day of the week. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. Default is sunday. Required if type is weekly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String FirstDayOfWeek; + [Write, Description("Specifies on which instance of the allowed days specified in daysOfWeek the event occurs, counted from the first instance in the month. The possible values are: first, second, third, fourth, last. Default is first. Optional and used if type is relativeMonthly or relativeYearly."), ValueMap{"first","second","third","fourth","last"}, Values{"first","second","third","fourth","last"}] String Index; + [Write, Description("The number of units between occurrences, where units can be in days, weeks, months, or years, depending on the type. Required.")] UInt32 Interval; + [Write, Description("The month in which the event occurs. This is a number from 1 to 12.")] UInt32 Month; + [Write, Description("The recurrence pattern type: daily, weekly, absoluteMonthly, relativeMonthly, absoluteYearly, relativeYearly. Required. For more information, see values of type property."), ValueMap{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}, Values{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}] String Type; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRecurrenceRange1 +{ + [Write, Description("The date to stop applying the recurrence pattern. Depending on the recurrence pattern of the event, the last occurrence of the meeting may not be this date. Required if type is endDate.")] String EndDate; + [Write, Description("The number of times to repeat the event. Required and must be positive if type is numbered.")] UInt32 NumberOfOccurrences; + [Write, Description("Time zone for the startDate and endDate properties. Optional. If not specified, the time zone of the event is used.")] String RecurrenceTimeZone; + [Write, Description("The date to start applying the recurrence pattern. The first occurrence of the meeting may be this date or later, depending on the recurrence pattern of the event. Must be the same value as the start property of the recurring event. Required.")] String StartDate; + [Write, Description("The recurrence range. The possible values are: endDate, noEnd, numbered. Required."), ValueMap{"endDate","noEnd","numbered"}, Values{"endDate","noEnd","numbered"}] String Type; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphTicketInfo +{ + [Write, Description("The ticket number.")] String TicketNumber; + [Write, Description("The description of the ticket system.")] String TicketSystem; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphIdentitySet +{ + [Write, Description("Optional. The application associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Application; + [Write, Description("Optional. The device associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Device; + [Write, Description("Optional. The user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String User; + [Write, Description("If present, represents a conversation (for example, team or channel) mentioned in a message."), EmbeddedInstance("MSFT_MicrosoftGraphTeamworkConversationIdentity")] String Conversation; + [Write, Description("The application instance associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String ApplicationInstance; + [Write, Description("An identity the participant would like to present itself as to the other participants in the call."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String AssertedIdentity; + [Write, Description("The Azure Communication Services user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String AzureCommunicationServicesUser; + [Write, Description("The encrypted user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Encrypted; + [Write, Description("Type of endpoint that the participant uses. Possible values are: default, voicemail, skypeForBusiness, skypeForBusinessVoipPhone, unknownFutureValue."), ValueMap{"default","voicemail","skypeForBusiness","skypeForBusinessVoipPhone","unknownFutureValue"}, Values{"default","voicemail","skypeForBusiness","skypeForBusinessVoipPhone","unknownFutureValue"}] String EndpointType; + [Write, Description("The guest user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Guest; + [Write, Description("The Skype for Business on-premises user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String OnPremises; + [Write, Description("The phone user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Phone; + [Write, Description("The group associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Group; + [Write, Description("The SharePoint group associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphSharePointIdentity")] String SiteGroup; + [Write, Description("The SharePoint user associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphSharePointIdentity")] String SiteUser; + [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.chatMessageFromIdentitySet","#microsoft.graph.chatMessageMentionedIdentitySet","#microsoft.graph.chatMessageReactionIdentitySet","#microsoft.graph.communicationsIdentitySet","#microsoft.graph.sharePointIdentitySet"}, Values{"#microsoft.graph.chatMessageFromIdentitySet","#microsoft.graph.chatMessageMentionedIdentitySet","#microsoft.graph.chatMessageReactionIdentitySet","#microsoft.graph.communicationsIdentitySet","#microsoft.graph.sharePointIdentitySet"}] String odataType; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphIdentity +{ + [Write, Description("Id of the User group or device")] String Id; + [Write, Description("Displayname of the user group or device")] String displayName; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphTeamworkConversationIdentity +{ + [Write, Description("Type of conversation. Possible values are: team, channel, chat, and unknownFutureValue."), ValueMap{"team","channel","chat","unknownFutureValue"}, Values{"team","channel","chat","unknownFutureValue"}] String ConversationIdentityType; + [Write, Description("The display name of the identity.For drive items, the display name might not always be available or up to date. For example, if a user changes their display name the API might show the new value in a future response, but the items associated with the user don't show up as changed when using delta.")] String DisplayName; + [Write, Description("Unique identifier for the identity or actor. For example, in the access reviews decisions API, this property might record the id of the principal, that is, the group, user, or application that's subject to review.")] String Id; + [Write, Description("The Azure Communication Services resource ID associated with the user.")] String AzureCommunicationServicesResourceId; + [Write, Description("First-party Microsoft application that presents this identity.")] String ApplicationType; + [Write, Description("True if the participant shouldn't be shown in other participants' rosters.")] Boolean Hidden; + [Write, Description("The tenant ID of the application.")] String TenantId; + [Write, Description("Email address of the user.")] String Email; + [Write, Description("Type of initiator. Possible values are: user, application, system, unknownFutureValue."), ValueMap{"user","application","system","unknownFutureValue"}, Values{"user","application","system","unknownFutureValue"}] String InitiatorType; + [Write, Description("Details of the identity."), EmbeddedInstance("MSFT_MicrosoftGraphDetailsInfo")] String Details; + [Write, Description("Type of identity that has been provisioned, such as 'user' or 'group'. Supports $filter (eq, contains).")] String IdentityType; + [Write, Description("The application identifier of the service principal.")] String AppId; + [Write, Description("The sign in name of the SharePoint identity.")] String LoginName; + [Write, Description("Type of application that is referenced. Possible values are: aadApplication, bot, tenantBot, office365Connector, outgoingWebhook, and unknownFutureValue."), ValueMap{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}, Values{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}] String ApplicationIdentityType; + [Write, Description("Type of user. Possible values are: aadUser, onPremiseAadUser, anonymousGuest, federatedUser, personalMicrosoftAccountUser, skypeUser, phoneUser, unknownFutureValue and emailUser."), ValueMap{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}, Values{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}] String UserIdentityType; + [Write, Description("Indicates the client IP address associated with the user performing the activity (audit log only).")] String IpAddress; + [Write, Description("The userPrincipalName attribute of the user.")] String UserPrincipalName; + [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}, Values{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}] String odataType; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphDetailsInfo +{ +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphSharePointIdentity +{ + [Write, Description("The sign in name of the SharePoint identity.")] String LoginName; + [Write, Description("The display name of the identity.For drive items, the display name might not always be available or up to date. For example, if a user changes their display name the API might show the new value in a future response, but the items associated with the user don't show up as changed when using delta.")] String DisplayName; + [Write, Description("Unique identifier for the identity or actor. For example, in the access reviews decisions API, this property might record the id of the principal, that is, the group, user, or application that's subject to review.")] String Id; + [Write, Description("The Azure Communication Services resource ID associated with the user.")] String AzureCommunicationServicesResourceId; + [Write, Description("First-party Microsoft application that presents this identity.")] String ApplicationType; + [Write, Description("True if the participant shouldn't be shown in other participants' rosters.")] Boolean Hidden; + [Write, Description("The tenant ID of the application.")] String TenantId; + [Write, Description("Email address of the user.")] String Email; + [Write, Description("Type of initiator. Possible values are: user, application, system, unknownFutureValue."), ValueMap{"user","application","system","unknownFutureValue"}, Values{"user","application","system","unknownFutureValue"}] String InitiatorType; + [Write, Description("Details of the identity."), EmbeddedInstance("MSFT_MicrosoftGraphDetailsInfo")] String Details; + [Write, Description("Type of identity that has been provisioned, such as 'user' or 'group'. Supports $filter (eq, contains).")] String IdentityType; + [Write, Description("The application identifier of the service principal.")] String AppId; + [Write, Description("Type of application that is referenced. Possible values are: aadApplication, bot, tenantBot, office365Connector, outgoingWebhook, and unknownFutureValue."), ValueMap{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}, Values{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}] String ApplicationIdentityType; + [Write, Description("Type of conversation. Possible values are: team, channel, chat, and unknownFutureValue."), ValueMap{"team","channel","chat","unknownFutureValue"}, Values{"team","channel","chat","unknownFutureValue"}] String ConversationIdentityType; + [Write, Description("Type of user. Possible values are: aadUser, onPremiseAadUser, anonymousGuest, federatedUser, personalMicrosoftAccountUser, skypeUser, phoneUser, unknownFutureValue and emailUser."), ValueMap{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}, Values{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}] String UserIdentityType; + [Write, Description("Indicates the client IP address associated with the user performing the activity (audit log only).")] String IpAddress; + [Write, Description("The userPrincipalName attribute of the user.")] String UserPrincipalName; + [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}, Values{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}] String odataType; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("AADGroupEligibilityScheduleRequest")] +class MSFT_AADGroupEligibilityScheduleRequest : OMI_BaseResource +{ + [Write, Description("The identifier of membership or ownership eligibility relationship to the group. Required. The possible values are: owner, member, unknownFutureValue."), ValueMap{"owner","member","unknownFutureValue"}, Values{"owner","member","unknownFutureValue"}] String AccessId; + [Write, Description("The identifier of the group representing the scope of the membership and ownership eligibility through PIM for groups. Required.")] String GroupId; + [Key, Description("The Displayname of the group reppresenting the scope of the membership and ownership eligibility through PIM for groups. Required.")] String GroupDisplayName; + [Write, Description("The identifier of the principal whose membership or ownership eligibility to the group is managed through PIM for groups. Required.")] String PrincipalId; + [Write, Description("The identifier of the schedule that's created from the eligibility request. Optional.")] String TargetScheduleId; + [Write, Description("Represents the type of operation on the group membership or ownership assignment request. The possible values are: adminAssign, adminUpdate, adminRemove, selfActivate, selfDeactivate, adminExtend, adminRenew. adminAssign: For administrators to assign group membership or ownership to principals.adminRemove: For administrators to remove principals from group membership or ownership. adminUpdate: For administrators to change existing group membership or ownership assignments.adminExtend: For administrators to extend expiring assignments.adminRenew: For administrators to renew expired assignments.selfActivate: For principals to activate their assignments.selfDeactivate: For principals to deactivate their active assignments."), ValueMap{"adminAssign","adminUpdate","adminRemove","selfActivate","selfDeactivate","adminExtend","adminRenew","selfExtend","selfRenew","unknownFutureValue"}, Values{"adminAssign","adminUpdate","adminRemove","selfActivate","selfDeactivate","adminExtend","adminRenew","selfExtend","selfRenew","unknownFutureValue"}] String Action; + [Write, Description("Determines whether the call is a validation or an actual call. Only set this property if you want to check whether an activation is subject to additional rules like MFA before actually submitting the request.")] Boolean IsValidationOnly; + [Write, Description("A message provided by users and administrators when create they create the privilegedAccessGroupAssignmentScheduleRequest object.")] String Justification; + [Write, Description("The period of the group membership or ownership assignment. Recurring schedules are currently unsupported."), EmbeddedInstance("MSFT_MicrosoftGraphrequestSchedule")] String ScheduleInfo; + [Write, Description("Ticket details linked to the group membership or ownership assignment request including details of the ticket number and ticket system."), EmbeddedInstance("MSFT_MicrosoftGraphticketInfo")] String TicketInfo; + [Write, Description("The identifier of the approval of the request.")] String ApprovalId; + [Write, Description("The request completion date time.")] String CompletedDateTime; + [Write, Description("The principal that created the request."), EmbeddedInstance("MSFT_MicrosoftGraphidentitySet")] String CreatedBy; + [Write, Description("The status of the request. Not nullable. The possible values are: Canceled, Denied, Failed, Granted, PendingAdminDecision, PendingApproval, PendingProvisioning, PendingScheduleCreation, Provisioned, Revoked, and ScheduleCreated. Not nullable.")] String Status; + [Write, Description("The unique identifier for an entity. Read-only.")] String Id; + [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_AADGroupEligibilityScheduleRequest/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md new file mode 100644 index 0000000000..85788e0a2e --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md @@ -0,0 +1,6 @@ + +# AADGroupEligibilityScheduleRequest + +## Description + +Azure AD Group Eligibility Schedule Request diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json new file mode 100644 index 0000000000..d76b1e149f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json @@ -0,0 +1,29 @@ +{ + "resourceName": "AADGroupEligibilityScheduleRequest", + "description": "This resource configures an Azure AD Group Eligibility Schedule Request.", + "permissions": { + "graph": { + "delegated": { + "read": [ + { + "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" + } + ], + "update": [ + + ] + }, + "application": { + "read": [ + { + "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" + } + ], + "update": [ + + ] + } + } +} + +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 new file mode 100644 index 0000000000..8e2edc6565 --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 @@ -0,0 +1,1290 @@ +[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 "AADGroupEligibilityScheduleRequest" -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-MSCloudLoginConnectionProfile -MockWith { + } + + Mock -CommandName Reset-MSCloudLoginConnectionProfileContext -MockWith { + } + + Mock -CommandName Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + + Mock -CommandName Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + } + + Mock -CommandName New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + } + + Mock -CommandName Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -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 AADGroupEligibilityScheduleRequest should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + Action = "adminAssign" + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ + EndpointType = "default" + Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ + Id = "FakeStringValue" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + IpAddress = "FakeStringValue" + AppId = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + odataType = "#microsoft.graph.chatMessageFromIdentitySet" + Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + } -ClientOnly) + CustomData = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + IsValidationOnly = $True + Justification = "FakeStringValue" + PrincipalId = "FakeStringValue" + scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } -ClientOnly) + range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } -ClientOnly) + } -ClientOnly) + expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } -ClientOnly) + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + TargetScheduleId = "FakeStringValue" + ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } -ClientOnly) + Ensure = "Present" + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 + } + } + + Context -Name "The AADGroupEligibilityScheduleRequest exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + Action = "adminAssign" + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ + EndpointType = "default" + Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ + Id = "FakeStringValue" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + IpAddress = "FakeStringValue" + AppId = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + odataType = "#microsoft.graph.chatMessageFromIdentitySet" + Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + } -ClientOnly) + CustomData = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + IsValidationOnly = $True + Justification = "FakeStringValue" + PrincipalId = "FakeStringValue" + scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } -ClientOnly) + range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } -ClientOnly) + } -ClientOnly) + expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } -ClientOnly) + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + TargetScheduleId = "FakeStringValue" + ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } -ClientOnly) + Ensure = 'Absent' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return @{ + AdditionalProperties = @{ + isValidationOnly = $True + scheduleInfo = @{ + recurrence = @{ + pattern = @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } + range = @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } + } + expiration = @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + principalId = "FakeStringValue" + justification = "FakeStringValue" + accessId = "owner" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" + groupId = "FakeStringValue" + action = "adminAssign" + targetScheduleId = "FakeStringValue" + ticketInfo = @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } + } + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = @{ + '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" + Group = @{ + } + User = @{ + } + EndpointType = "default" + ApplicationInstance = @{ + } + Phone = @{ + } + Conversation = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = @{ + Name = "Details" + isArray = $False + } + AppId = "FakeStringValue" + Email = "FakeStringValue" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Application = @{ + } + SiteGroup = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Encrypted = @{ + } + AssertedIdentity = @{ + } + Guest = @{ + } + AzureCommunicationServicesUser = @{ + } + OnPremises = @{ + } + Device = @{ + } + SiteUser = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + } + CustomData = "FakeStringValue" + Id = "FakeStringValue" + Status = "FakeStringValue" + + } + } + } + + 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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 + } + } + + Context -Name "The AADGroupEligibilityScheduleRequest Exists and Values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + Action = "adminAssign" + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ + EndpointType = "default" + Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ + Id = "FakeStringValue" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + IpAddress = "FakeStringValue" + AppId = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + odataType = "#microsoft.graph.chatMessageFromIdentitySet" + Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + } -ClientOnly) + CustomData = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + IsValidationOnly = $True + Justification = "FakeStringValue" + PrincipalId = "FakeStringValue" + scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } -ClientOnly) + range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } -ClientOnly) + } -ClientOnly) + expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } -ClientOnly) + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + TargetScheduleId = "FakeStringValue" + ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } -ClientOnly) + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return @{ + AdditionalProperties = @{ + isValidationOnly = $True + scheduleInfo = @{ + recurrence = @{ + pattern = @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } + range = @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } + } + expiration = @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + principalId = "FakeStringValue" + justification = "FakeStringValue" + accessId = "owner" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" + groupId = "FakeStringValue" + action = "adminAssign" + targetScheduleId = "FakeStringValue" + ticketInfo = @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } + } + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = @{ + '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" + Group = @{ + } + User = @{ + } + EndpointType = "default" + ApplicationInstance = @{ + } + Phone = @{ + } + Conversation = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = @{ + Name = "Details" + isArray = $False + } + AppId = "FakeStringValue" + Email = "FakeStringValue" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Application = @{ + } + SiteGroup = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Encrypted = @{ + } + AssertedIdentity = @{ + } + Guest = @{ + } + AzureCommunicationServicesUser = @{ + } + OnPremises = @{ + } + Device = @{ + } + SiteUser = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + } + CustomData = "FakeStringValue" + Id = "FakeStringValue" + Status = "FakeStringValue" + + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The AADGroupEligibilityScheduleRequest exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + Action = "adminAssign" + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ + EndpointType = "default" + Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ + Id = "FakeStringValue" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + IpAddress = "FakeStringValue" + AppId = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + odataType = "#microsoft.graph.chatMessageFromIdentitySet" + Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ + } -ClientOnly) + SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ + Id = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ + Name = "Details" + isArray = $False + CIMType = "MSFT_MicrosoftGraphdetailsInfo" + } -ClientOnly) + Email = "FakeStringValue" + odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } -ClientOnly) + } -ClientOnly) + CustomData = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + IsValidationOnly = $True + Justification = "FakeStringValue" + PrincipalId = "FakeStringValue" + scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } -ClientOnly) + range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } -ClientOnly) + } -ClientOnly) + expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } -ClientOnly) + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + TargetScheduleId = "FakeStringValue" + ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } -ClientOnly) + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return @{ + AdditionalProperties = @{ + justification = "FakeStringValue" + scheduleInfo = @{ + recurrence = @{ + pattern = @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 7 + month = 7 + daysOfWeek = @("sunday") + type = "daily" + interval = 7 + } + range = @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 7 + type = "endDate" + } + } + expiration = @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + accessId = "owner" + principalId = "FakeStringValue" + action = "adminAssign" + groupId = "FakeStringValue" + targetScheduleId = "FakeStringValue" + ticketInfo = @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } + } + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = @{ + '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" + Group = @{ + } + User = @{ + } + EndpointType = "default" + ApplicationInstance = @{ + } + Phone = @{ + } + Conversation = @{ + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationIdentityType = "aadApplication" + Id = "FakeStringValue" + AppId = "FakeStringValue" + Email = "FakeStringValue" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + UserIdentityType = "aadUser" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + IdentityType = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + ConversationIdentityType = "team" + } + Application = @{ + } + SiteGroup = @{ + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + AzureCommunicationServicesResourceId = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + Id = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + UserIdentityType = "aadUser" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + IdentityType = "FakeStringValue" + AppId = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + ConversationIdentityType = "team" + } + Encrypted = @{ + } + AssertedIdentity = @{ + } + Guest = @{ + } + AzureCommunicationServicesUser = @{ + } + OnPremises = @{ + } + Device = @{ + } + SiteUser = @{ + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + AzureCommunicationServicesResourceId = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + Id = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + ApplicationIdentityType = "aadApplication" + ApplicationType = "FakeStringValue" + UserIdentityType = "aadUser" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + IdentityType = "FakeStringValue" + AppId = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + ConversationIdentityType = "team" + } + } + CustomData = "FakeStringValue" + Id = "FakeStringValue" + Status = "FakeStringValue" + } + } + } + + 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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return @{ + AdditionalProperties = @{ + isValidationOnly = $True + scheduleInfo = @{ + recurrence = @{ + pattern = @{ + index = "first" + firstDayOfWeek = "sunday" + dayOfMonth = 25 + month = 25 + daysOfWeek = @("sunday") + type = "daily" + interval = 25 + } + range = @{ + startDate = "2023-01-01T00:00:00.0000000" + endDate = "2023-01-01T00:00:00.0000000" + recurrenceTimeZone = "FakeStringValue" + numberOfOccurrences = 25 + type = "endDate" + } + } + expiration = @{ + endDateTime = "2023-01-01T00:00:00.0000000+01:00" + type = "notSpecified" + } + startDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + principalId = "FakeStringValue" + justification = "FakeStringValue" + accessId = "owner" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" + groupId = "FakeStringValue" + action = "adminAssign" + targetScheduleId = "FakeStringValue" + ticketInfo = @{ + ticketNumber = "FakeStringValue" + ticketSystem = "FakeStringValue" + } + } + approvalId = "FakeStringValue" + completedDateTime = "2023-01-01T00:00:00.0000000+01:00" + CreatedBy = @{ + '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" + Group = @{ + } + User = @{ + } + EndpointType = "default" + ApplicationInstance = @{ + } + Phone = @{ + } + Conversation = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + Details = @{ + Name = "Details" + isArray = $False + } + AppId = "FakeStringValue" + Email = "FakeStringValue" + ApplicationType = "FakeStringValue" + IpAddress = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AzureCommunicationServicesResourceId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Application = @{ + } + SiteGroup = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + Encrypted = @{ + } + AssertedIdentity = @{ + } + Guest = @{ + } + AzureCommunicationServicesUser = @{ + } + OnPremises = @{ + } + Device = @{ + } + SiteUser = @{ + Id = "FakeStringValue" + '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" + UserIdentityType = "aadUser" + ApplicationIdentityType = "aadApplication" + AzureCommunicationServicesResourceId = "FakeStringValue" + IpAddress = "FakeStringValue" + Email = "FakeStringValue" + Details = @{ + Name = "Details" + isArray = $False + } + ApplicationType = "FakeStringValue" + InitiatorType = "user" + DisplayName = "FakeStringValue" + TenantId = "FakeStringValue" + LoginName = "FakeStringValue" + UserPrincipalName = "FakeStringValue" + AppId = "FakeStringValue" + Hidden = $True + ConversationIdentityType = "team" + IdentityType = "FakeStringValue" + } + } + CustomData = "FakeStringValue" + Id = "FakeStringValue" + Status = "FakeStringValue" + + } + } + } + + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index 4f8feade39..a19ed4340b 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -105439,3 +105439,465 @@ function Update-MgDeviceManagementDeviceConfigurationAssignment #endregion +#region MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleRequestId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String[]] + $ExpandProperty, + + [Parameter()] + [System.String[]] + $Property, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.String] + $Search, + + [Parameter()] + [System.Int32] + $Skip, + + [Parameter()] + [System.String[]] + $Sort, + + [Parameter()] + [System.Int32] + $Top, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Int32] + $PageSize, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $All, + + [Parameter()] + [System.String] + $CountVariable + ) +} + +function New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +{ + [CmdletBinding()] + param + ( + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $Action, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.String] + $ApprovalId, + + [Parameter()] + [System.DateTime] + $CompletedDateTime, + + [Parameter()] + [PSObject] + $CreatedBy, + + [Parameter()] + [System.DateTime] + $CreatedDateTime, + + [Parameter()] + [System.String] + $CustomData, + + [Parameter()] + [PSObject] + $Group, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IsValidationOnly, + + [Parameter()] + [System.String] + $Justification, + + [Parameter()] + [PSObject] + $Principal, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [PSObject] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Status, + + [Parameter()] + [PSObject] + $TargetSchedule, + + [Parameter()] + [System.String] + $TargetScheduleId, + + [Parameter()] + [PSObject] + $TicketInfo, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +function Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleRequestId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PassThru, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +function Stop-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleRequestId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PassThru, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleRequestId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $Action, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.String] + $ApprovalId, + + [Parameter()] + [System.DateTime] + $CompletedDateTime, + + [Parameter()] + [PSObject] + $CreatedBy, + + [Parameter()] + [System.DateTime] + $CreatedDateTime, + + [Parameter()] + [System.String] + $CustomData, + + [Parameter()] + [PSObject] + $Group, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $IsValidationOnly, + + [Parameter()] + [System.String] + $Justification, + + [Parameter()] + [PSObject] + $Principal, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [PSObject] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Status, + + [Parameter()] + [PSObject] + $TargetSchedule, + + [Parameter()] + [System.String] + $TargetScheduleId, + + [Parameter()] + [PSObject] + $TicketInfo, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +#endregion + From 70e67848959f2bc20ca93e6243d817d4888b12f8 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Mon, 23 Dec 2024 10:07:00 +0100 Subject: [PATCH 02/11] wip --- ...FT_AADGroupEligibilityScheduleRequest.psm1 | 1183 --------------- ...GroupEligibilityScheduleRequest.schema.mof | 148 -- .../readme.md | 6 - .../settings.json | 29 - ...DGroupEligibilityScheduleRequest.Tests.ps1 | 1290 ----------------- 5 files changed, 2656 deletions(-) delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md delete mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json delete mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 deleted file mode 100644 index 8beb002bfd..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.psm1 +++ /dev/null @@ -1,1183 +0,0 @@ -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - #region resource generator code - [Parameter()] - [ValidateSet('owner','member','unknownFutureValue')] - [System.String] - $AccessId, - - [Parameter()] - [System.String] - $GroupId, - - [Parameter(Mandatory = $true)] - [System.String] - $GroupDisplayName, - - [Parameter()] - [System.String] - $PrincipalId, - - [Parameter()] - [System.String] - $TargetScheduleId, - - [Parameter()] - [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] - [System.String] - $Action, - - [Parameter()] - [System.Boolean] - $IsValidationOnly, - - [Parameter()] - [System.String] - $Justification, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $ScheduleInfo, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $TicketInfo, - - [Parameter()] - [System.String] - $ApprovalId, - - [Parameter()] - [System.String] - $CompletedDateTime, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $CreatedBy, - - [Parameter()] - [System.String] - $CustomData, - - [Parameter()] - [System.String] - $Id, - - #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 - ) - - Write-Verbose -Message "Getting configuration of the Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" - - 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 - if (-not $PSBoundParameters.ContainsKey('Id') -or [string]::IsNullOrEmpty($Id)) { - $Group = Get-MgGroup -Filter "displayName eq '$GroupDisplayName'" -ErrorAction SilentlyContinue - if([string]::IsNullOrEmpty($GroupId)){ - Write-Verbose -Message "Could not find an Azure AD Group with DisplayName {$GroupDisplayName}." - return $nullResult - } - elseif($Group.Length -gt 1){ - Write-Verbose -Message "Found multiple Azure AD Groups with DisplayName {$GroupDisplayName}." - return $nullResult - } - else{ - $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Filter "groupId eq '$($Group.Id)'" -ErrorAction SilentlyContinue - } - } - else{ - $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -PrivilegedAccessGroupEligibilityScheduleRequestId $Id -ErrorAction SilentlyContinue - } - #endregion - if ($null -eq $getValue) - { - Write-Verbose -Message "Could not find an Azure AD Group Eligibility Schedule Request with Id {$Id}." - return $nullResult - } - $Id = $getValue.Id - Write-Verbose -Message "An Azure AD Group Eligibility Schedule Request with Id {$Id} for Group {$($group.DisplayName)} was found" - - #region resource generator code - $complexScheduleInfo = @{} - $complexExpiration = @{} - $complexExpiration.Add('Duration', $getValue.additionalProperties.scheduleInfo.expiration.duration) - if ($null -ne $getValue.additionalProperties.scheduleInfo.expiration.endDateTime) - { - $complexExpiration.Add('EndDateTime', ([DateTimeOffset]$getValue.additionalProperties.scheduleInfo.expiration.endDateTime).ToString('')) - } - if ($null -ne $getValue.additionalProperties.scheduleInfo.expiration.type) - { - $complexExpiration.Add('Type', $getValue.additionalProperties.scheduleInfo.expiration.type.ToString()) - } - if ($complexExpiration.values.Where({$null -ne $_}).Count -eq 0) - { - $complexExpiration = $null - } - $complexScheduleInfo.Add('Expiration',$complexExpiration) - $complexRecurrence = @{} - $complexPattern = @{} - $complexPattern.Add('DayOfMonth', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.dayOfMonth) - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.daysOfWeek) - { - $complexPattern.Add('DaysOfWeek', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.daysOfWeek.ToString()) - } - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.firstDayOfWeek) - { - $complexPattern.Add('FirstDayOfWeek', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.firstDayOfWeek.ToString()) - } - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.index) - { - $complexPattern.Add('Index', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.index.ToString()) - } - $complexPattern.Add('Interval', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.interval) - $complexPattern.Add('Month', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.month) - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.pattern.type) - { - $complexPattern.Add('Type', $getValue.additionalProperties.scheduleInfo.recurrence.pattern.type.ToString()) - } - if ($complexPattern.values.Where({$null -ne $_}).Count -eq 0) - { - $complexPattern = $null - } - $complexRecurrence.Add('Pattern',$complexPattern) - $complexRange = @{} - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.endDate) - { - $complexRange.Add('EndDate', ([DateTime]$getValue.additionalProperties.scheduleInfo.recurrence.range.endDate).ToString('')) - } - $complexRange.Add('NumberOfOccurrences', $getValue.additionalProperties.scheduleInfo.recurrence.range.numberOfOccurrences) - $complexRange.Add('RecurrenceTimeZone', $getValue.additionalProperties.scheduleInfo.recurrence.range.recurrenceTimeZone) - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.startDate) - { - $complexRange.Add('StartDate', ([DateTime]$getValue.additionalProperties.scheduleInfo.recurrence.range.startDate).ToString('')) - } - if ($null -ne $getValue.additionalProperties.scheduleInfo.recurrence.range.type) - { - $complexRange.Add('Type', $getValue.additionalProperties.scheduleInfo.recurrence.range.type.ToString()) - } - if ($complexRange.values.Where({$null -ne $_}).Count -eq 0) - { - $complexRange = $null - } - $complexRecurrence.Add('Range',$complexRange) - if ($complexRecurrence.values.Where({$null -ne $_}).Count -eq 0) - { - $complexRecurrence = $null - } - $complexScheduleInfo.Add('Recurrence',$complexRecurrence) - if ($null -ne $getValue.AdditionalProperties.scheduleInfo.startDateTime) - { - $complexScheduleInfo.Add('StartDateTime', ([DateTimeOffset]$getValue.AdditionalProperties.scheduleInfo.startDateTime).ToString('o')) - } - if ($complexScheduleInfo.values.Where({$null -ne $_}).Count -eq 0) - { - $complexScheduleInfo = $null - } - - $complexTicketInfo = @{} - $complexTicketInfo.Add('TicketNumber', $getValue.AdditionalProperties.ticketInfo.ticketNumber) - $complexTicketInfo.Add('TicketSystem', $getValue.AdditionalProperties.ticketInfo.ticketSystem) - if ($complexTicketInfo.values.Where({$null -ne $_}).Count -eq 0) - { - $complexTicketInfo = $null - } - - $complexCreatedBy = @{} - $complexApplication = @{} - $complexApplication.Add('id', $getValue.createdBy.application.id) - $complexApplication.Add('displayName', $getValue.createdBy.application.displayName) - if ($complexApplication.values.Where({$null -ne $_}).Count -eq 0) - { - $complexApplication = $null - } - $complexCreatedBy.Add('Application',$complexApplication) - $complexDevice = @{} - $complexDevice.Add('id', $getValue.createdBy.device.id) - $complexDevice.Add('displayName', $getValue.createdBy.device.displayName) - if ($complexDevice.values.Where({$null -ne $_}).Count -eq 0) - { - $complexDevice = $null - } - $complexCreatedBy.Add('Device',$complexDevice) - $complexUser = @{} - $complexUser.Add('id', $getValue.createdBy.user.id) - $complexUser.Add('displayName', $getValue.createdBy.user.displayName) - if ($complexUser.values.Where({$null -ne $_}).Count -eq 0) - { - $complexUser = $null - } - $complexCreatedBy.Add('User',$complexUser) - $complexConversation = @{} - if ($null -ne $getValue.createdBy.conversation.conversationIdentityType) - { - $complexConversation.Add('ConversationIdentityType', $getValue.createdBy.conversation.conversationIdentityType.ToString()) - } - $complexConversation.Add('DisplayName', $getValue.createdBy.conversation.displayName) - $complexConversation.Add('Id', $getValue.createdBy.conversation.id) - $complexConversation.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.conversation.azureCommunicationServicesResourceId) - $complexConversation.Add('ApplicationType', $getValue.createdBy.conversation.applicationType) - $complexConversation.Add('Hidden', $getValue.createdBy.conversation.hidden) - $complexConversation.Add('TenantId', $getValue.createdBy.conversation.tenantId) - $complexConversation.Add('Email', $getValue.createdBy.conversation.email) - if ($null -ne $getValue.createdBy.conversation.initiatorType) - { - $complexConversation.Add('InitiatorType', $getValue.createdBy.conversation.initiatorType.ToString()) - } - $complexDetails = @{} - if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) - { - $complexDetails = $null - } - $complexConversation.Add('Details',$complexDetails) - $complexConversation.Add('IdentityType', $getValue.createdBy.conversation.identityType) - $complexConversation.Add('AppId', $getValue.createdBy.conversation.appId) - $complexConversation.Add('LoginName', $getValue.createdBy.conversation.loginName) - if ($null -ne $getValue.createdBy.conversation.applicationIdentityType) - { - $complexConversation.Add('ApplicationIdentityType', $getValue.createdBy.conversation.applicationIdentityType.ToString()) - } - if ($null -ne $getValue.createdBy.conversation.userIdentityType) - { - $complexConversation.Add('UserIdentityType', $getValue.createdBy.conversation.userIdentityType.ToString()) - } - $complexConversation.Add('IpAddress', $getValue.createdBy.conversation.ipAddress) - $complexConversation.Add('UserPrincipalName', $getValue.createdBy.conversation.userPrincipalName) - if ($null -ne $getValue.createdBy.conversation.'@odata.type') - { - $complexConversation.Add('odataType', $getValue.createdBy.conversation.'@odata.type'.ToString()) - } - if ($complexConversation.values.Where({$null -ne $_}).Count -eq 0) - { - $complexConversation = $null - } - $complexCreatedBy.Add('Conversation',$complexConversation) - $complexApplicationInstance = @{} - $complexApplicationInstance.Add('Type', $getValue.createdBy.applicationInstance.type) - if ($complexApplicationInstance.values.Where({$null -ne $_}).Count -eq 0) - { - $complexApplicationInstance = $null - } - $complexCreatedBy.Add('ApplicationInstance',$complexApplicationInstance) - $complexAssertedIdentity = @{} - $complexAssertedIdentity.Add('Type', $getValue.createdBy.assertedIdentity.type) - if ($complexAssertedIdentity.values.Where({$null -ne $_}).Count -eq 0) - { - $complexAssertedIdentity = $null - } - $complexCreatedBy.Add('AssertedIdentity',$complexAssertedIdentity) - $complexAzureCommunicationServicesUser = @{} - $complexAzureCommunicationServicesUser.Add('Type', $getValue.createdBy.azureCommunicationServicesUser.type) - if ($complexAzureCommunicationServicesUser.values.Where({$null -ne $_}).Count -eq 0) - { - $complexAzureCommunicationServicesUser = $null - } - $complexCreatedBy.Add('AzureCommunicationServicesUser',$complexAzureCommunicationServicesUser) - $complexEncrypted = @{} - $complexEncrypted.Add('Type', $getValue.createdBy.encrypted.type) - if ($complexEncrypted.values.Where({$null -ne $_}).Count -eq 0) - { - $complexEncrypted = $null - } - $complexCreatedBy.Add('Encrypted',$complexEncrypted) - if ($null -ne $getValue.CreatedBy.endpointType) - { - $complexCreatedBy.Add('EndpointType', $getValue.CreatedBy.endpointType.ToString()) - } - $complexGuest = @{} - $complexGuest.Add('Type', $getValue.createdBy.guest.type) - if ($complexGuest.values.Where({$null -ne $_}).Count -eq 0) - { - $complexGuest = $null - } - $complexCreatedBy.Add('Guest',$complexGuest) - $complexOnPremises = @{} - $complexOnPremises.Add('Type', $getValue.createdBy.onPremises.type) - if ($complexOnPremises.values.Where({$null -ne $_}).Count -eq 0) - { - $complexOnPremises = $null - } - $complexCreatedBy.Add('OnPremises',$complexOnPremises) - $complexPhone = @{} - $complexPhone.Add('Type', $getValue.createdBy.phone.type) - if ($complexPhone.values.Where({$null -ne $_}).Count -eq 0) - { - $complexPhone = $null - } - $complexCreatedBy.Add('Phone',$complexPhone) - $complexGroup = @{} - $complexGroup.Add('Type', $getValue.createdBy.group.type) - if ($complexGroup.values.Where({$null -ne $_}).Count -eq 0) - { - $complexGroup = $null - } - $complexCreatedBy.Add('Group',$complexGroup) - $complexSiteGroup = @{} - $complexSiteGroup.Add('LoginName', $getValue.createdBy.siteGroup.loginName) - $complexSiteGroup.Add('DisplayName', $getValue.createdBy.siteGroup.displayName) - $complexSiteGroup.Add('Id', $getValue.createdBy.siteGroup.id) - $complexSiteGroup.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.siteGroup.azureCommunicationServicesResourceId) - $complexSiteGroup.Add('ApplicationType', $getValue.createdBy.siteGroup.applicationType) - $complexSiteGroup.Add('Hidden', $getValue.createdBy.siteGroup.hidden) - $complexSiteGroup.Add('TenantId', $getValue.createdBy.siteGroup.tenantId) - $complexSiteGroup.Add('Email', $getValue.createdBy.siteGroup.email) - if ($null -ne $getValue.createdBy.siteGroup.initiatorType) - { - $complexSiteGroup.Add('InitiatorType', $getValue.createdBy.siteGroup.initiatorType.ToString()) - } - $complexDetails = @{} - if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) - { - $complexDetails = $null - } - $complexSiteGroup.Add('Details',$complexDetails) - $complexSiteGroup.Add('IdentityType', $getValue.createdBy.siteGroup.identityType) - $complexSiteGroup.Add('AppId', $getValue.createdBy.siteGroup.appId) - if ($null -ne $getValue.createdBy.siteGroup.applicationIdentityType) - { - $complexSiteGroup.Add('ApplicationIdentityType', $getValue.createdBy.siteGroup.applicationIdentityType.ToString()) - } - if ($null -ne $getValue.createdBy.siteGroup.conversationIdentityType) - { - $complexSiteGroup.Add('ConversationIdentityType', $getValue.createdBy.siteGroup.conversationIdentityType.ToString()) - } - if ($null -ne $getValue.createdBy.siteGroup.userIdentityType) - { - $complexSiteGroup.Add('UserIdentityType', $getValue.createdBy.siteGroup.userIdentityType.ToString()) - } - $complexSiteGroup.Add('IpAddress', $getValue.createdBy.siteGroup.ipAddress) - $complexSiteGroup.Add('UserPrincipalName', $getValue.createdBy.siteGroup.userPrincipalName) - if ($null -ne $getValue.createdBy.siteGroup.'@odata.type') - { - $complexSiteGroup.Add('odataType', $getValue.createdBy.siteGroup.'@odata.type'.ToString()) - } - if ($complexSiteGroup.values.Where({$null -ne $_}).Count -eq 0) - { - $complexSiteGroup = $null - } - $complexCreatedBy.Add('SiteGroup',$complexSiteGroup) - $complexSiteUser = @{} - $complexSiteUser.Add('LoginName', $getValue.createdBy.siteUser.loginName) - $complexSiteUser.Add('DisplayName', $getValue.createdBy.siteUser.displayName) - $complexSiteUser.Add('Id', $getValue.createdBy.siteUser.id) - $complexSiteUser.Add('AzureCommunicationServicesResourceId', $getValue.createdBy.siteUser.azureCommunicationServicesResourceId) - $complexSiteUser.Add('ApplicationType', $getValue.createdBy.siteUser.applicationType) - $complexSiteUser.Add('Hidden', $getValue.createdBy.siteUser.hidden) - $complexSiteUser.Add('TenantId', $getValue.createdBy.siteUser.tenantId) - $complexSiteUser.Add('Email', $getValue.createdBy.siteUser.email) - if ($null -ne $getValue.createdBy.siteUser.initiatorType) - { - $complexSiteUser.Add('InitiatorType', $getValue.createdBy.siteUser.initiatorType.ToString()) - } - $complexDetails = @{} - if ($complexDetails.values.Where({$null -ne $_}).Count -eq 0) - { - $complexDetails = $null - } - $complexSiteUser.Add('Details',$complexDetails) - $complexSiteUser.Add('IdentityType', $getValue.createdBy.siteUser.identityType) - $complexSiteUser.Add('AppId', $getValue.createdBy.siteUser.appId) - if ($null -ne $getValue.createdBy.siteUser.applicationIdentityType) - { - $complexSiteUser.Add('ApplicationIdentityType', $getValue.createdBy.siteUser.applicationIdentityType.ToString()) - } - if ($null -ne $getValue.createdBy.siteUser.conversationIdentityType) - { - $complexSiteUser.Add('ConversationIdentityType', $getValue.createdBy.siteUser.conversationIdentityType.ToString()) - } - if ($null -ne $getValue.createdBy.siteUser.userIdentityType) - { - $complexSiteUser.Add('UserIdentityType', $getValue.createdBy.siteUser.userIdentityType.ToString()) - } - $complexSiteUser.Add('IpAddress', $getValue.createdBy.siteUser.ipAddress) - $complexSiteUser.Add('UserPrincipalName', $getValue.createdBy.siteUser.userPrincipalName) - if ($null -ne $getValue.createdBy.siteUser.'@odata.type') - { - $complexSiteUser.Add('odataType', $getValue.createdBy.siteUser.'@odata.type'.ToString()) - } - if ($complexSiteUser.values.Where({$null -ne $_}).Count -eq 0) - { - $complexSiteUser = $null - } - $complexCreatedBy.Add('SiteUser',$complexSiteUser) - if ($null -ne $getValue.CreatedBy.'@odata.type') - { - $complexCreatedBy.Add('odataType', $getValue.CreatedBy.'@odata.type'.ToString()) - } - if ($complexCreatedBy.values.Where({$null -ne $_}).Count -eq 0) - { - $complexCreatedBy = $null - } - #endregion - - #region resource generator code - $enumAccessId = $null - if ($null -ne $getValue.AdditionalProperties.accessId) - { - $enumAccessId = $getValue.AdditionalProperties.accessId.ToString() - } - - $enumAction = $null - if ($null -ne $getValue.AdditionalProperties.action) - { - $enumAction = $getValue.AdditionalProperties.action.ToString() - } - #endregion - - #region resource generator code - $dateCompletedDateTime = $null - if ($null -ne $getValue.CompletedDateTime) - { - $dateCompletedDateTime = ([DateTimeOffset]$getValue.CompletedDateTime).ToString('o') - } - #endregion - - $results = @{ - #region resource generator code - AccessId = $enumAccessId - GroupId = $getValue.groupId - GroupDisplayName = $group.DisplayName - PrincipalId = $getValue.principalId - TargetScheduleId = $getValue.targetScheduleId - Action = $enumAction - IsValidationOnly = $getValue.isValidationOnly - Justification = $getValue.justification - ScheduleInfo = $complexScheduleInfo - TicketInfo = $complexTicketInfo - ApprovalId = $getValue.ApprovalId - CompletedDateTime = $dateCompletedDateTime - CreatedBy = $complexCreatedBy - CustomData = $getValue.CustomData - Id = $getValue.Id - Ensure = 'Present' - Credential = $Credential - ApplicationId = $ApplicationId - TenantId = $TenantId - ApplicationSecret = $ApplicationSecret - CertificateThumbprint = $CertificateThumbprint - ManagedIdentity = $ManagedIdentity.IsPresent - #endregion - } - - 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()] - [ValidateSet('owner','member','unknownFutureValue')] - [System.String] - $AccessId, - - [Parameter()] - [System.String] - $GroupId, - - [Parameter(Mandatory = $true)] - [System.String] - $GroupDisplayName, - - [Parameter()] - [System.String] - $PrincipalId, - - [Parameter()] - [System.String] - $TargetScheduleId, - - [Parameter()] - [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] - [System.String] - $Action, - - [Parameter()] - [System.Boolean] - $IsValidationOnly, - - [Parameter()] - [System.String] - $Justification, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $ScheduleInfo, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $TicketInfo, - - [Parameter()] - [System.String] - $ApprovalId, - - [Parameter()] - [System.String] - $CompletedDateTime, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $CreatedBy, - - [Parameter()] - [System.String] - $CustomData, - - [Parameter()] - [System.String] - $Id, - - #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 - ) - - Write-Verbose -Message "Setting configuration of the Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" - - #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 - - - if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') - { - Write-Verbose -Message "Creating an Azure AD Group Eligibility Schedule Request with DisplayName {$DisplayName}" - - $createParameters = ([Hashtable]$BoundParameters).Clone() - $createParameters = Rename-M365DSCCimInstanceParameter -Properties $createParameters - $createParameters.Remove('Id') | Out-Null - - $keys = (([Hashtable]$createParameters).Clone()).Keys - foreach ($key in $keys) - { - if ($null -ne $createParameters.$key -and $createParameters.$key.GetType().Name -like '*CimInstance*') - { - $createParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $createParameters.$key - } - } - #region resource generator code - $createParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest") - $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $createParameters - #endregion - } - elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') - { - Write-Verbose -Message "Updating the Azure AD Group Eligibility Schedule Request with Id {$($currentInstance.Id)}" - - $updateParameters = ([Hashtable]$BoundParameters).Clone() - $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters - - $updateParameters.Remove('Id') | Out-Null - - $keys = (([Hashtable]$updateParameters).Clone()).Keys - foreach ($key in $keys) - { - if ($null -ne $pdateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') - { - $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.PrivilegedAccessGroupEligibilityScheduleRequestId - } - } - - #region resource generator code - $UpdateParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest") - Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ` - -PrivilegedAccessGroupEligibilityScheduleRequestId $currentInstance.Id ` - -BodyParameter $UpdateParameters - #endregion - } - elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') - { - Write-Verbose -Message "Removing the Azure AD Group Eligibility Schedule Request with Id {$($currentInstance.Id)}" - #region resource generator code - Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -PrivilegedAccessGroupEligibilityScheduleRequestId $currentInstance.Id - #endregion - } -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - #region resource generator code - [Parameter()] - [ValidateSet('owner','member','unknownFutureValue')] - [System.String] - $AccessId, - - [Parameter()] - [System.String] - $GroupId, - - [Parameter(Mandatory = $true)] - [System.String] - $GroupDisplayName, - - [Parameter()] - [System.String] - $PrincipalId, - - [Parameter()] - [System.String] - $TargetScheduleId, - - [Parameter()] - [ValidateSet('adminAssign','adminUpdate','adminRemove','selfActivate','selfDeactivate','adminExtend','adminRenew','selfExtend','selfRenew','unknownFutureValue')] - [System.String] - $Action, - - [Parameter()] - [System.Boolean] - $IsValidationOnly, - - [Parameter()] - [System.String] - $Justification, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $ScheduleInfo, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $TicketInfo, - - [Parameter()] - [System.String] - $ApprovalId, - - [Parameter()] - [System.String] - $CompletedDateTime, - - [Parameter()] - [Microsoft.Management.Infrastructure.CimInstance] - $CreatedBy, - - [Parameter()] - [System.String] - $CustomData, - - [Parameter()] - [System.String] - $Id, - - #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 Azure AD Group Eligibility Schedule Request with Id {$Id} and DisplayName {$DisplayName}" - - $CurrentValues = Get-TargetResource @PSBoundParameters - $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() - - 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 $ValuesToCheck)" - - 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 - $groups = Get-MgGroup -Filter "MailEnabled eq false and NOT(groupTypes/any(x:x eq 'DynamicMembership'))" -Property "displayname,Id" -CountVariable CountVar -ConsistencyLevel eventual -ErrorAction Stop - foreach ($group in $groups) - { - $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ` - -Filter "groupId eq '$($group.Id)'" ` - -All ` - -ErrorAction Stop - if($null -eq $getValue) - { - continue - } - #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 + " / " + $group.DisplayName - Write-Host " |---[$i/$($getValue.Count)] $displayedKey" -NoNewline - $params = @{ - Id = $config.Id - GroupDisplayName = $group.DisplayName - 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 ($null -ne $Results.ScheduleInfo) - { - $complexMapping = @( - @{ - Name = 'ScheduleInfo' - CimInstanceName = 'MicrosoftGraphRequestSchedule' - IsRequired = $False - } - @{ - Name = 'Expiration' - CimInstanceName = 'MicrosoftGraphExpirationPattern' - IsRequired = $False - } - @{ - Name = 'Recurrence' - CimInstanceName = 'MicrosoftGraphPatternedRecurrence1' - IsRequired = $False - } - @{ - Name = 'Pattern' - CimInstanceName = 'MicrosoftGraphRecurrencePattern1' - IsRequired = $False - } - @{ - Name = 'Range' - CimInstanceName = 'MicrosoftGraphRecurrenceRange1' - IsRequired = $False - } - ) - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` - -ComplexObject $Results.ScheduleInfo ` - -CIMInstanceName 'MicrosoftGraphrequestSchedule' ` - -ComplexTypeMapping $complexMapping - - if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) - { - $Results.ScheduleInfo = $complexTypeStringResult - } - else - { - $Results.Remove('ScheduleInfo') | Out-Null - } - } - if ($null -ne $Results.TicketInfo) - { - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` - -ComplexObject $Results.TicketInfo ` - -CIMInstanceName 'MicrosoftGraphticketInfo' - if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) - { - $Results.TicketInfo = $complexTypeStringResult - } - else - { - $Results.Remove('TicketInfo') | Out-Null - } - } - if ($null -ne $Results.CreatedBy) - { - $complexMapping = @( - @{ - Name = 'CreatedBy' - CimInstanceName = 'MicrosoftGraphIdentitySet' - IsRequired = $False - } - @{ - Name = 'Application' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Device' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'User' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Conversation' - CimInstanceName = 'MicrosoftGraphTeamworkConversationIdentity' - IsRequired = $False - } - @{ - Name = 'Details' - CimInstanceName = 'MicrosoftGraphDetailsInfo' - IsRequired = $False - } - @{ - Name = 'ApplicationInstance' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'AssertedIdentity' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'AzureCommunicationServicesUser' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Encrypted' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Guest' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'OnPremises' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Phone' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'Group' - CimInstanceName = 'MicrosoftGraphIdentity' - IsRequired = $False - } - @{ - Name = 'SiteGroup' - CimInstanceName = 'MicrosoftGraphSharePointIdentity' - IsRequired = $False - } - @{ - Name = 'Details' - CimInstanceName = 'MicrosoftGraphDetailsInfo' - IsRequired = $False - } - @{ - Name = 'SiteUser' - CimInstanceName = 'MicrosoftGraphSharePointIdentity' - IsRequired = $False - } - @{ - Name = 'Details' - CimInstanceName = 'MicrosoftGraphDetailsInfo' - IsRequired = $False - } - ) - $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` - -ComplexObject $Results.CreatedBy ` - -CIMInstanceName 'MicrosoftGraphidentitySet' ` - -ComplexTypeMapping $complexMapping - - if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) - { - $Results.CreatedBy = $complexTypeStringResult - } - else - { - $Results.Remove('CreatedBy') | Out-Null - } - } - - $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` - -ConnectionMode $ConnectionMode ` - -ModulePath $PSScriptRoot ` - -Results $Results ` - -Credential $Credential - if ($Results.ScheduleInfo) - { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "ScheduleInfo" -IsCIMArray:$False - } - if ($Results.TicketInfo) - { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "TicketInfo" -IsCIMArray:$False - } - if ($Results.CreatedBy) - { - $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "CreatedBy" -IsCIMArray:$False - } - - $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_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof deleted file mode 100644 index e3f303d040..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/MSFT_AADGroupEligibilityScheduleRequest.schema.mof +++ /dev/null @@ -1,148 +0,0 @@ -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphRequestSchedule -{ - [Write, Description("When the eligible or active assignment expires."), EmbeddedInstance("MSFT_MicrosoftGraphExpirationPattern")] String Expiration; - [Write, Description("The frequency of the eligible or active assignment. This property is currently unsupported in PIM."), EmbeddedInstance("MSFT_MicrosoftGraphPatternedRecurrence1")] String Recurrence; - [Write, Description("When the eligible or active assignment becomes active.")] String StartDateTime; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphExpirationPattern -{ - [Write, Description("The requestor's desired duration of access represented in ISO 8601 format for durations. For example, PT3H refers to three hours. If specified in a request, endDateTime should not be present and the type property should be set to afterDuration.")] String Duration; - [Write, Description("Timestamp of date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z.")] String EndDateTime; - [Write, Description("The requestor's desired expiration pattern type. The possible values are: notSpecified, noExpiration, afterDateTime, afterDuration."), ValueMap{"notSpecified","noExpiration","afterDateTime","afterDuration"}, Values{"notSpecified","noExpiration","afterDateTime","afterDuration"}] String Type; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphPatternedRecurrence1 -{ - [Write, Description("The frequency of an event. For access reviews: Do not specify this property for a one-time access review. Only interval, dayOfMonth, and type (weekly, absoluteMonthly) properties of recurrencePattern are supported."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrencePattern1")] String Pattern; - [Write, Description("The duration of an event."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrenceRange1")] String Range; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphRecurrencePattern1 -{ - [Write, Description("The day of the month on which the event occurs. Required if type is absoluteMonthly or absoluteYearly.")] UInt32 DayOfMonth; - [Write, Description("A collection of the days of the week on which the event occurs. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. If type is relativeMonthly or relativeYearly, and daysOfWeek specifies more than one day, the event falls on the first day that satisfies the pattern. Required if type is weekly, relativeMonthly, or relativeYearly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String DaysOfWeek[]; - [Write, Description("The first day of the week. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. Default is sunday. Required if type is weekly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String FirstDayOfWeek; - [Write, Description("Specifies on which instance of the allowed days specified in daysOfWeek the event occurs, counted from the first instance in the month. The possible values are: first, second, third, fourth, last. Default is first. Optional and used if type is relativeMonthly or relativeYearly."), ValueMap{"first","second","third","fourth","last"}, Values{"first","second","third","fourth","last"}] String Index; - [Write, Description("The number of units between occurrences, where units can be in days, weeks, months, or years, depending on the type. Required.")] UInt32 Interval; - [Write, Description("The month in which the event occurs. This is a number from 1 to 12.")] UInt32 Month; - [Write, Description("The recurrence pattern type: daily, weekly, absoluteMonthly, relativeMonthly, absoluteYearly, relativeYearly. Required. For more information, see values of type property."), ValueMap{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}, Values{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}] String Type; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphRecurrenceRange1 -{ - [Write, Description("The date to stop applying the recurrence pattern. Depending on the recurrence pattern of the event, the last occurrence of the meeting may not be this date. Required if type is endDate.")] String EndDate; - [Write, Description("The number of times to repeat the event. Required and must be positive if type is numbered.")] UInt32 NumberOfOccurrences; - [Write, Description("Time zone for the startDate and endDate properties. Optional. If not specified, the time zone of the event is used.")] String RecurrenceTimeZone; - [Write, Description("The date to start applying the recurrence pattern. The first occurrence of the meeting may be this date or later, depending on the recurrence pattern of the event. Must be the same value as the start property of the recurring event. Required.")] String StartDate; - [Write, Description("The recurrence range. The possible values are: endDate, noEnd, numbered. Required."), ValueMap{"endDate","noEnd","numbered"}, Values{"endDate","noEnd","numbered"}] String Type; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphTicketInfo -{ - [Write, Description("The ticket number.")] String TicketNumber; - [Write, Description("The description of the ticket system.")] String TicketSystem; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphIdentitySet -{ - [Write, Description("Optional. The application associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Application; - [Write, Description("Optional. The device associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Device; - [Write, Description("Optional. The user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String User; - [Write, Description("If present, represents a conversation (for example, team or channel) mentioned in a message."), EmbeddedInstance("MSFT_MicrosoftGraphTeamworkConversationIdentity")] String Conversation; - [Write, Description("The application instance associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String ApplicationInstance; - [Write, Description("An identity the participant would like to present itself as to the other participants in the call."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String AssertedIdentity; - [Write, Description("The Azure Communication Services user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String AzureCommunicationServicesUser; - [Write, Description("The encrypted user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Encrypted; - [Write, Description("Type of endpoint that the participant uses. Possible values are: default, voicemail, skypeForBusiness, skypeForBusinessVoipPhone, unknownFutureValue."), ValueMap{"default","voicemail","skypeForBusiness","skypeForBusinessVoipPhone","unknownFutureValue"}, Values{"default","voicemail","skypeForBusiness","skypeForBusinessVoipPhone","unknownFutureValue"}] String EndpointType; - [Write, Description("The guest user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Guest; - [Write, Description("The Skype for Business on-premises user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String OnPremises; - [Write, Description("The phone user associated with this action."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Phone; - [Write, Description("The group associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphIdentity")] String Group; - [Write, Description("The SharePoint group associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphSharePointIdentity")] String SiteGroup; - [Write, Description("The SharePoint user associated with this action. Optional."), EmbeddedInstance("MSFT_MicrosoftGraphSharePointIdentity")] String SiteUser; - [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.chatMessageFromIdentitySet","#microsoft.graph.chatMessageMentionedIdentitySet","#microsoft.graph.chatMessageReactionIdentitySet","#microsoft.graph.communicationsIdentitySet","#microsoft.graph.sharePointIdentitySet"}, Values{"#microsoft.graph.chatMessageFromIdentitySet","#microsoft.graph.chatMessageMentionedIdentitySet","#microsoft.graph.chatMessageReactionIdentitySet","#microsoft.graph.communicationsIdentitySet","#microsoft.graph.sharePointIdentitySet"}] String odataType; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphIdentity -{ - [Write, Description("Id of the User group or device")] String Id; - [Write, Description("Displayname of the user group or device")] String displayName; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphTeamworkConversationIdentity -{ - [Write, Description("Type of conversation. Possible values are: team, channel, chat, and unknownFutureValue."), ValueMap{"team","channel","chat","unknownFutureValue"}, Values{"team","channel","chat","unknownFutureValue"}] String ConversationIdentityType; - [Write, Description("The display name of the identity.For drive items, the display name might not always be available or up to date. For example, if a user changes their display name the API might show the new value in a future response, but the items associated with the user don't show up as changed when using delta.")] String DisplayName; - [Write, Description("Unique identifier for the identity or actor. For example, in the access reviews decisions API, this property might record the id of the principal, that is, the group, user, or application that's subject to review.")] String Id; - [Write, Description("The Azure Communication Services resource ID associated with the user.")] String AzureCommunicationServicesResourceId; - [Write, Description("First-party Microsoft application that presents this identity.")] String ApplicationType; - [Write, Description("True if the participant shouldn't be shown in other participants' rosters.")] Boolean Hidden; - [Write, Description("The tenant ID of the application.")] String TenantId; - [Write, Description("Email address of the user.")] String Email; - [Write, Description("Type of initiator. Possible values are: user, application, system, unknownFutureValue."), ValueMap{"user","application","system","unknownFutureValue"}, Values{"user","application","system","unknownFutureValue"}] String InitiatorType; - [Write, Description("Details of the identity."), EmbeddedInstance("MSFT_MicrosoftGraphDetailsInfo")] String Details; - [Write, Description("Type of identity that has been provisioned, such as 'user' or 'group'. Supports $filter (eq, contains).")] String IdentityType; - [Write, Description("The application identifier of the service principal.")] String AppId; - [Write, Description("The sign in name of the SharePoint identity.")] String LoginName; - [Write, Description("Type of application that is referenced. Possible values are: aadApplication, bot, tenantBot, office365Connector, outgoingWebhook, and unknownFutureValue."), ValueMap{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}, Values{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}] String ApplicationIdentityType; - [Write, Description("Type of user. Possible values are: aadUser, onPremiseAadUser, anonymousGuest, federatedUser, personalMicrosoftAccountUser, skypeUser, phoneUser, unknownFutureValue and emailUser."), ValueMap{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}, Values{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}] String UserIdentityType; - [Write, Description("Indicates the client IP address associated with the user performing the activity (audit log only).")] String IpAddress; - [Write, Description("The userPrincipalName attribute of the user.")] String UserPrincipalName; - [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}, Values{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}] String odataType; -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphDetailsInfo -{ -}; -[ClassVersion("1.0.0")] -class MSFT_MicrosoftGraphSharePointIdentity -{ - [Write, Description("The sign in name of the SharePoint identity.")] String LoginName; - [Write, Description("The display name of the identity.For drive items, the display name might not always be available or up to date. For example, if a user changes their display name the API might show the new value in a future response, but the items associated with the user don't show up as changed when using delta.")] String DisplayName; - [Write, Description("Unique identifier for the identity or actor. For example, in the access reviews decisions API, this property might record the id of the principal, that is, the group, user, or application that's subject to review.")] String Id; - [Write, Description("The Azure Communication Services resource ID associated with the user.")] String AzureCommunicationServicesResourceId; - [Write, Description("First-party Microsoft application that presents this identity.")] String ApplicationType; - [Write, Description("True if the participant shouldn't be shown in other participants' rosters.")] Boolean Hidden; - [Write, Description("The tenant ID of the application.")] String TenantId; - [Write, Description("Email address of the user.")] String Email; - [Write, Description("Type of initiator. Possible values are: user, application, system, unknownFutureValue."), ValueMap{"user","application","system","unknownFutureValue"}, Values{"user","application","system","unknownFutureValue"}] String InitiatorType; - [Write, Description("Details of the identity."), EmbeddedInstance("MSFT_MicrosoftGraphDetailsInfo")] String Details; - [Write, Description("Type of identity that has been provisioned, such as 'user' or 'group'. Supports $filter (eq, contains).")] String IdentityType; - [Write, Description("The application identifier of the service principal.")] String AppId; - [Write, Description("Type of application that is referenced. Possible values are: aadApplication, bot, tenantBot, office365Connector, outgoingWebhook, and unknownFutureValue."), ValueMap{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}, Values{"aadApplication","bot","tenantBot","office365Connector","outgoingWebhook","unknownFutureValue"}] String ApplicationIdentityType; - [Write, Description("Type of conversation. Possible values are: team, channel, chat, and unknownFutureValue."), ValueMap{"team","channel","chat","unknownFutureValue"}, Values{"team","channel","chat","unknownFutureValue"}] String ConversationIdentityType; - [Write, Description("Type of user. Possible values are: aadUser, onPremiseAadUser, anonymousGuest, federatedUser, personalMicrosoftAccountUser, skypeUser, phoneUser, unknownFutureValue and emailUser."), ValueMap{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}, Values{"aadUser","onPremiseAadUser","anonymousGuest","federatedUser","personalMicrosoftAccountUser","skypeUser","phoneUser","unknownFutureValue","emailUser"}] String UserIdentityType; - [Write, Description("Indicates the client IP address associated with the user performing the activity (audit log only).")] String IpAddress; - [Write, Description("The userPrincipalName attribute of the user.")] String UserPrincipalName; - [Write, Description("The type of the entity."), ValueMap{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}, Values{"#microsoft.graph.azureCommunicationServicesUserIdentity","#microsoft.graph.communicationsApplicationIdentity","#microsoft.graph.communicationsApplicationInstanceIdentity","#microsoft.graph.communicationsEncryptedIdentity","#microsoft.graph.communicationsGuestIdentity","#microsoft.graph.communicationsPhoneIdentity","#microsoft.graph.communicationsUserIdentity","#microsoft.graph.emailIdentity","#microsoft.graph.initiator","#microsoft.graph.provisionedIdentity","#microsoft.graph.provisioningServicePrincipal","#microsoft.graph.provisioningSystem","#microsoft.graph.servicePrincipalIdentity","#microsoft.graph.sharePointIdentity","#microsoft.graph.teamworkApplicationIdentity","#microsoft.graph.teamworkConversationIdentity","#microsoft.graph.teamworkTagIdentity","#microsoft.graph.teamworkUserIdentity","#microsoft.graph.userIdentity"}] String odataType; -}; - -[ClassVersion("1.0.0.0"), FriendlyName("AADGroupEligibilityScheduleRequest")] -class MSFT_AADGroupEligibilityScheduleRequest : OMI_BaseResource -{ - [Write, Description("The identifier of membership or ownership eligibility relationship to the group. Required. The possible values are: owner, member, unknownFutureValue."), ValueMap{"owner","member","unknownFutureValue"}, Values{"owner","member","unknownFutureValue"}] String AccessId; - [Write, Description("The identifier of the group representing the scope of the membership and ownership eligibility through PIM for groups. Required.")] String GroupId; - [Key, Description("The Displayname of the group reppresenting the scope of the membership and ownership eligibility through PIM for groups. Required.")] String GroupDisplayName; - [Write, Description("The identifier of the principal whose membership or ownership eligibility to the group is managed through PIM for groups. Required.")] String PrincipalId; - [Write, Description("The identifier of the schedule that's created from the eligibility request. Optional.")] String TargetScheduleId; - [Write, Description("Represents the type of operation on the group membership or ownership assignment request. The possible values are: adminAssign, adminUpdate, adminRemove, selfActivate, selfDeactivate, adminExtend, adminRenew. adminAssign: For administrators to assign group membership or ownership to principals.adminRemove: For administrators to remove principals from group membership or ownership. adminUpdate: For administrators to change existing group membership or ownership assignments.adminExtend: For administrators to extend expiring assignments.adminRenew: For administrators to renew expired assignments.selfActivate: For principals to activate their assignments.selfDeactivate: For principals to deactivate their active assignments."), ValueMap{"adminAssign","adminUpdate","adminRemove","selfActivate","selfDeactivate","adminExtend","adminRenew","selfExtend","selfRenew","unknownFutureValue"}, Values{"adminAssign","adminUpdate","adminRemove","selfActivate","selfDeactivate","adminExtend","adminRenew","selfExtend","selfRenew","unknownFutureValue"}] String Action; - [Write, Description("Determines whether the call is a validation or an actual call. Only set this property if you want to check whether an activation is subject to additional rules like MFA before actually submitting the request.")] Boolean IsValidationOnly; - [Write, Description("A message provided by users and administrators when create they create the privilegedAccessGroupAssignmentScheduleRequest object.")] String Justification; - [Write, Description("The period of the group membership or ownership assignment. Recurring schedules are currently unsupported."), EmbeddedInstance("MSFT_MicrosoftGraphrequestSchedule")] String ScheduleInfo; - [Write, Description("Ticket details linked to the group membership or ownership assignment request including details of the ticket number and ticket system."), EmbeddedInstance("MSFT_MicrosoftGraphticketInfo")] String TicketInfo; - [Write, Description("The identifier of the approval of the request.")] String ApprovalId; - [Write, Description("The request completion date time.")] String CompletedDateTime; - [Write, Description("The principal that created the request."), EmbeddedInstance("MSFT_MicrosoftGraphidentitySet")] String CreatedBy; - [Write, Description("The status of the request. Not nullable. The possible values are: Canceled, Denied, Failed, Granted, PendingAdminDecision, PendingApproval, PendingProvisioning, PendingScheduleCreation, Provisioned, Revoked, and ScheduleCreated. Not nullable.")] String Status; - [Write, Description("The unique identifier for an entity. Read-only.")] String Id; - [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_AADGroupEligibilityScheduleRequest/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md deleted file mode 100644 index 85788e0a2e..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/readme.md +++ /dev/null @@ -1,6 +0,0 @@ - -# AADGroupEligibilityScheduleRequest - -## Description - -Azure AD Group Eligibility Schedule Request diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json deleted file mode 100644 index d76b1e149f..0000000000 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilityScheduleRequest/settings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "resourceName": "AADGroupEligibilityScheduleRequest", - "description": "This resource configures an Azure AD Group Eligibility Schedule Request.", - "permissions": { - "graph": { - "delegated": { - "read": [ - { - "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" - } - ], - "update": [ - - ] - }, - "application": { - "read": [ - { - "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" - } - ], - "update": [ - - ] - } - } -} - -} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 deleted file mode 100644 index 8e2edc6565..0000000000 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilityScheduleRequest.Tests.ps1 +++ /dev/null @@ -1,1290 +0,0 @@ -[CmdletBinding()] -param( -) -$M365DSCTestFolder = Join-Path -Path $PSScriptRoot ` - -ChildPath '..\..\Unit' ` - -Resolve -$CmdletModule = (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\Stubs\Microsoft365.psm1' ` - -Resolve) -$GenericStubPath = (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\Stubs\Generic.psm1' ` - -Resolve) -Import-Module -Name (Join-Path -Path $M365DSCTestFolder ` - -ChildPath '\UnitTestHelper.psm1' ` - -Resolve) - -$Global:DscHelper = New-M365DscUnitTestHelper -StubModule $CmdletModule ` - -DscResource "AADGroupEligibilityScheduleRequest" -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-MSCloudLoginConnectionProfile -MockWith { - } - - Mock -CommandName Reset-MSCloudLoginConnectionProfileContext -MockWith { - } - - Mock -CommandName Get-PSSession -MockWith { - } - - Mock -CommandName Remove-PSSession -MockWith { - } - - Mock -CommandName Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - } - - Mock -CommandName New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - } - - Mock -CommandName Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -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 AADGroupEligibilityScheduleRequest should exist but it DOES NOT" -Fixture { - BeforeAll { - $testParams = @{ - AccessId = "owner" - Action = "adminAssign" - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ - EndpointType = "default" - Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ - Id = "FakeStringValue" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - IpAddress = "FakeStringValue" - AppId = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - odataType = "#microsoft.graph.chatMessageFromIdentitySet" - Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - } -ClientOnly) - CustomData = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" - IsValidationOnly = $True - Justification = "FakeStringValue" - PrincipalId = "FakeStringValue" - scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } -ClientOnly) - range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } -ClientOnly) - } -ClientOnly) - expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } -ClientOnly) - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - TargetScheduleId = "FakeStringValue" - ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } -ClientOnly) - Ensure = "Present" - Credential = $Credential; - } - - Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 - } - } - - Context -Name "The AADGroupEligibilityScheduleRequest exists but it SHOULD NOT" -Fixture { - BeforeAll { - $testParams = @{ - AccessId = "owner" - Action = "adminAssign" - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ - EndpointType = "default" - Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ - Id = "FakeStringValue" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - IpAddress = "FakeStringValue" - AppId = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - odataType = "#microsoft.graph.chatMessageFromIdentitySet" - Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - } -ClientOnly) - CustomData = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" - IsValidationOnly = $True - Justification = "FakeStringValue" - PrincipalId = "FakeStringValue" - scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } -ClientOnly) - range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } -ClientOnly) - } -ClientOnly) - expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } -ClientOnly) - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - TargetScheduleId = "FakeStringValue" - ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } -ClientOnly) - Ensure = 'Absent' - Credential = $Credential; - } - - Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - return @{ - AdditionalProperties = @{ - isValidationOnly = $True - scheduleInfo = @{ - recurrence = @{ - pattern = @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } - range = @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } - } - expiration = @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - principalId = "FakeStringValue" - justification = "FakeStringValue" - accessId = "owner" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" - groupId = "FakeStringValue" - action = "adminAssign" - targetScheduleId = "FakeStringValue" - ticketInfo = @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } - } - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = @{ - '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" - Group = @{ - } - User = @{ - } - EndpointType = "default" - ApplicationInstance = @{ - } - Phone = @{ - } - Conversation = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = @{ - Name = "Details" - isArray = $False - } - AppId = "FakeStringValue" - Email = "FakeStringValue" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Application = @{ - } - SiteGroup = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Encrypted = @{ - } - AssertedIdentity = @{ - } - Guest = @{ - } - AzureCommunicationServicesUser = @{ - } - OnPremises = @{ - } - Device = @{ - } - SiteUser = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - } - CustomData = "FakeStringValue" - Id = "FakeStringValue" - Status = "FakeStringValue" - - } - } - } - - 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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 - } - } - - Context -Name "The AADGroupEligibilityScheduleRequest Exists and Values are already in the desired state" -Fixture { - BeforeAll { - $testParams = @{ - AccessId = "owner" - Action = "adminAssign" - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ - EndpointType = "default" - Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ - Id = "FakeStringValue" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - IpAddress = "FakeStringValue" - AppId = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - odataType = "#microsoft.graph.chatMessageFromIdentitySet" - Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - } -ClientOnly) - CustomData = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" - IsValidationOnly = $True - Justification = "FakeStringValue" - PrincipalId = "FakeStringValue" - scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } -ClientOnly) - range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } -ClientOnly) - } -ClientOnly) - expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } -ClientOnly) - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - TargetScheduleId = "FakeStringValue" - ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } -ClientOnly) - Ensure = 'Present' - Credential = $Credential; - } - - Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - return @{ - AdditionalProperties = @{ - isValidationOnly = $True - scheduleInfo = @{ - recurrence = @{ - pattern = @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } - range = @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } - } - expiration = @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - principalId = "FakeStringValue" - justification = "FakeStringValue" - accessId = "owner" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" - groupId = "FakeStringValue" - action = "adminAssign" - targetScheduleId = "FakeStringValue" - ticketInfo = @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } - } - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = @{ - '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" - Group = @{ - } - User = @{ - } - EndpointType = "default" - ApplicationInstance = @{ - } - Phone = @{ - } - Conversation = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = @{ - Name = "Details" - isArray = $False - } - AppId = "FakeStringValue" - Email = "FakeStringValue" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Application = @{ - } - SiteGroup = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Encrypted = @{ - } - AssertedIdentity = @{ - } - Guest = @{ - } - AzureCommunicationServicesUser = @{ - } - OnPremises = @{ - } - Device = @{ - } - SiteUser = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - } - CustomData = "FakeStringValue" - Id = "FakeStringValue" - Status = "FakeStringValue" - - } - } - } - - It 'Should return true from the Test method' { - Test-TargetResource @testParams | Should -Be $true - } - } - - Context -Name "The AADGroupEligibilityScheduleRequest exists and values are NOT in the desired state" -Fixture { - BeforeAll { - $testParams = @{ - AccessId = "owner" - Action = "adminAssign" - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentitySet -Property @{ - EndpointType = "default" - Group = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - OnPremises = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - User = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - ApplicationInstance = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Phone = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Conversation = (New-CimInstance -ClassName MSFT_MicrosoftGraphteamworkConversationIdentity -Property @{ - Id = "FakeStringValue" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - IpAddress = "FakeStringValue" - AppId = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Application = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteGroup = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - Encrypted = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AssertedIdentity = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - Guest = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - AzureCommunicationServicesUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - odataType = "#microsoft.graph.chatMessageFromIdentitySet" - Device = (New-CimInstance -ClassName MSFT_MicrosoftGraphidentity -Property @{ - } -ClientOnly) - SiteUser = (New-CimInstance -ClassName MSFT_MicrosoftGraphsharePointIdentity -Property @{ - Id = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = (New-CimInstance -ClassName MSFT_MicrosoftGraphdetailsInfo -Property @{ - Name = "Details" - isArray = $False - CIMType = "MSFT_MicrosoftGraphdetailsInfo" - } -ClientOnly) - Email = "FakeStringValue" - odataType = "#microsoft.graph.azureCommunicationServicesUserIdentity" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } -ClientOnly) - } -ClientOnly) - CustomData = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" - IsValidationOnly = $True - Justification = "FakeStringValue" - PrincipalId = "FakeStringValue" - scheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } -ClientOnly) - range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } -ClientOnly) - } -ClientOnly) - expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } -ClientOnly) - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - TargetScheduleId = "FakeStringValue" - ticketInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphticketInfo -Property @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } -ClientOnly) - Ensure = 'Present' - Credential = $Credential; - } - - Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - return @{ - AdditionalProperties = @{ - justification = "FakeStringValue" - scheduleInfo = @{ - recurrence = @{ - pattern = @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 7 - month = 7 - daysOfWeek = @("sunday") - type = "daily" - interval = 7 - } - range = @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 7 - type = "endDate" - } - } - expiration = @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - accessId = "owner" - principalId = "FakeStringValue" - action = "adminAssign" - groupId = "FakeStringValue" - targetScheduleId = "FakeStringValue" - ticketInfo = @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } - } - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = @{ - '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" - Group = @{ - } - User = @{ - } - EndpointType = "default" - ApplicationInstance = @{ - } - Phone = @{ - } - Conversation = @{ - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationIdentityType = "aadApplication" - Id = "FakeStringValue" - AppId = "FakeStringValue" - Email = "FakeStringValue" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - UserIdentityType = "aadUser" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - IdentityType = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - ConversationIdentityType = "team" - } - Application = @{ - } - SiteGroup = @{ - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - AzureCommunicationServicesResourceId = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - Id = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - UserIdentityType = "aadUser" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - IdentityType = "FakeStringValue" - AppId = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - ConversationIdentityType = "team" - } - Encrypted = @{ - } - AssertedIdentity = @{ - } - Guest = @{ - } - AzureCommunicationServicesUser = @{ - } - OnPremises = @{ - } - Device = @{ - } - SiteUser = @{ - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - AzureCommunicationServicesResourceId = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - Id = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - ApplicationIdentityType = "aadApplication" - ApplicationType = "FakeStringValue" - UserIdentityType = "aadUser" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - IdentityType = "FakeStringValue" - AppId = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - ConversationIdentityType = "team" - } - } - CustomData = "FakeStringValue" - Id = "FakeStringValue" - Status = "FakeStringValue" - } - } - } - - 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-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 - } - } - - Context -Name 'ReverseDSC Tests' -Fixture { - BeforeAll { - $Global:CurrentModeIsExport = $true - $Global:PartialExportFileName = "$(New-Guid).partial.ps1" - $testParams = @{ - Credential = $Credential - } - - Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - return @{ - AdditionalProperties = @{ - isValidationOnly = $True - scheduleInfo = @{ - recurrence = @{ - pattern = @{ - index = "first" - firstDayOfWeek = "sunday" - dayOfMonth = 25 - month = 25 - daysOfWeek = @("sunday") - type = "daily" - interval = 25 - } - range = @{ - startDate = "2023-01-01T00:00:00.0000000" - endDate = "2023-01-01T00:00:00.0000000" - recurrenceTimeZone = "FakeStringValue" - numberOfOccurrences = 25 - type = "endDate" - } - } - expiration = @{ - endDateTime = "2023-01-01T00:00:00.0000000+01:00" - type = "notSpecified" - } - startDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - principalId = "FakeStringValue" - justification = "FakeStringValue" - accessId = "owner" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilityScheduleRequest" - groupId = "FakeStringValue" - action = "adminAssign" - targetScheduleId = "FakeStringValue" - ticketInfo = @{ - ticketNumber = "FakeStringValue" - ticketSystem = "FakeStringValue" - } - } - approvalId = "FakeStringValue" - completedDateTime = "2023-01-01T00:00:00.0000000+01:00" - CreatedBy = @{ - '@odata.type' = "#microsoft.graph.chatMessageFromIdentitySet" - Group = @{ - } - User = @{ - } - EndpointType = "default" - ApplicationInstance = @{ - } - Phone = @{ - } - Conversation = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - Details = @{ - Name = "Details" - isArray = $False - } - AppId = "FakeStringValue" - Email = "FakeStringValue" - ApplicationType = "FakeStringValue" - IpAddress = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AzureCommunicationServicesResourceId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Application = @{ - } - SiteGroup = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - Encrypted = @{ - } - AssertedIdentity = @{ - } - Guest = @{ - } - AzureCommunicationServicesUser = @{ - } - OnPremises = @{ - } - Device = @{ - } - SiteUser = @{ - Id = "FakeStringValue" - '@odata.type' = "#microsoft.graph.azureCommunicationServicesUserIdentity" - UserIdentityType = "aadUser" - ApplicationIdentityType = "aadApplication" - AzureCommunicationServicesResourceId = "FakeStringValue" - IpAddress = "FakeStringValue" - Email = "FakeStringValue" - Details = @{ - Name = "Details" - isArray = $False - } - ApplicationType = "FakeStringValue" - InitiatorType = "user" - DisplayName = "FakeStringValue" - TenantId = "FakeStringValue" - LoginName = "FakeStringValue" - UserPrincipalName = "FakeStringValue" - AppId = "FakeStringValue" - Hidden = $True - ConversationIdentityType = "team" - IdentityType = "FakeStringValue" - } - } - CustomData = "FakeStringValue" - Id = "FakeStringValue" - Status = "FakeStringValue" - - } - } - } - - It 'Should Reverse Engineer resource from the Export method' { - $result = Export-TargetResource @testParams - $result | Should -Not -BeNullOrEmpty - } - } - } -} - -Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope From 4f6fe2e11a88353133099c836a0c70b5816a8ab7 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Mon, 23 Dec 2024 10:09:24 +0100 Subject: [PATCH 03/11] wip --- Tests/Unit/Stubs/Microsoft365.psm1 | 135 ----------------------------- 1 file changed, 135 deletions(-) diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index a19ed4340b..b17b09792d 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -105764,140 +105764,5 @@ function Stop-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleReques ) } -function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -{ - [CmdletBinding()] - param - ( - [Parameter()] - [System.String] - $PrivilegedAccessGroupEligibilityScheduleRequestId, - - [Parameter()] - [PSObject] - $InputObject, - - [Parameter()] - [PSObject] - $BodyParameter, - - [Parameter()] - [System.String] - $ResponseHeadersVariable, - - [Parameter()] - [System.String] - $AccessId, - - [Parameter()] - [System.String] - $Action, - - [Parameter()] - [System.Collections.Hashtable] - $AdditionalProperties, - - [Parameter()] - [System.String] - $ApprovalId, - - [Parameter()] - [System.DateTime] - $CompletedDateTime, - - [Parameter()] - [PSObject] - $CreatedBy, - - [Parameter()] - [System.DateTime] - $CreatedDateTime, - - [Parameter()] - [System.String] - $CustomData, - - [Parameter()] - [PSObject] - $Group, - - [Parameter()] - [System.String] - $GroupId, - - [Parameter()] - [System.String] - $Id, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $IsValidationOnly, - - [Parameter()] - [System.String] - $Justification, - - [Parameter()] - [PSObject] - $Principal, - - [Parameter()] - [System.String] - $PrincipalId, - - [Parameter()] - [PSObject] - $ScheduleInfo, - - [Parameter()] - [System.String] - $Status, - - [Parameter()] - [PSObject] - $TargetSchedule, - - [Parameter()] - [System.String] - $TargetScheduleId, - - [Parameter()] - [PSObject] - $TicketInfo, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Break, - - [Parameter()] - [System.Collections.IDictionary] - $Headers, - - [Parameter()] - [PSObject[]] - $HttpPipelineAppend, - - [Parameter()] - [PSObject[]] - $HttpPipelinePrepend, - - [Parameter()] - [System.Uri] - $Proxy, - - [Parameter()] - [System.Management.Automation.PSCredential] - $ProxyCredential, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ProxyUseDefaultCredentials, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm - ) -} - #endregion From e7153b68c58c86860cc69e80417f786097b58c98 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Mon, 23 Dec 2024 11:47:39 +0100 Subject: [PATCH 04/11] wip --- .../MSFT_AADGroupEligibilitySchedule.psm1 | 772 ++++++++++++++++++ ...SFT_AADGroupEligibilitySchedule.schema.mof | 62 ++ .../readme.md | 6 + .../settings.json | 29 + .../1-AADGroupEligibilitySchedule-Example.ps1 | 34 + ...5DSC.AADGroupEligibilitySchedule.Tests.ps1 | 458 +++++++++++ Tests/Unit/Stubs/Microsoft365.psm1 | 351 ++++++++ 7 files changed, 1712 insertions(+) create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/readme.md create mode 100644 Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/settings.json create mode 100644 Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 create mode 100644 Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 new file mode 100644 index 0000000000..0535e11b1a --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 @@ -0,0 +1,772 @@ +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + #region resource generator code + [Parameter()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [ValidateSet('direct','group','unknownFutureValue')] + [System.String] + $MemberType, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $PrincipalType, + + [Parameter()] + [System.String] + $PrincipalDisplayName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Id, + + #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 + ) + + Write-Verbose -Message "Getting configuration of the Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + + 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 + + if ($Id -notmatch '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}_member_[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') { + $getId = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ` + -Filter "Groupid eq '$GroupId'" ` + -ErrorAction SilentlyContinue + $Id = $getId.Id + } + + $uri = 'https://graph.microsoft.com/v1.0/identityGovernance/privilegedAccess/group/eligibilitySchedules/' + $Id + $getvalue = Invoke-GraphRequest -Uri $uri -Method Get -ErrorAction SilentlyContinue + + #endregion + if ($null -eq $getValue) + { + Write-Verbose -Message "Could not find an Azure AD Group Eligibility Schedule with DisplayName {$DisplayName}." + return $nullResult + } + $Id = $getValue.Id + Write-Verbose -Message "An Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName} was found" + + #region resource generator code + $complexScheduleInfo = @{} + $complexExpiration = @{} + $complexExpiration.Add('Duration', $getValue.scheduleInfo.expiration.duration) + if ($null -ne $getValue.scheduleInfo.expiration.endDateTime) + { + $complexExpiration.Add('EndDateTime', ([DateTimeOffset]$getValue.scheduleInfo.expiration.endDateTime).ToString('')) + } + if ($null -ne $getValue.scheduleInfo.expiration.type) + { + $complexExpiration.Add('Type', $getValue.scheduleInfo.expiration.type.ToString()) + } + if ($complexExpiration.values.Where({$null -ne $_}).Count -eq 0) + { + $complexExpiration = $null + } + $complexScheduleInfo.Add('Expiration',$complexExpiration) + $complexRecurrence = @{} + $complexPattern = @{} + $complexPattern.Add('DayOfMonth', $getValue.scheduleInfo.recurrence.pattern.dayOfMonth) + if ($null -ne $getValue.scheduleInfo.recurrence.pattern.daysOfWeek) + { + $complexPattern.Add('DaysOfWeek', $getValue.scheduleInfo.recurrence.pattern.daysOfWeek.ToString()) + } + if ($null -ne $getValue.scheduleInfo.recurrence.pattern.firstDayOfWeek) + { + $complexPattern.Add('FirstDayOfWeek', $getValue.scheduleInfo.recurrence.pattern.firstDayOfWeek.ToString()) + } + if ($null -ne $getValue.scheduleInfo.recurrence.pattern.index) + { + $complexPattern.Add('Index', $getValue.scheduleInfo.recurrence.pattern.index.ToString()) + } + $complexPattern.Add('Interval', $getValue.scheduleInfo.recurrence.pattern.interval) + $complexPattern.Add('Month', $getValue.scheduleInfo.recurrence.pattern.month) + if ($null -ne $getValue.scheduleInfo.recurrence.pattern.type) + { + $complexPattern.Add('Type', $getValue.scheduleInfo.recurrence.pattern.type.ToString()) + } + if ($complexPattern.values.Where({$null -ne $_}).Count -eq 0) + { + $complexPattern = $null + } + $complexRecurrence.Add('Pattern',$complexPattern) + $complexRange = @{} + if ($null -ne $getValue.scheduleInfo.recurrence.range.endDate) + { + $complexRange.Add('EndDate', ([DateTime]$getValue.scheduleInfo.recurrence.range.endDate).ToString('')) + } + $complexRange.Add('NumberOfOccurrences', $getValue.scheduleInfo.recurrence.range.numberOfOccurrences) + $complexRange.Add('RecurrenceTimeZone', $getValue.scheduleInfo.recurrence.range.recurrenceTimeZone) + if ($null -ne $getValue.scheduleInfo.recurrence.range.startDate) + { + $complexRange.Add('StartDate', ([DateTime]$getValue.scheduleInfo.recurrence.range.startDate).ToString('')) + } + if ($null -ne $getValue.scheduleInfo.recurrence.range.type) + { + $complexRange.Add('Type', $getValue.scheduleInfo.recurrence.range.type.ToString()) + } + if ($complexRange.values.Where({$null -ne $_}).Count -eq 0) + { + $complexRange = $null + } + $complexRecurrence.Add('Range',$complexRange) + if ($complexRecurrence.values.Where({$null -ne $_}).Count -eq 0) + { + $complexRecurrence = $null + } + $complexScheduleInfo.Add('Recurrence',$complexRecurrence) + if ($null -ne $getValue.ScheduleInfo.startDateTime) + { + $complexScheduleInfo.Add('StartDateTime', ([DateTimeOffset]$getValue.ScheduleInfo.startDateTime).ToString('o')) + } + if ($complexScheduleInfo.values.Where({$null -ne $_}).Count -eq 0) + { + $complexScheduleInfo = $null + } + #endregion + + #region resource generator code + $enumAccessId = $null + if ($null -ne $getValue.accessId) + { + $enumAccessId = $getValue.accessId.ToString() + } + + $enumMemberType = $null + if ($null -ne $getValue.memberType) + { + $enumMemberType = $getValue.memberType.ToString() + } + #endregion + + #region resource generator code + $dateModifiedDateTime = $null + if ($null -ne $getValue.ModifiedDateTime) + { + $dateModifiedDateTime = ([DateTimeOffset]$getValue.ModifiedDateTime).ToString('o') + } + #endregion + $PrincipalGroup = Get-MgGroup -GroupId $getvalue.PrincipalId + if($null -ne $PrincipalGroup){ + $PrincipalType = 'group' + $PrincipalDisplayName = $PrincipalGroup.DisplayName + } + else{ + $PrincipalType = 'user' + $PrincipalDisplayName = (Get-MgUser -UserId $getvalue.PrincipalId).DisplayName + } + $GroupDisplayName = (Get-MgGroup -GroupId $getvalue.GroupId).DisplayName + + $results = @{ + #region resource generator code + AccessId = $enumAccessId + GroupId = $getValue.groupId + GroupDisplayName = $GroupDisplayName + MemberType = $enumMemberType + PrincipalType = $PrincipalType + PrincipalDisplayname = $PrincipalDisplayName + CreatedUsing = $getValue.CreatedUsing + ModifiedDateTime = $dateModifiedDateTime + ScheduleInfo = $complexScheduleInfo + Status = $getValue.Status + Id = $getValue.Id + Ensure = 'Present' + Credential = $Credential + ApplicationId = $ApplicationId + TenantId = $TenantId + ApplicationSecret = $ApplicationSecret + CertificateThumbprint = $CertificateThumbprint + ManagedIdentity = $ManagedIdentity.IsPresent + #endregion + } + + 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()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [ValidateSet('direct','group','unknownFutureValue')] + [System.String] + $MemberType, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $PrincipalType, + + [Parameter()] + [System.String] + $PrincipalDisplayName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Id, + + #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 + ) + + Write-Verbose -Message "Setting configuration of the Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + + #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 + + + if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') + { + Write-Verbose -Message "Creating an Azure AD Group Eligibility Schedule with DisplayName {$DisplayName}" + + $createParameters = ([Hashtable]$BoundParameters).Clone() + $createParameters = Rename-M365DSCCimInstanceParameter -Properties $createParameters + $createParameters.Remove('Id') | Out-Null + $createParameters.Remove('PrincipalType') | Out-Null + $createParameters.Remove('PrincipalDisplayName') | Out-Null + $createParameters.Remove('GroupDisplayName') | Out-Null + + $GroupId = (Get-MgGroup -DisplayName $GroupDisplayName).Id + $createParameters.Add('GroupId', $GroupId) + if($PrincipalType -eq 'group'){ + $PrincipalId = (Get-MgGroup -DisplayName $PrincipalDisplayName).Id + } + else{ + $PrincipalId = (Get-MgUser -DisplayName $PrincipalDisplayName).Id + } + $createParameters.Add('PrincipalId', $PrincipalId) + + $keys = (([Hashtable]$createParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $createParameters.$key -and $createParameters.$key.GetType().Name -like '*CimInstance*') + { + $createParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $createParameters.$key + } + } + #region resource generator code + $createParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule") + $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -BodyParameter $createParameters + #endregion + } + elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Updating the Azure AD Group Eligibility Schedule with Id {$($currentInstance.Id)}" + + $updateParameters = ([Hashtable]$BoundParameters).Clone() + $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters + + $updateParameters.Remove('Id') | Out-Null + $updateParameters.Remove('PrincipalType') | Out-Null + $updateParameters.Remove('PrincipalDisplayName') | Out-Null + $updateParameters.Remove('GroupDisplayName') | Out-Null + + $GroupId = (Get-MgGroup -DisplayName $GroupDisplayName).Id + $createParameters.Add('GroupId', $GroupId) + if($PrincipalType -eq 'group'){ + $PrincipalId = (Get-MgGroup -DisplayName $PrincipalDisplayName).Id + } + else{ + $PrincipalId = (Get-MgUser -DisplayName $PrincipalDisplayName).Id + } + $updateParameters.Add('PrincipalId', $PrincipalId) + + $keys = (([Hashtable]$updateParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $pdateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') + { + $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.PrivilegedAccessGroupEligibilityScheduleId + } + } + + #region resource generator code + $UpdateParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule") + Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ` + -PrivilegedAccessGroupEligibilityScheduleId $currentInstance.Id ` + -BodyParameter $UpdateParameters + #endregion + } + elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') + { + Write-Verbose -Message "Removing the Azure AD Group Eligibility Schedule with Id {$($currentInstance.Id)}" + #region resource generator code + Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -PrivilegedAccessGroupEligibilityScheduleId $currentInstance.Id + #endregion + } +} + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + #region resource generator code + [Parameter()] + [ValidateSet('owner','member','unknownFutureValue')] + [System.String] + $AccessId, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter(Mandatory = $true)] + [System.String] + $GroupDisplayName, + + [Parameter()] + [ValidateSet('direct','group','unknownFutureValue')] + [System.String] + $MemberType, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [System.String] + $PrincipalType, + + [Parameter()] + [System.String] + $PrincipalDisplayName, + + [Parameter()] + [Microsoft.Management.Infrastructure.CimInstance] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Id, + + #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 Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + + $CurrentValues = Get-TargetResource @PSBoundParameters + $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() + + 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 $ValuesToCheck)" + + 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 + { + + $groups = Get-MgGroup -Filter "MailEnabled eq false and NOT(groupTypes/any(x:x eq 'DynamicMembership'))" -Property "displayname,Id" -CountVariable CountVar -ConsistencyLevel eventual -ErrorAction Stop + foreach ($group in $groups) + { + Write-Host "get group $($group.DisplayName)" + #region resource generator code + $getValue = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ` + -Filter "groupId eq '$($group.Id)'" ` + -All ` + -ErrorAction Stop + if($null -eq $getValue) + { + continue + } + + $i = 1 + $dscContent = '' + if ($getValue.Length -eq 0) + { + Write-Host $Global:M365DSCEmojiGreenCheckMark + } + else + { + Write-Host "`r`n" -NoNewline + } + foreach ($config in $getValue) + { + Write-Host " |---[$i/$($getValue.Count)] $($group.DisplayName)" -NoNewline + $params = @{ + Id = $config.Id + GroupDisplayName = $group.DisplayName + 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 ($null -ne $Results.ScheduleInfo) + { + $complexMapping = @( + @{ + Name = 'ScheduleInfo' + CimInstanceName = 'MicrosoftGraphRequestSchedule' + IsRequired = $True + } + @{ + Name = 'Expiration' + CimInstanceName = 'MicrosoftGraphExpirationPattern' + IsRequired = $False + } + @{ + Name = 'Recurrence' + CimInstanceName = 'MicrosoftGraphPatternedRecurrence1' + IsRequired = $False + } + @{ + Name = 'Pattern' + CimInstanceName = 'MicrosoftGraphRecurrencePattern1' + IsRequired = $False + } + @{ + Name = 'Range' + CimInstanceName = 'MicrosoftGraphRecurrenceRange1' + IsRequired = $False + } + ) + $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` + -ComplexObject $Results.ScheduleInfo ` + -CIMInstanceName 'MicrosoftGraphrequestSchedule' ` + -ComplexTypeMapping $complexMapping + + if (-not [String]::IsNullOrWhiteSpace($complexTypeStringResult)) + { + $Results.ScheduleInfo = $complexTypeStringResult + } + else + { + $Results.Remove('ScheduleInfo') | Out-Null + } + } + + $currentDSCBlock = Get-M365DSCExportContentForResource -ResourceName $ResourceName ` + -ConnectionMode $ConnectionMode ` + -ModulePath $PSScriptRoot ` + -Results $Results ` + -Credential $Credential + if ($Results.ScheduleInfo) + { + $currentDSCBlock = Convert-DSCStringParamToVariable -DSCBlock $currentDSCBlock -ParameterName "ScheduleInfo" -IsCIMArray:$False + } + + $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_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof new file mode 100644 index 0000000000..20f21d3701 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof @@ -0,0 +1,62 @@ +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRequestSchedule +{ + [Write, Description("When the eligible or active assignment expires."), EmbeddedInstance("MSFT_MicrosoftGraphExpirationPattern")] String Expiration; + [Write, Description("The frequency of the eligible or active assignment. This property is currently unsupported in PIM."), EmbeddedInstance("MSFT_MicrosoftGraphPatternedRecurrence1")] String Recurrence; + [Write, Description("When the eligible or active assignment becomes active.")] String StartDateTime; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphExpirationPattern +{ + [Write, Description("The requestor's desired duration of access represented in ISO 8601 format for durations. For example, PT3H refers to three hours. If specified in a request, endDateTime should not be present and the type property should be set to afterDuration.")] String Duration; + [Write, Description("Timestamp of date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z.")] String EndDateTime; + [Write, Description("The requestor's desired expiration pattern type. The possible values are: notSpecified, noExpiration, afterDateTime, afterDuration."), ValueMap{"notSpecified","noExpiration","afterDateTime","afterDuration"}, Values{"notSpecified","noExpiration","afterDateTime","afterDuration"}] String Type; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphPatternedRecurrence1 +{ + [Write, Description("The frequency of an event. For access reviews: Do not specify this property for a one-time access review. Only interval, dayOfMonth, and type (weekly, absoluteMonthly) properties of recurrencePattern are supported."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrencePattern1")] String Pattern; + [Write, Description("The duration of an event."), EmbeddedInstance("MSFT_MicrosoftGraphRecurrenceRange1")] String Range; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRecurrencePattern1 +{ + [Write, Description("The day of the month on which the event occurs. Required if type is absoluteMonthly or absoluteYearly.")] UInt32 DayOfMonth; + [Write, Description("A collection of the days of the week on which the event occurs. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. If type is relativeMonthly or relativeYearly, and daysOfWeek specifies more than one day, the event falls on the first day that satisfies the pattern. Required if type is weekly, relativeMonthly, or relativeYearly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String DaysOfWeek[]; + [Write, Description("The first day of the week. The possible values are: sunday, monday, tuesday, wednesday, thursday, friday, saturday. Default is sunday. Required if type is weekly."), ValueMap{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}, Values{"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}] String FirstDayOfWeek; + [Write, Description("Specifies on which instance of the allowed days specified in daysOfWeek the event occurs, counted from the first instance in the month. The possible values are: first, second, third, fourth, last. Default is first. Optional and used if type is relativeMonthly or relativeYearly."), ValueMap{"first","second","third","fourth","last"}, Values{"first","second","third","fourth","last"}] String Index; + [Write, Description("The number of units between occurrences, where units can be in days, weeks, months, or years, depending on the type. Required.")] UInt32 Interval; + [Write, Description("The month in which the event occurs. This is a number from 1 to 12.")] UInt32 Month; + [Write, Description("The recurrence pattern type: daily, weekly, absoluteMonthly, relativeMonthly, absoluteYearly, relativeYearly. Required. For more information, see values of type property."), ValueMap{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}, Values{"daily","weekly","absoluteMonthly","relativeMonthly","absoluteYearly","relativeYearly"}] String Type; +}; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphRecurrenceRange1 +{ + [Write, Description("The date to stop applying the recurrence pattern. Depending on the recurrence pattern of the event, the last occurrence of the meeting may not be this date. Required if type is endDate.")] String EndDate; + [Write, Description("The number of times to repeat the event. Required and must be positive if type is numbered.")] UInt32 NumberOfOccurrences; + [Write, Description("Time zone for the startDate and endDate properties. Optional. If not specified, the time zone of the event is used.")] String RecurrenceTimeZone; + [Write, Description("The date to start applying the recurrence pattern. The first occurrence of the meeting may be this date or later, depending on the recurrence pattern of the event. Must be the same value as the start property of the recurring event. Required.")] String StartDate; + [Write, Description("The recurrence range. The possible values are: endDate, noEnd, numbered. Required."), ValueMap{"endDate","noEnd","numbered"}, Values{"endDate","noEnd","numbered"}] String Type; +}; + +[ClassVersion("1.0.0.0"), FriendlyName("AADGroupEligibilitySchedule")] +class MSFT_AADGroupEligibilitySchedule : OMI_BaseResource +{ + [Write, Description("The identifier of the membership or ownership eligibility to the group that is governed by PIM. Required. The possible values are: owner, member. Supports $filter (eq)."), ValueMap{"owner","member","unknownFutureValue"}, Values{"owner","member","unknownFutureValue"}] String AccessId; + [Write, Description("The identifier of the group representing the scope of the membership or ownership eligibility through PIM for groups. Required. Supports $filter (eq).")] String GroupId; + [Key, Description("Dsiaplyname of the group representing the scope of the membership or ownership eligibility through PIM for groups.")] String GroupDisplayName; + [Write, Description("Indicates whether the assignment is derived from a group assignment. It can further imply whether the caller can manage the schedule. Required. The possible values are: direct, group, unknownFutureValue. Supports $filter (eq)."), ValueMap{"direct","group","unknownFutureValue"}, Values{"direct","group","unknownFutureValue"}] String MemberType; + [Write, Description("The identifier of the principal whose membership or ownership eligibility is granted through PIM for groups. Required. Supports $filter (eq).")] String PrincipalId; + [Write, Description("Principal type user or group"), ValueMap{"user","group"}, Values{"user","group"}] String PrincipalType, + [Write, Description("Displayname of the Principal")], String PrincipalDisplayName, + [Write, Description("Represents the period of the access assignment or eligibility. The scheduleInfo can represent a single occurrence or multiple recurring instances. Required."), EmbeddedInstance("MSFT_MicrosoftGraphrequestSchedule")] String ScheduleInfo; + [Write, Description("The unique identifier for an entity. Read-only.")] String Id; + [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_AADGroupEligibilitySchedule/readme.md b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/readme.md new file mode 100644 index 0000000000..be5cf0dab6 --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/readme.md @@ -0,0 +1,6 @@ + +# AADGroupEligibilitySchedule + +## Description + +Azure AD Group Eligibility Schedule diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/settings.json b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/settings.json new file mode 100644 index 0000000000..0cd7ea504f --- /dev/null +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/settings.json @@ -0,0 +1,29 @@ +{ + "resourceName": "AADGroupEligibilitySchedule", + "description": "This resource configures an Azure AD Group Eligibility Schedule.", + "permissions": { + "graph": { + "delegated": { + "read": [ + { + "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" + } + ], + "update": [ + + ] + }, + "application": { + "read": [ + { + "name": "PrivilegedEligibilitySchedule.Read.AzureADGroup" + } + ], + "update": [ + + ] + } + } +} + +} diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 new file mode 100644 index 0000000000..41aebfc15d --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 @@ -0,0 +1,34 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + AADGroupEligibilitySchedule 'Example' + { + AccessId = "member"; + Ensure = "Present"; + GroupDisplayName = "MyPIMGroup"; + MemberType = "direct"; + PrincipalDisplayname = "MyPrincipalGroup"; + PrincipalType = "group"; + ScheduleInfo = MSFT_MicrosoftGraphrequestSchedule{ + StartDateTime = '2024-12-23T08:59:28.1200000+00:00' + Expiration = MSFT_MicrosoftGraphExpirationPattern{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + Type = 'notSpecified' + } + }; + } + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 new file mode 100644 index 0000000000..5218b42c8f --- /dev/null +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 @@ -0,0 +1,458 @@ +[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 "AADGroupEligibilitySchedule" -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-MSCloudLoginConnectionProfile -MockWith { + } + + Mock -CommandName Reset-MSCloudLoginConnectionProfileContext -MockWith { + } + + Mock -CommandName Get-PSSession -MockWith { + } + + Mock -CommandName Remove-PSSession -MockWith { + } + + Mock -CommandName Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + } + + Mock -CommandName New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + } + + Mock -CommandName Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -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 AADGroupEligibilitySchedule should exist but it DOES NOT" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + CreatedUsing = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + MemberType = "direct" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + PrincipalId = "FakeStringValue" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } -ClientOnly) + Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } -ClientOnly) + } -ClientOnly) + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } -ClientOnly) + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + Ensure = "Present" + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -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-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + } + } + + Context -Name "The AADGroupEligibilitySchedule exists but it SHOULD NOT" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + CreatedUsing = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + MemberType = "direct" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + PrincipalId = "FakeStringValue" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } -ClientOnly) + Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } -ClientOnly) + } -ClientOnly) + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } -ClientOnly) + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + Ensure = 'Absent' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + return @{ + AdditionalProperties = @{ + groupId = "FakeStringValue" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" + principalId = "FakeStringValue" + memberType = "direct" + accessId = "owner" + } + CreatedUsing = "FakeStringValue" + Id = "FakeStringValue" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + ScheduleInfo = @{ + Recurrence = @{ + Pattern = @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } + Range = @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } + } + Expiration = @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + Status = "FakeStringValue" + + } + } + } + + 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-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + } + } + + Context -Name "The AADGroupEligibilitySchedule Exists and Values are already in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + CreatedUsing = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + MemberType = "direct" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + PrincipalId = "FakeStringValue" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } -ClientOnly) + Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } -ClientOnly) + } -ClientOnly) + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } -ClientOnly) + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + return @{ + AdditionalProperties = @{ + groupId = "FakeStringValue" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" + principalId = "FakeStringValue" + memberType = "direct" + accessId = "owner" + } + CreatedUsing = "FakeStringValue" + Id = "FakeStringValue" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + ScheduleInfo = @{ + Recurrence = @{ + Pattern = @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } + Range = @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } + } + Expiration = @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + Status = "FakeStringValue" + + } + } + } + + It 'Should return true from the Test method' { + Test-TargetResource @testParams | Should -Be $true + } + } + + Context -Name "The AADGroupEligibilitySchedule exists and values are NOT in the desired state" -Fixture { + BeforeAll { + $testParams = @{ + AccessId = "owner" + CreatedUsing = "FakeStringValue" + GroupId = "FakeStringValue" + Id = "FakeStringValue" + MemberType = "direct" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + PrincipalId = "FakeStringValue" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ + Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ + Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } -ClientOnly) + Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } -ClientOnly) + } -ClientOnly) + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } -ClientOnly) + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } -ClientOnly) + Status = "FakeStringValue" + Ensure = 'Present' + Credential = $Credential; + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + return @{ + AdditionalProperties = @{ + principalId = "FakeStringValue" + groupId = "FakeStringValue" + memberType = "direct" + accessId = "owner" + } + CreatedUsing = "FakeStringValue" + Id = "FakeStringValue" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + ScheduleInfo = @{ + Recurrence = @{ + Pattern = @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 7 + Month = 7 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 7 + } + Range = @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 7 + Type = "endDate" + } + } + Expiration = @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + Status = "FakeStringValue" + } + } + } + + 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-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + } + } + + Context -Name 'ReverseDSC Tests' -Fixture { + BeforeAll { + $Global:CurrentModeIsExport = $true + $Global:PartialExportFileName = "$(New-Guid).partial.ps1" + $testParams = @{ + Credential = $Credential + } + + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + return @{ + AdditionalProperties = @{ + groupId = "FakeStringValue" + '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" + principalId = "FakeStringValue" + memberType = "direct" + accessId = "owner" + } + CreatedUsing = "FakeStringValue" + Id = "FakeStringValue" + ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" + ScheduleInfo = @{ + Recurrence = @{ + Pattern = @{ + Index = "first" + FirstDayOfWeek = "sunday" + DayOfMonth = 25 + Month = 25 + DaysOfWeek = @("sunday") + Type = "daily" + Interval = 25 + } + Range = @{ + StartDate = "2023-01-01T00:00:00.0000000" + EndDate = "2023-01-01T00:00:00.0000000" + RecurrenceTimeZone = "FakeStringValue" + NumberOfOccurrences = 25 + Type = "endDate" + } + } + Expiration = @{ + EndDateTime = "2023-01-01T00:00:00.0000000+01:00" + Type = "notSpecified" + } + StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + } + Status = "FakeStringValue" + + } + } + } + + It 'Should Reverse Engineer resource from the Export method' { + $result = Export-TargetResource @testParams + $result | Should -Not -BeNullOrEmpty + } + } + } +} + +Invoke-Command -ScriptBlock $Global:DscHelper.CleanupScript -NoNewScope diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index b17b09792d..52a425eff2 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -105766,3 +105766,354 @@ function Stop-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleReques #endregion +#region MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String[]] + $ExpandProperty, + + [Parameter()] + [System.String[]] + $Property, + + [Parameter()] + [System.String] + $Filter, + + [Parameter()] + [System.String] + $Search, + + [Parameter()] + [System.Int32] + $Skip, + + [Parameter()] + [System.String[]] + $Sort, + + [Parameter()] + [System.Int32] + $Top, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Int32] + $PageSize, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $All, + + [Parameter()] + [System.String] + $CountVariable + ) +} + +function New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +{ + [CmdletBinding()] + param + ( + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.String] + $AccessId, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.DateTime] + $CreatedDateTime, + + [Parameter()] + [System.String] + $CreatedUsing, + + [Parameter()] + [PSObject] + $Group, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $MemberType, + + [Parameter()] + [System.DateTime] + $ModifiedDateTime, + + [Parameter()] + [PSObject] + $Principal, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [PSObject] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Status, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +function Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $PassThru, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $PrivilegedAccessGroupEligibilityScheduleId, + + [Parameter()] + [PSObject] + $InputObject, + + [Parameter()] + [PSObject] + $BodyParameter, + + [Parameter()] + [System.String] + $ResponseHeadersVariable, + + [Parameter()] + [System.String] + $AccessId, + + [Parameter()] + [System.Collections.Hashtable] + $AdditionalProperties, + + [Parameter()] + [System.DateTime] + $CreatedDateTime, + + [Parameter()] + [System.String] + $CreatedUsing, + + [Parameter()] + [PSObject] + $Group, + + [Parameter()] + [System.String] + $GroupId, + + [Parameter()] + [System.String] + $Id, + + [Parameter()] + [System.String] + $MemberType, + + [Parameter()] + [System.DateTime] + $ModifiedDateTime, + + [Parameter()] + [PSObject] + $Principal, + + [Parameter()] + [System.String] + $PrincipalId, + + [Parameter()] + [PSObject] + $ScheduleInfo, + + [Parameter()] + [System.String] + $Status, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Break, + + [Parameter()] + [System.Collections.IDictionary] + $Headers, + + [Parameter()] + [PSObject[]] + $HttpPipelineAppend, + + [Parameter()] + [PSObject[]] + $HttpPipelinePrepend, + + [Parameter()] + [System.Uri] + $Proxy, + + [Parameter()] + [System.Management.Automation.PSCredential] + $ProxyCredential, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $ProxyUseDefaultCredentials, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $Confirm + ) +} + +#endregion + From 88ecd8ea8b44b99f75378a7a8751fe6117a01936 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Mon, 23 Dec 2024 13:40:20 +0100 Subject: [PATCH 05/11] wip --- .../MSFT_AADGroupEligibilitySchedule.psm1 | 44 +++++++++---------- ...SFT_AADGroupEligibilitySchedule.schema.mof | 4 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 index 0535e11b1a..961bf2b5bb 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 @@ -79,7 +79,7 @@ function Get-TargetResource $AccessTokens ) - Write-Verbose -Message "Getting configuration of the Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + Write-Verbose -Message "Getting configuration of the Azure AD Group {$GroupDisplayName}Eligibility Schedule" try { @@ -102,7 +102,10 @@ function Get-TargetResource $nullResult.Ensure = 'Absent' $getValue = $null - + if($GroupId.Length -eq 0){ + $Filter = "DisplayName eq '" + $GroupDisplayName + "'" + $GroupId = (Get-MgGroup -Filter $Filter).Id + } if ($Id -notmatch '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}_member_[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') { $getId = Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ` -Filter "Groupid eq '$GroupId'" ` @@ -116,11 +119,11 @@ function Get-TargetResource #endregion if ($null -eq $getValue) { - Write-Verbose -Message "Could not find an Azure AD Group Eligibility Schedule with DisplayName {$DisplayName}." + Write-Verbose -Message "Could not find an Azure AD Group Eligibility Schedule with {$GroupDisplayName}." return $nullResult } $Id = $getValue.Id - Write-Verbose -Message "An Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName} was found" + Write-Verbose -Message "An Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$GroupDisplayName} was found" #region resource generator code $complexScheduleInfo = @{} @@ -214,13 +217,6 @@ function Get-TargetResource } #endregion - #region resource generator code - $dateModifiedDateTime = $null - if ($null -ne $getValue.ModifiedDateTime) - { - $dateModifiedDateTime = ([DateTimeOffset]$getValue.ModifiedDateTime).ToString('o') - } - #endregion $PrincipalGroup = Get-MgGroup -GroupId $getvalue.PrincipalId if($null -ne $PrincipalGroup){ $PrincipalType = 'group' @@ -240,10 +236,7 @@ function Get-TargetResource MemberType = $enumMemberType PrincipalType = $PrincipalType PrincipalDisplayname = $PrincipalDisplayName - CreatedUsing = $getValue.CreatedUsing - ModifiedDateTime = $dateModifiedDateTime ScheduleInfo = $complexScheduleInfo - Status = $getValue.Status Id = $getValue.Id Ensure = 'Present' Credential = $Credential @@ -369,7 +362,7 @@ function Set-TargetResource if ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Absent') { - Write-Verbose -Message "Creating an Azure AD Group Eligibility Schedule with DisplayName {$DisplayName}" + Write-Verbose -Message "Creating an Azure AD Group Eligibility Schedule for Group {$GroupDisplayName}" $createParameters = ([Hashtable]$BoundParameters).Clone() $createParameters = Rename-M365DSCCimInstanceParameter -Properties $createParameters @@ -377,14 +370,17 @@ function Set-TargetResource $createParameters.Remove('PrincipalType') | Out-Null $createParameters.Remove('PrincipalDisplayName') | Out-Null $createParameters.Remove('GroupDisplayName') | Out-Null + $createParameters.Add('Action', 'adminAssign') - $GroupId = (Get-MgGroup -DisplayName $GroupDisplayName).Id + $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" + $GroupId = (Get-MgGroup -Filter $GroupFilter).Id $createParameters.Add('GroupId', $GroupId) + $Filter = "DisplayName eq '" + $PrincipalDisplayname + "'" if($PrincipalType -eq 'group'){ - $PrincipalId = (Get-MgGroup -DisplayName $PrincipalDisplayName).Id + $PrincipalId = (Get-MgGroup -Filter $Filter).Id } else{ - $PrincipalId = (Get-MgUser -DisplayName $PrincipalDisplayName).Id + $PrincipalId = (Get-MgUser -Filter $Filter).Id } $createParameters.Add('PrincipalId', $PrincipalId) @@ -397,8 +393,7 @@ function Set-TargetResource } } #region resource generator code - $createParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule") - $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -BodyParameter $createParameters + $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $createParameters #endregion } elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') @@ -412,14 +407,17 @@ function Set-TargetResource $updateParameters.Remove('PrincipalType') | Out-Null $updateParameters.Remove('PrincipalDisplayName') | Out-Null $updateParameters.Remove('GroupDisplayName') | Out-Null + $updateParameters.Add('Action', 'adminUpdate') - $GroupId = (Get-MgGroup -DisplayName $GroupDisplayName).Id + $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" + $GroupId = (Get-MgGroup -Filter $GroupFilter).Id $createParameters.Add('GroupId', $GroupId) + $Filter = "DisplayName eq '" + $PrincipalDisplayname + "'" if($PrincipalType -eq 'group'){ - $PrincipalId = (Get-MgGroup -DisplayName $PrincipalDisplayName).Id + $PrincipalId = (Get-MgGroup -Filter $Filter).Id } else{ - $PrincipalId = (Get-MgUser -DisplayName $PrincipalDisplayName).Id + $PrincipalId = (Get-MgUser -Filter $Filter).Id } $updateParameters.Add('PrincipalId', $PrincipalId) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof index 20f21d3701..cbc9a6c4ff 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof @@ -47,8 +47,8 @@ class MSFT_AADGroupEligibilitySchedule : OMI_BaseResource [Key, Description("Dsiaplyname of the group representing the scope of the membership or ownership eligibility through PIM for groups.")] String GroupDisplayName; [Write, Description("Indicates whether the assignment is derived from a group assignment. It can further imply whether the caller can manage the schedule. Required. The possible values are: direct, group, unknownFutureValue. Supports $filter (eq)."), ValueMap{"direct","group","unknownFutureValue"}, Values{"direct","group","unknownFutureValue"}] String MemberType; [Write, Description("The identifier of the principal whose membership or ownership eligibility is granted through PIM for groups. Required. Supports $filter (eq).")] String PrincipalId; - [Write, Description("Principal type user or group"), ValueMap{"user","group"}, Values{"user","group"}] String PrincipalType, - [Write, Description("Displayname of the Principal")], String PrincipalDisplayName, + [Write, Description("Principal type user or group"), ValueMap{"user","group"}, Values{"user","group"}] String PrincipalType; + [Write, Description("Displayname of the Principal")] String PrincipalDisplayName; [Write, Description("Represents the period of the access assignment or eligibility. The scheduleInfo can represent a single occurrence or multiple recurring instances. Required."), EmbeddedInstance("MSFT_MicrosoftGraphrequestSchedule")] String ScheduleInfo; [Write, Description("The unique identifier for an entity. Read-only.")] String Id; [Write, Description("Present ensures the policy exists, absent ensures it is removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] string Ensure; From 02ae0d65a229f76aac3775a1d8e67e0b3a0bba51 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Mon, 6 Jan 2025 18:11:11 +0100 Subject: [PATCH 06/11] wip --- .../MSFT_AADGroupEligibilitySchedule.psm1 | 184 ++++++- ...SFT_AADGroupEligibilitySchedule.schema.mof | 2 +- ...ilitySchedule-Example.ps1 => 1-Create.ps1} | 2 +- .../AADGroupEligibilitySchedule/2-Update.ps1 | 32 ++ ...5DSC.AADGroupEligibilitySchedule.Tests.ps1 | 484 ++++++++---------- Tests/Unit/Stubs/Microsoft365.psm1 | 318 +----------- 6 files changed, 436 insertions(+), 586 deletions(-) rename Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/{1-AADGroupEligibilitySchedule-Example.ps1 => 1-Create.ps1} (95%) create mode 100644 Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/2-Update.ps1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 index 961bf2b5bb..c7515beb3a 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 @@ -217,15 +217,16 @@ function Get-TargetResource } #endregion - $PrincipalGroup = Get-MgGroup -GroupId $getvalue.PrincipalId - if($null -ne $PrincipalGroup){ - $PrincipalType = 'group' - $PrincipalDisplayName = $PrincipalGroup.DisplayName - } - else{ - $PrincipalType = 'user' - $PrincipalDisplayName = (Get-MgUser -UserId $getvalue.PrincipalId).DisplayName + switch ($getValue.PrincipalType) + { + 'group' { + $PrincipalDisplayName = (Get-MgGroup -GroupId $getvalue.PrincipalId).DisplayName + } + 'user' { + $PrincipalDisplayName = (Get-MgUser -UserId $getvalue.PrincipalId).DisplayName + } } + $GroupDisplayName = (Get-MgGroup -GroupId $getvalue.GroupId).DisplayName $results = @{ @@ -341,7 +342,7 @@ function Set-TargetResource $AccessTokens ) - Write-Verbose -Message "Setting configuration of the Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + Write-Verbose -Message "Setting configuration of the Azure AD Group Eligibility Schedule for group {$GroupId} and DisplayName {$GroupDisplayName}" #Ensure the proper dependencies are installed in the current environment. Confirm-M365DSCDependencies @@ -374,6 +375,60 @@ function Set-TargetResource $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" $GroupId = (Get-MgGroup -Filter $GroupFilter).Id + + if($ScheduleInfo.Expiration.Type -eq 'noExpiration'){ + $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $unifiedRoleManagementPolicyId = $p.PolicyId + $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" + $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + if($isExpirationRequired){ + $params = @{ + "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" + id = "Expiration_Admin_Eligibility" + isExpirationRequired = $false + target = @{ + "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" + caller = "Admin" + operations = @( + "All" + ) + level = "Eligibility" + inheritableSettings = @( + ) + enforcedSettings = @( + ) + } + } + Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + } + } + elseif($ScheduleInfo.Expiration.Type -eq 'afterDuration'){ + $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $unifiedRoleManagementPolicyId = $p.PolicyId + $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" + $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + if(-not $isExpirationRequired){ + $params = @{ + "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" + id = "Expiration_Admin_Eligibility" + isExpirationRequired = $true + target = @{ + "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" + caller = "Admin" + operations = @( + "All" + ) + level = "Eligibility" + inheritableSettings = @( + ) + enforcedSettings = @( + ) + } + } + Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + } + } + $createParameters.Add('GroupId', $GroupId) $Filter = "DisplayName eq '" + $PrincipalDisplayname + "'" if($PrincipalType -eq 'group'){ @@ -393,13 +448,21 @@ function Set-TargetResource } } #region resource generator code - $policy = New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $createParameters + New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $createParameters #endregion } elseif ($Ensure -eq 'Present' -and $currentInstance.Ensure -eq 'Present') { Write-Verbose -Message "Updating the Azure AD Group Eligibility Schedule with Id {$($currentInstance.Id)}" + $scheduledStart = $currentInstance.ScheduleInfo.StartDateTime + $scheduledEnd = $currentInstance.ScheduleInfo.Expiration.EndDateTime + if($scheduledStart -ne $ScheduleInfo.StartDateTime -or $scheduledEnd -ne $ScheduleInfo.Expiration.EndDateTime){ + $Action = 'adminExtend' + } + else{ + $Action = 'adminUpdate' + } $updateParameters = ([Hashtable]$BoundParameters).Clone() $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters @@ -407,11 +470,66 @@ function Set-TargetResource $updateParameters.Remove('PrincipalType') | Out-Null $updateParameters.Remove('PrincipalDisplayName') | Out-Null $updateParameters.Remove('GroupDisplayName') | Out-Null - $updateParameters.Add('Action', 'adminUpdate') + $updateParameters.Add('Action', $Action) $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" $GroupId = (Get-MgGroup -Filter $GroupFilter).Id - $createParameters.Add('GroupId', $GroupId) + if($ScheduleInfo.Expiration.Type -eq 'noExpiration'){ + $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $unifiedRoleManagementPolicyId = $p.PolicyId + $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" + $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + if($isExpirationRequired){ + $params = @{ + "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" + id = "Expiration_Admin_Eligibility" + isExpirationRequired = $false + target = @{ + "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" + caller = "Admin" + operations = @( + "All" + ) + level = "Eligibility" + inheritableSettings = @( + ) + enforcedSettings = @( + ) + } + } + Write-Verbose -Message "Updating the expiration policy for the group {$GroupDisplayName}" + Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + } + } + elseif($ScheduleInfo.Expiration.Type -match "^after"){ + $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $unifiedRoleManagementPolicyId = $p.PolicyId + $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" + $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + if(-not $isExpirationRequired){ + $params = @{ + "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" + id = "Expiration_Admin_Eligibility" + isExpirationRequired = $true + maximumDuration = 'P365D' + target = @{ + "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" + caller = "Admin" + operations = @( + "All" + ) + level = "Eligibility" + inheritableSettings = @( + ) + enforcedSettings = @( + ) + } + } + Write-Verbose -Message "Updating the expiration policy for the group {$GroupDisplayName}" + Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + } + } + $updateParameters.Add('GroupId', $GroupId) $Filter = "DisplayName eq '" + $PrincipalDisplayname + "'" if($PrincipalType -eq 'group'){ $PrincipalId = (Get-MgGroup -Filter $Filter).Id @@ -431,17 +549,45 @@ function Set-TargetResource } #region resource generator code - $UpdateParameters.Add("@odata.type", "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule") - Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ` - -PrivilegedAccessGroupEligibilityScheduleId $currentInstance.Id ` - -BodyParameter $UpdateParameters + New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $UpdateParameters #endregion } elseif ($Ensure -eq 'Absent' -and $currentInstance.Ensure -eq 'Present') { - Write-Verbose -Message "Removing the Azure AD Group Eligibility Schedule with Id {$($currentInstance.Id)}" + Write-Verbose -Message "Removiong the Azure AD Group Eligibility Schedule with Id {$($currentInstance.Id)}" + + $updateParameters = ([Hashtable]$BoundParameters).Clone() + $updateParameters = Rename-M365DSCCimInstanceParameter -Properties $updateParameters + + $updateParameters.Remove('Id') | Out-Null + $updateParameters.Remove('PrincipalType') | Out-Null + $updateParameters.Remove('PrincipalDisplayName') | Out-Null + $updateParameters.Remove('GroupDisplayName') | Out-Null + $updateParameters.Add('Action', 'adminRemove') + + $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" + $GroupId = (Get-MgGroup -Filter $GroupFilter).Id + $updateParameters.Add('GroupId', $GroupId) + $Filter = "DisplayName eq '" + $PrincipalDisplayname + "'" + if($PrincipalType -eq 'group'){ + $PrincipalId = (Get-MgGroup -Filter $Filter).Id + } + else{ + $PrincipalId = (Get-MgUser -Filter $Filter).Id + } + $updateParameters.Add('PrincipalId', $PrincipalId) + + $keys = (([Hashtable]$updateParameters).Clone()).Keys + foreach ($key in $keys) + { + if ($null -ne $pdateParameters.$key -and $updateParameters.$key.GetType().Name -like '*CimInstance*') + { + $updateParameters.$key = Convert-M365DSCDRGComplexTypeToHashtable -ComplexObject $updateParameters.PrivilegedAccessGroupEligibilityScheduleId + } + } + #region resource generator code - Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -PrivilegedAccessGroupEligibilityScheduleId $currentInstance.Id + New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -BodyParameter $UpdateParameters #endregion } } @@ -539,7 +685,7 @@ function Test-TargetResource Add-M365DSCTelemetryEvent -Data $data #endregion - Write-Verbose -Message "Testing configuration of the Azure AD Group Eligibility Schedule with Id {$Id} and DisplayName {$DisplayName}" + Write-Verbose -Message "Testing configuration of the Azure AD Group Eligibility Schedule for Group {$GroupId} and DisplayName {$GroupDisplayName}" $CurrentValues = Get-TargetResource @PSBoundParameters $ValuesToCheck = ([Hashtable]$PSBoundParameters).clone() diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof index cbc9a6c4ff..f2c14e3fc2 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.schema.mof @@ -44,7 +44,7 @@ class MSFT_AADGroupEligibilitySchedule : OMI_BaseResource { [Write, Description("The identifier of the membership or ownership eligibility to the group that is governed by PIM. Required. The possible values are: owner, member. Supports $filter (eq)."), ValueMap{"owner","member","unknownFutureValue"}, Values{"owner","member","unknownFutureValue"}] String AccessId; [Write, Description("The identifier of the group representing the scope of the membership or ownership eligibility through PIM for groups. Required. Supports $filter (eq).")] String GroupId; - [Key, Description("Dsiaplyname of the group representing the scope of the membership or ownership eligibility through PIM for groups.")] String GroupDisplayName; + [Key, Description("Displayname of the group representing the scope of the membership or ownership eligibility through PIM for groups.")] String GroupDisplayName; [Write, Description("Indicates whether the assignment is derived from a group assignment. It can further imply whether the caller can manage the schedule. Required. The possible values are: direct, group, unknownFutureValue. Supports $filter (eq)."), ValueMap{"direct","group","unknownFutureValue"}, Values{"direct","group","unknownFutureValue"}] String MemberType; [Write, Description("The identifier of the principal whose membership or ownership eligibility is granted through PIM for groups. Required. Supports $filter (eq).")] String PrincipalId; [Write, Description("Principal type user or group"), ValueMap{"user","group"}, Values{"user","group"}] String PrincipalType; diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-Create.ps1 similarity index 95% rename from Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 rename to Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-Create.ps1 index 41aebfc15d..885b7dc471 100644 --- a/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-AADGroupEligibilitySchedule-Example.ps1 +++ b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/1-Create.ps1 @@ -26,7 +26,7 @@ Configuration Example StartDateTime = '2024-12-23T08:59:28.1200000+00:00' Expiration = MSFT_MicrosoftGraphExpirationPattern{ EndDateTime = '12/23/2025 8:59:00 AM +00:00' - Type = 'notSpecified' + Type = 'afterDateTime' } }; } diff --git a/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/2-Update.ps1 b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/2-Update.ps1 new file mode 100644 index 0000000000..d33e380248 --- /dev/null +++ b/Modules/Microsoft365DSC/Examples/Resources/AADGroupEligibilitySchedule/2-Update.ps1 @@ -0,0 +1,32 @@ +<# +This example is used to test new resources and showcase the usage of new resources being worked on. +It is not meant to use as a production baseline. +#> + +Configuration Example +{ + param( + [Parameter(Mandatory = $true)] + [PSCredential] + $Credscredential + ) + Import-DscResource -ModuleName Microsoft365DSC + + node localhost + { + AADGroupEligibilitySchedule 'Example' + { + AccessId = "member"; + Ensure = "Present"; + GroupDisplayName = "MyPIMGroup"; + MemberType = "direct"; + PrincipalDisplayname = "MyPrincipalGroup"; + PrincipalType = "group"; + ScheduleInfo = MSFT_MicrosoftGraphrequestSchedule{ + Expiration = MSFT_MicrosoftGraphExpirationPattern{ + Type = 'noExpiration' + } + }; + } + } +} diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 index 5218b42c8f..7a7f3a3cf0 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 @@ -39,19 +39,25 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Remove-PSSession -MockWith { } - Mock -CommandName Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + Mock -CommandName New-M365DSCConnection -MockWith { + return "Credentials" } - Mock -CommandName New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + Mock -CommandName Get-MgPolicyRoleManagementPolicyAssignment -MockWith { + return @( + @{ + PolicyIdId = 'FakeId' + } + ) } - Mock -CommandName Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + Mock -CommandName Get-MgPolicyRoleManagementPolicyRule -MockWith { + return @() } - Mock -CommandName New-M365DSCConnection -MockWith { - return "Credentials" + Mock -CommandName Update-MgPolicyRoleManagementPolicyRule -MockWith { + return @() } - # Mock Write-Host to hide output during the tests Mock -CommandName Write-Host -MockWith { } @@ -63,39 +69,16 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "The AADGroupEligibilitySchedule should exist but it DOES NOT" -Fixture { BeforeAll { $testParams = @{ - AccessId = "owner" - CreatedUsing = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" + AccessId = "member" + GroupDisplayName = "FakeStringValue" MemberType = "direct" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - PrincipalId = "FakeStringValue" - ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 + PrincipalDisplayName = "FakePrincipal" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) - Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" - } -ClientOnly) - } -ClientOnly) - Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } -ClientOnly) - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" Ensure = "Present" Credential = $Credential; } @@ -103,6 +86,10 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return $null } + + Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return $null + } } It 'Should return Values from the Get method' { (Get-TargetResource @testParams).Ensure | Should -Be 'Absent' @@ -112,91 +99,69 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } It 'Should Create the group from the Set method' { Set-TargetResource @testParams - Should -Invoke -CommandName New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + Should -Invoke -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 } } Context -Name "The AADGroupEligibilitySchedule exists but it SHOULD NOT" -Fixture { BeforeAll { $testParams = @{ - AccessId = "owner" - CreatedUsing = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" + AccessId = "member" + GroupDisplayName = "FakeStringValue" MemberType = "direct" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - PrincipalId = "FakeStringValue" - ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 - } -ClientOnly) - Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" + PrincipalDisplayName = "FakePrincipal" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) - } -ClientOnly) - Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } -ClientOnly) - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - Ensure = 'Absent' + Ensure = "Absent" Credential = $Credential; } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return @{ - AdditionalProperties = @{ - groupId = "FakeStringValue" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" - principalId = "FakeStringValue" - memberType = "direct" - accessId = "owner" - } - CreatedUsing = "FakeStringValue" - Id = "FakeStringValue" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - ScheduleInfo = @{ - Recurrence = @{ - Pattern = @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 - } - Range = @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @( + @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' } } - Expiration = @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - Status = "FakeStringValue" + ) + } + } + Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return $null + } + + Mock -CommandName Invoke-GraphRequest -MockWith { + return @{ + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @( + @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' + } + } + ) } } + Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return $null + } } It 'Should return Values from the Get method' { @@ -209,91 +174,92 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { It 'Should Remove the group from the Set method' { Set-TargetResource @testParams - Should -Invoke -CommandName Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + Should -Invoke -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 } } Context -Name "The AADGroupEligibilitySchedule Exists and Values are already in the desired state" -Fixture { BeforeAll { $testParams = @{ - AccessId = "owner" - CreatedUsing = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" + AccessId = "member" + GroupDisplayName = "FakeStringValue" MemberType = "direct" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - PrincipalId = "FakeStringValue" - ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 + PrincipalDisplayName = "FakePrincipal" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) - Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" - } -ClientOnly) - } -ClientOnly) - Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } -ClientOnly) - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - Ensure = 'Present' + Ensure = "Present" Credential = $Credential; } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return @{ - AdditionalProperties = @{ - groupId = "FakeStringValue" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" - principalId = "FakeStringValue" - memberType = "direct" - accessId = "owner" - } - CreatedUsing = "FakeStringValue" - Id = "FakeStringValue" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - ScheduleInfo = @{ - Recurrence = @{ - Pattern = @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 - } - Range = @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @( + @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' } } - Expiration = @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + ) + } + } + + mock -CommandName Get-MgGroup -MockWith { + return @{ + Id = 'FakeId' + DisplayName = 'FakeStringValue' + } + } + + Mock -CommandName Invoke-GraphRequest -MockWith { + return @{ + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' + } + } + } + } + + Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return $null + } + + Mock -CommandName Get-MgPolicyRoleManagementPolicyAssignment -MockWith { + return @( + @{ + PolicyId = 'FakeId' } - Status = "FakeStringValue" + ) + } + Mock -CommandName Get-MgPolicyRoleManagementPolicyRule -MockWith { + return @{ + AdditionalProperties = @{ + isExpirationRequired = $true + } } } + + Mock -CommandName Update-MgPolicyRoleManagementPolicyRule -MockWith { + return @() + } + } It 'Should return true from the Test method' { @@ -304,82 +270,84 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Context -Name "The AADGroupEligibilitySchedule exists and values are NOT in the desired state" -Fixture { BeforeAll { $testParams = @{ - AccessId = "owner" - CreatedUsing = "FakeStringValue" - GroupId = "FakeStringValue" - Id = "FakeStringValue" + AccessId = "member" + GroupDisplayName = "FakeStringValue" MemberType = "direct" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - PrincipalId = "FakeStringValue" - ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphrequestSchedule -Property @{ - Recurrence = (New-CimInstance -ClassName MSFT_MicrosoftGraphpatternedRecurrence1 -Property @{ - Pattern = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrencePattern1 -Property @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 - } -ClientOnly) - Range = (New-CimInstance -ClassName MSFT_MicrosoftGraphrecurrenceRange1 -Property @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" + PrincipalDisplayName = "FakePrincipal" + ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) - } -ClientOnly) - Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphexpirationPattern -Property @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } -ClientOnly) - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } -ClientOnly) - Status = "FakeStringValue" - Ensure = 'Present' + Ensure = "Present" Credential = $Credential; } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return @{ - AdditionalProperties = @{ - principalId = "FakeStringValue" - groupId = "FakeStringValue" - memberType = "direct" - accessId = "owner" - } - CreatedUsing = "FakeStringValue" - Id = "FakeStringValue" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - ScheduleInfo = @{ - Recurrence = @{ - Pattern = @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 7 - Month = 7 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 7 - } - Range = @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 7 - Type = "endDate" + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @( + @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/24/2025 8:59:00 AM +00:00' + type = 'afterDateTime' } } - Expiration = @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" + ) + } + } + + mock -CommandName Get-MgGroup -MockWith { + return @{ + Id = 'FakeId' + DisplayName = 'FakeStringValue' + } + } + + Mock -CommandName Invoke-GraphRequest -MockWith { + return @{ + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' + } + } + } + } + + Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { + return $null + } + + Mock -CommandName Get-MgPolicyRoleManagementPolicyAssignment -MockWith { + return @( + @{ + PolicyId = 'FakeId' + } + ) + } + + Mock -CommandName Get-MgPolicyRoleManagementPolicyRule -MockWith { + return @{ + AdditionalProperties = @{ + isExpirationRequired = $true } - Status = "FakeStringValue" } } + + Mock -CommandName Update-MgPolicyRoleManagementPolicyRule -MockWith { + return @() + } } It 'Should return Values from the Get method' { @@ -392,7 +360,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { It 'Should call the Set method' { Set-TargetResource @testParams - Should -Invoke -CommandName Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -Exactly 1 + Should -Invoke -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -Exactly 1 } } @@ -406,43 +374,19 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return @{ - AdditionalProperties = @{ - groupId = "FakeStringValue" - '@odata.type' = "#microsoft.graph.PrivilegedAccessGroupEligibilitySchedule" - principalId = "FakeStringValue" - memberType = "direct" - accessId = "owner" - } - CreatedUsing = "FakeStringValue" - Id = "FakeStringValue" - ModifiedDateTime = "2023-01-01T00:00:00.0000000+01:00" - ScheduleInfo = @{ - Recurrence = @{ - Pattern = @{ - Index = "first" - FirstDayOfWeek = "sunday" - DayOfMonth = 25 - Month = 25 - DaysOfWeek = @("sunday") - Type = "daily" - Interval = 25 - } - Range = @{ - StartDate = "2023-01-01T00:00:00.0000000" - EndDate = "2023-01-01T00:00:00.0000000" - RecurrenceTimeZone = "FakeStringValue" - NumberOfOccurrences = 25 - Type = "endDate" + AccessId = 'member' + GroupDisplayName = 'FakeStringValue' + MemberType = 'direct' + PrincipalDisplayName = 'FakePrincipal' + ScheduleInfo = @( + @{ + StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + Expiration = @{ + EndDateTime = '12/23/2025 8:59:00 AM +00:00' + type = 'afterDateTime' } } - Expiration = @{ - EndDateTime = "2023-01-01T00:00:00.0000000+01:00" - Type = "notSpecified" - } - StartDateTime = "2023-01-01T00:00:00.0000000+01:00" - } - Status = "FakeStringValue" - + ) } } } diff --git a/Tests/Unit/Stubs/Microsoft365.psm1 b/Tests/Unit/Stubs/Microsoft365.psm1 index 52a425eff2..fae2f3e556 100644 --- a/Tests/Unit/Stubs/Microsoft365.psm1 +++ b/Tests/Unit/Stubs/Microsoft365.psm1 @@ -105439,15 +105439,15 @@ function Update-MgDeviceManagementDeviceConfigurationAssignment #endregion -#region MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +#region MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule { [CmdletBinding()] param ( [Parameter()] [System.String] - $PrivilegedAccessGroupEligibilityScheduleRequestId, + $PrivilegedAccessGroupEligibilityScheduleId, [Parameter()] [PSObject] @@ -105527,7 +105527,7 @@ function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ) } -function New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +function New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest { [CmdletBinding()] param @@ -105654,127 +105654,18 @@ function New-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest ) } -function Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest +function Get-MgPolicyRoleManagementPolicyAssignment { [CmdletBinding()] param ( [Parameter()] [System.String] - $PrivilegedAccessGroupEligibilityScheduleRequestId, - - [Parameter()] - [PSObject] - $InputObject, + $PolicyAssignmentId, [Parameter()] [System.String] - $ResponseHeadersVariable, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Break, - - [Parameter()] - [System.Collections.IDictionary] - $Headers, - - [Parameter()] - [PSObject[]] - $HttpPipelineAppend, - - [Parameter()] - [PSObject[]] - $HttpPipelinePrepend, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $PassThru, - - [Parameter()] - [System.Uri] - $Proxy, - - [Parameter()] - [System.Management.Automation.PSCredential] - $ProxyCredential, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ProxyUseDefaultCredentials, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm - ) -} - -function Stop-MgIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -{ - [CmdletBinding()] - param - ( - [Parameter()] - [System.String] - $PrivilegedAccessGroupEligibilityScheduleRequestId, - - [Parameter()] - [PSObject] - $InputObject, - - [Parameter()] - [System.String] - $ResponseHeadersVariable, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Break, - - [Parameter()] - [System.Collections.IDictionary] - $Headers, - - [Parameter()] - [PSObject[]] - $HttpPipelineAppend, - - [Parameter()] - [PSObject[]] - $HttpPipelinePrepend, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $PassThru, - - [Parameter()] - [System.Uri] - $Proxy, - - [Parameter()] - [System.Management.Automation.PSCredential] - $ProxyCredential, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ProxyUseDefaultCredentials, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm - ) -} - -#endregion - -#region MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -{ - [CmdletBinding()] - param - ( - [Parameter()] - [System.String] - $PrivilegedAccessGroupEligibilityScheduleId, + $PolicyId, [Parameter()] [PSObject] @@ -105854,168 +105745,14 @@ function Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule ) } -function New-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -{ - [CmdletBinding()] - param - ( - [Parameter()] - [PSObject] - $BodyParameter, - - [Parameter()] - [System.String] - $ResponseHeadersVariable, - - [Parameter()] - [System.String] - $AccessId, - - [Parameter()] - [System.Collections.Hashtable] - $AdditionalProperties, - - [Parameter()] - [System.DateTime] - $CreatedDateTime, - - [Parameter()] - [System.String] - $CreatedUsing, - - [Parameter()] - [PSObject] - $Group, - - [Parameter()] - [System.String] - $GroupId, - - [Parameter()] - [System.String] - $Id, - - [Parameter()] - [System.String] - $MemberType, - - [Parameter()] - [System.DateTime] - $ModifiedDateTime, - - [Parameter()] - [PSObject] - $Principal, - - [Parameter()] - [System.String] - $PrincipalId, - - [Parameter()] - [PSObject] - $ScheduleInfo, - - [Parameter()] - [System.String] - $Status, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Break, - - [Parameter()] - [System.Collections.IDictionary] - $Headers, - - [Parameter()] - [PSObject[]] - $HttpPipelineAppend, - - [Parameter()] - [PSObject[]] - $HttpPipelinePrepend, - - [Parameter()] - [System.Uri] - $Proxy, - - [Parameter()] - [System.Management.Automation.PSCredential] - $ProxyCredential, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ProxyUseDefaultCredentials, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm - ) -} - -function Remove-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule +function Update-MgPolicyRoleManagementPolicyRule { [CmdletBinding()] param ( [Parameter()] [System.String] - $PrivilegedAccessGroupEligibilityScheduleId, - - [Parameter()] - [PSObject] - $InputObject, - - [Parameter()] - [System.String] - $ResponseHeadersVariable, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Break, - - [Parameter()] - [System.Collections.IDictionary] - $Headers, - - [Parameter()] - [PSObject[]] - $HttpPipelineAppend, - - [Parameter()] - [PSObject[]] - $HttpPipelinePrepend, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $PassThru, - - [Parameter()] - [System.Uri] - $Proxy, - - [Parameter()] - [System.Management.Automation.PSCredential] - $ProxyCredential, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $ProxyUseDefaultCredentials, - - [Parameter()] - [System.Management.Automation.SwitchParameter] - $Confirm - ) -} - -function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -{ - [CmdletBinding()] - param - ( - [Parameter()] - [System.String] - $PrivilegedAccessGroupEligibilityScheduleId, + $PolicyRuleId, [Parameter()] [PSObject] @@ -106029,57 +105766,49 @@ function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule [System.String] $ResponseHeadersVariable, - [Parameter()] - [System.String] - $AccessId, - [Parameter()] [System.Collections.Hashtable] $AdditionalProperties, - [Parameter()] - [System.DateTime] - $CreatedDateTime, - [Parameter()] [System.String] - $CreatedUsing, + $Id, [Parameter()] - [PSObject] - $Group, + [System.String] + $Name, [Parameter()] [System.String] - $GroupId, + $PolicyId, [Parameter()] [System.String] - $Id, + $PolicyRuleType, [Parameter()] [System.String] - $MemberType, + $PolicyType, [Parameter()] - [System.DateTime] - $ModifiedDateTime, + [System.String] + $Priority, [Parameter()] - [PSObject] - $Principal, + [System.String] + $RuleType, [Parameter()] [System.String] - $PrincipalId, + $Status, [Parameter()] - [PSObject] - $ScheduleInfo, + [System.String] + $TargetType, [Parameter()] [System.String] - $Status, + $TargetValue, [Parameter()] [System.Management.Automation.SwitchParameter] @@ -106114,6 +105843,5 @@ function Update-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule $Confirm ) } - #endregion From ff3e577153a3b3671b3e6d0fbab8050320f3a525 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Wed, 8 Jan 2025 11:04:56 +0100 Subject: [PATCH 07/11] wip --- ...5DSC.AADGroupEligibilitySchedule.Tests.ps1 | 110 ++++++------------ 1 file changed, 33 insertions(+), 77 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 index 7a7f3a3cf0..2c17b67fc2 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 @@ -74,9 +74,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = "direct" PrincipalDisplayName = "FakePrincipal" ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + startDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '23/12/2025 08:59:00 +00:00' Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) Ensure = "Present" @@ -111,9 +111,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = "direct" PrincipalDisplayName = "FakePrincipal" ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + startDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '23/12/2025 08:59:00 +00:00' Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) Ensure = "Absent" @@ -121,20 +121,13 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { + return $null + } + + mock -CommandName Get-MgGroup -MockWith { return @{ - AccessId = 'member' - GroupDisplayName = 'FakeStringValue' - MemberType = 'direct' - PrincipalDisplayName = 'FakePrincipal' - ScheduleInfo = @( - @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' - Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' - type = 'afterDateTime' - } - } - ) + Id = 'FakeId' + DisplayName = 'FakeStringValue' } } @@ -148,20 +141,16 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { GroupDisplayName = 'FakeStringValue' MemberType = 'direct' PrincipalDisplayName = 'FakePrincipal' - ScheduleInfo = @( - @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + ScheduleInfo = @{ + StartDateTime = '2025-01-23T08:59:00.000Z' Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '2025-12-23T08:59:00.000Z' type = 'afterDateTime' } - } - ) + } } } - Mock -CommandName New-MgBetaIdentityGovernancePrivilegedAccessGroupEligibilityScheduleRequest -MockWith { - return $null - } + } It 'Should return Values from the Get method' { @@ -186,9 +175,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = "direct" PrincipalDisplayName = "FakePrincipal" ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + startDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '23/12/2025 08:59:00 +00:00' Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) Ensure = "Present" @@ -196,21 +185,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { - return @{ - AccessId = 'member' - GroupDisplayName = 'FakeStringValue' - MemberType = 'direct' - PrincipalDisplayName = 'FakePrincipal' - ScheduleInfo = @( - @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' - Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' - type = 'afterDateTime' - } - } - ) - } + return $null } mock -CommandName Get-MgGroup -MockWith { @@ -227,9 +202,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = 'direct' PrincipalDisplayName = 'FakePrincipal' ScheduleInfo = @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + StartDateTime = '2025-01-23T08:59:00.000Z' Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '2025-12-23T08:59:00.000Z' type = 'afterDateTime' } } @@ -275,9 +250,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = "direct" PrincipalDisplayName = "FakePrincipal" ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + startDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '23/12/2025 08:59:00 +00:00' Type = 'afterDateTime'} -ClientOnly) } -ClientOnly) Ensure = "Present" @@ -285,21 +260,7 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { } Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { - return @{ - AccessId = 'member' - GroupDisplayName = 'FakeStringValue' - MemberType = 'direct' - PrincipalDisplayName = 'FakePrincipal' - ScheduleInfo = @( - @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' - Expiration = @{ - EndDateTime = '12/24/2025 8:59:00 AM +00:00' - type = 'afterDateTime' - } - } - ) - } + return $null } mock -CommandName Get-MgGroup -MockWith { @@ -316,9 +277,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = 'direct' PrincipalDisplayName = 'FakePrincipal' ScheduleInfo = @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' + StartDateTime = '2025-01-23T08:59:00.000Z' Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' + EndDateTime = '2025-12-22T08:59:00.000Z' type = 'afterDateTime' } } @@ -372,21 +333,16 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { Credential = $Credential } + mock -CommandName Get-MgGroup -MockWith { + return @{ + Id = 'FakeId' + DisplayName = 'FakeStringValue' + } + } + Mock -CommandName Get-MgIdentityGovernancePrivilegedAccessGroupEligibilitySchedule -MockWith { return @{ - AccessId = 'member' - GroupDisplayName = 'FakeStringValue' - MemberType = 'direct' - PrincipalDisplayName = 'FakePrincipal' - ScheduleInfo = @( - @{ - StartDateTime = '2025-01-23T08:59:28.1200000+00:00' - Expiration = @{ - EndDateTime = '12/23/2025 8:59:00 AM +00:00' - type = 'afterDateTime' - } - } - ) + Id = 'FakeStringValue' } } } From de963027bf321b816a70d08d4e8d89970aaf6034 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Wed, 8 Jan 2025 11:12:51 +0100 Subject: [PATCH 08/11] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 347bee63d0..547f483cb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * AADAuthenticationRequirement * Changed Export logic to extract instances from all users. +* AADGroupEligibilitySchedule + * New resource for Privileged Identity Management (PIM) for Groups * AADOrganizationCertificateBasedAuthConfiguration * Fixed the primary key of the resource. FIXES [#5523](https://github.com/microsoft/Microsoft365DSC/issues/5523) From 45ad5530ef10fe9b39ab475f510b5284fc0c2f42 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Wed, 8 Jan 2025 12:17:06 +0100 Subject: [PATCH 09/11] update ti beta module --- .../MSFT_AADGroupEligibilitySchedule.psm1 | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 index c7515beb3a..b827841667 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADGroupEligibilitySchedule/MSFT_AADGroupEligibilitySchedule.psm1 @@ -377,17 +377,16 @@ function Set-TargetResource $GroupId = (Get-MgGroup -Filter $GroupFilter).Id if($ScheduleInfo.Expiration.Type -eq 'noExpiration'){ - $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $p = Get-MgBetaPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) $unifiedRoleManagementPolicyId = $p.PolicyId $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" - $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + $isExpirationRequired = (Get-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired if($isExpirationRequired){ $params = @{ "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" id = "Expiration_Admin_Eligibility" isExpirationRequired = $false target = @{ - "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" caller = "Admin" operations = @( "All" @@ -399,21 +398,21 @@ function Set-TargetResource ) } } - Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + Update-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params } } - elseif($ScheduleInfo.Expiration.Type -eq 'afterDuration'){ - $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + elseif($ScheduleInfo.Expiration.Type -match "^after"){ + $p = Get-MgBetaPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) $unifiedRoleManagementPolicyId = $p.PolicyId $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" - $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + $isExpirationRequired = (Get-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired if(-not $isExpirationRequired){ $params = @{ "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" id = "Expiration_Admin_Eligibility" isExpirationRequired = $true + maximumDuration = 'P365D' target = @{ - "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" caller = "Admin" operations = @( "All" @@ -425,7 +424,7 @@ function Set-TargetResource ) } } - Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + Update-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params } } @@ -475,17 +474,16 @@ function Set-TargetResource $GroupFilter = "DisplayName eq '" + $GroupDisplayName + "'" $GroupId = (Get-MgGroup -Filter $GroupFilter).Id if($ScheduleInfo.Expiration.Type -eq 'noExpiration'){ - $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $p = Get-MgBetaPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) $unifiedRoleManagementPolicyId = $p.PolicyId $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" - $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + $isExpirationRequired = (Get-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired if($isExpirationRequired){ $params = @{ "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" id = "Expiration_Admin_Eligibility" isExpirationRequired = $false target = @{ - "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" caller = "Admin" operations = @( "All" @@ -498,14 +496,14 @@ function Set-TargetResource } } Write-Verbose -Message "Updating the expiration policy for the group {$GroupDisplayName}" - Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + Update-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params } } elseif($ScheduleInfo.Expiration.Type -match "^after"){ - $p = Get-MgPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) + $p = Get-MgBetaPolicyRoleManagementPolicyAssignment -Filter $("scopeId eq '{0}' and scopeType eq 'Group' and RoleDefinitionId eq 'member'" -f $GroupId) $unifiedRoleManagementPolicyId = $p.PolicyId $unifiedRoleManagementPolicyRuleId = "Expiration_Admin_Eligibility" - $isExpirationRequired = (Get-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired + $isExpirationRequired = (Get-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId).AdditionalProperties.isExpirationRequired if(-not $isExpirationRequired){ $params = @{ "@odata.type" = "#microsoft.graph.unifiedRoleManagementPolicyExpirationRule" @@ -513,7 +511,6 @@ function Set-TargetResource isExpirationRequired = $true maximumDuration = 'P365D' target = @{ - "@odata.type" = "microsoft.graph.unifiedRoleManagementPolicyRuleTarget" caller = "Admin" operations = @( "All" @@ -526,7 +523,7 @@ function Set-TargetResource } } Write-Verbose -Message "Updating the expiration policy for the group {$GroupDisplayName}" - Update-MgPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params + Update-MgBetaPolicyRoleManagementPolicyRule -UnifiedRoleManagementPolicyId $unifiedRoleManagementPolicyId -UnifiedRoleManagementPolicyRuleId $unifiedRoleManagementPolicyRuleId -BodyParameter $params } } $updateParameters.Add('GroupId', $GroupId) From 3b178ba4351ae465b0cbe40b9592203c307da6c5 Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Wed, 8 Jan 2025 12:19:40 +0100 Subject: [PATCH 10/11] update test --- .../Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 index 2c17b67fc2..48ad2f749c 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 @@ -202,9 +202,9 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = 'direct' PrincipalDisplayName = 'FakePrincipal' ScheduleInfo = @{ - StartDateTime = '2025-01-23T08:59:00.000Z' + StartDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = @{ - EndDateTime = '2025-12-23T08:59:00.000Z' + EndDateTime = '2025-12-23T08:59:00.0000000+00:00' type = 'afterDateTime' } } From 476c6b69b68b51168fcb42acfe6a879a73727e1e Mon Sep 17 00:00:00 2001 From: Sandro Lanfranchi Date: Wed, 8 Jan 2025 12:41:16 +0100 Subject: [PATCH 11/11] fix Test --- .../Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 index 48ad2f749c..d021389b2d 100644 --- a/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 +++ b/Tests/Unit/Microsoft365DSC/Microsoft365DSC.AADGroupEligibilitySchedule.Tests.ps1 @@ -175,10 +175,8 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = "direct" PrincipalDisplayName = "FakePrincipal" ScheduleInfo = (New-CimInstance -ClassName MSFT_MicrosoftGraphRequestSchedule -Property @{ - startDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = (New-CimInstance -ClassName MSFT_MicrosoftGraphExpirationPattern -Property @{ - EndDateTime = '23/12/2025 08:59:00 +00:00' - Type = 'afterDateTime'} -ClientOnly) + Type = 'noExpiration'} -ClientOnly) } -ClientOnly) Ensure = "Present" Credential = $Credential; @@ -202,10 +200,8 @@ Describe -Name $Global:DscHelper.DescribeHeader -Fixture { MemberType = 'direct' PrincipalDisplayName = 'FakePrincipal' ScheduleInfo = @{ - StartDateTime = '2025-01-23T08:59:00.0000000+00:00' Expiration = @{ - EndDateTime = '2025-12-23T08:59:00.0000000+00:00' - type = 'afterDateTime' + type = 'noExpiration' } } }