diff --git a/CHANGELOG.md b/CHANGELOG.md index 23d6f42b50..cfa0cce035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # UNRELEASED +* AADApplication + * Added support for Oauth2PermissionScopes. * TeamsMeetingPolicy * FIXES [#5550](https://github.com/microsoft/Microsoft365DSC/issues/5550) * MISC @@ -9,6 +11,9 @@ * M365DSCUtil * Update `Get-M365DSCWorkloadsListFromResourceNames` function for more input types. FIXES [#5525](https://github.com/microsoft/Microsoft365DSC/issues/5525) +* DEPENDENCIES + * Updated Microsoft.PowerApps.Administration.PowerShell to version 2.0.202. + * Updated ReverseDSC to version 2.0.0.23. # 1.24.1211.1 diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 index 069acb9eb3..72953ed80b 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.psm1 @@ -275,7 +275,24 @@ function Get-TargetResource $complexPreAuthorizedApplications += $myPreAuthorizedApplications } } + + $complexOAuth2Scopes = @() + foreach ($currentOAuth2Scope in $AADApp.api.Oauth2PermissionScopes) + { + $complexOAuth2Scopes += @{ + adminConsentDescription = $currentOAuth2Scope.adminConsentDescription + adminConsentDisplayName = $currentOAuth2Scope.adminConsentDisplayName + id = $currentOAuth2Scope.id + isEnabled = $currentOAuth2Scope.isEnabled + type = $currentOAuth2Scope.type + userConsentDescription = $currentOAuth2Scope.userConsentDescription + userConsentDisplayName = $currentOAuth2Scope.userConsentDisplayName + value = $currentOAuth2Scope.value + } + } + $complexApi.Add('PreAuthorizedApplications', $complexPreAuthorizedApplications) + $complexApi.Add('Oauth2PermissionScopes', $complexOAuth2Scopes) if ($complexApi.values.Where({ $null -ne $_ }).Count -eq 0) { $complexApi = $null @@ -736,18 +753,56 @@ function Set-TargetResource } $currentParameters.Remove('AvailableToOtherTenants') | Out-Null $currentParameters.Remove('PublicClient') | Out-Null + $currentParameters.Remove('Verbose') | Out-Null - if ($currentParameters.KnownClientApplications) + #region API + $apiValue = @{} + if ($currentParameters.Api.KnownClientApplications) + { + $apiValue.Add('KnownClientApplications', $currentParameters.Api.KnownClientApplications) + } + if ($currentParameters.Api.Oauth2PermissionScopes) { - $apiValue = @{ - KnownClientApplications = $currentParameters.KnownClientApplications + Write-Verbose -Message "Oauth2PermissionScopes specified and is not empty" + $scopeValue = @() + foreach ($scope in $currentParameters.Api.Oauth2PermissionScopes) + { + $scopeEntry = @{ + adminConsentDescription = $scope.adminConsentDescription + adminConsentDisplayName = $scope.adminConsentDisplayName + isEnabled = $scope.isEnabled + type = $scope.type + userConsentDescription = $scope.userConsentDescription + userConsentDisplayName = $scope.userConsentDisplayName + value = $scope.value + } + if (-not [System.String]::IsNullOrEmpty($scope.id)) + { + Write-Verbose -Message "Adding existing scope id {$($scope.id)}" + $scopeEntry.Add('id', $scope.id) + } + else + { + Write-Verbose -Message "Generating new scope id" + $scopeEntry.Add('id', (New-Guid).ToString()) + } + + $scopeValue += $scopeEntry } - $currentParameters.Add('Api', $apiValue) - $currentParameters.Remove('KnownClientApplications') | Out-Null + $apiValue.Add('Oauth2PermissionScopes', $scopeValue) + } + $currentParameters.Remove('KnownClientApplications') | Out-Null + #endregion + + if ($currentParameters.ContainsKey('Api')) + { + Write-Verbose "Found existing API parameter. Updating with $(Convert-M365DscHashtableToString -Hashtable $apiValue)" + $currentParameters.Api = $apiValue } else { - $currentParameters.Remove('KnownClientApplications') | Out-Null + Write-Verbose "Adding API parameter with $(Convert-M365DscHashtableToString -Hashtable $apiValue)" + $currentParameters.Add('Api', $apiValue) } if ($ReplyUrls -or $LogoutURL -or $Homepage) @@ -774,7 +829,6 @@ function Set-TargetResource $currentParameters.Remove('Homepage') | Out-Null $currentParameters.Remove('OnPremisesPublishing') | Out-Null - $keys = (([Hashtable]$currentParameters).clone()).Keys foreach ($key in $keys) { @@ -859,6 +913,7 @@ function Set-TargetResource $currentParameters.Remove('ApplicationTemplateId') | Out-Null Write-Verbose -Message "Creating New AzureAD Application {$DisplayName} with values:`r`n$($currentParameters | Out-String)" + Write-Verbose -Message "Parameters with API: $(ConvertTo-Json $currentParameters -Depth 10)" $currentAADApp = New-MgApplication @currentParameters Write-Verbose -Message "Azure AD Application {$DisplayName} was successfully created" $needToUpdatePermissions = $true @@ -1043,7 +1098,7 @@ function Set-TargetResource $allRequiredAccess = @() } else - { + { $allSourceAPIs = $Permissions.SourceAPI | Select-Object -Unique $allRequiredAccess = @() @@ -1570,6 +1625,11 @@ function Export-TargetResource CimInstanceName = 'MicrosoftGraphPreAuthorizedApplication' IsRequired = $False } + @{ + Name = 'Oauth2PermissionScopes' + CimInstanceName = 'MSFT_MicrosoftGraphApiOauth2PermissionScopes' + IsRequired = $False + } ) $complexTypeStringResult = Get-M365DSCDRGComplexTypeToString ` -ComplexObject $Results.Api ` diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.schema.mof b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.schema.mof index 21e278cc40..d64409ef93 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.schema.mof +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_AADApplication/MSFT_AADApplication.schema.mof @@ -82,10 +82,26 @@ class MSFT_MicrosoftGraphPreAuthorizedApplication [Write, Description("The unique identifier for the scopes the client application is granted.")] String PermissionIds[]; }; +[ClassVersion("1.0.0")] +class MSFT_MicrosoftGraphApiOauth2PermissionScopes +{ + [Write, Description("A description of the delegated permissions, intended to be read by an administrator granting the permission on behalf of all users. This text appears in tenant-wide admin consent experiences.")] String adminConsentDescription; + [Write, Description("The permission's title, intended to be read by an administrator granting the permission on behalf of all users.")] String adminConsentDisplayName; + [Write, Description("A description of the delegated permissions, intended to be read by a user granting the permission on their own behalf. This text appears in consent experiences where the user is consenting only on behalf of themselves.")] String userConsentDescription; + [Write, Description("A title for the permission, intended to be read by a user granting the permission on their own behalf. This text appears in consent experiences where the user is consenting only on behalf of themselves.")] String userConsentDisplayName; + [Write, Description("Specifies the value to include in the scp (scope) claim in access tokens. Must not exceed 120 characters in length.")] String value; + [Write, Description("When you create or update a permission, this property must be set to true (which is the default). To delete a permission, this property must first be set to false. At that point, in a subsequent call, the permission may be removed.")] Boolean isEnabled; + [Write, Description("The possible values are: User and Admin. Specifies whether this delegated permission should be considered safe for non-admin users to consent to on behalf of themselves, or whether an administrator consent should always be required.")] String type; + [Write, Description("Unique delegated permission identifier inside the collection of delegated permissions defined for a resource application.")] String id; + +}; + [ClassVersion("1.0.0")] class MSFT_MicrosoftGraphApiApplication { [Write, Description("Lists the client applications that are preauthorized with the specified delegated permissions to access this application's APIs. Users aren't required to consent to any preauthorized application (for the permissions specified). However, any other permissions not listed in preAuthorizedApplications (requested through incremental consent for example) will require user consent."), EmbeddedInstance("MSFT_MicrosoftGraphPreAuthorizedApplication")] String PreAuthorizedApplications[]; + [Write, Description("List of associated API scopes."), EmbeddedInstance("MSFT_MicrosoftGraphAPIOauth2PermissionScopes")] String Oauth2PermissionScopes[]; + }; [ClassVersion("1.0.0")] diff --git a/Modules/Microsoft365DSC/DSCResources/MSFT_PPPowerAppPolicyUrlPatterns/MSFT_PPPowerAppPolicyUrlPatterns.psm1 b/Modules/Microsoft365DSC/DSCResources/MSFT_PPPowerAppPolicyUrlPatterns/MSFT_PPPowerAppPolicyUrlPatterns.psm1 index 602805cb67..75ee6a2896 100644 --- a/Modules/Microsoft365DSC/DSCResources/MSFT_PPPowerAppPolicyUrlPatterns/MSFT_PPPowerAppPolicyUrlPatterns.psm1 +++ b/Modules/Microsoft365DSC/DSCResources/MSFT_PPPowerAppPolicyUrlPatterns/MSFT_PPPowerAppPolicyUrlPatterns.psm1 @@ -173,9 +173,6 @@ function Set-TargetResource Add-M365DSCTelemetryEvent -Data $data #endregion - $policy = Get-AdminDlpPolicy | Where-Object -FilterScript { $_.DisplayName -eq $PolicyName } - $policyNameValue = $policy.PolicyName - # CREATE if ($Ensure -eq 'Present') { @@ -192,10 +189,10 @@ function Set-TargetResource } } $payload = $(ConvertTo-Json $body -Depth 9 -Compress) - Write-Verbose -Message "Setting new Url Patterns for Policy {$($PolicyNameValue)} with parameters:`r`n$payload" + Write-Verbose -Message "Setting new Url Patterns for Policy {$($PolicyName)} with parameters:`r`n$payload" New-PowerAppPolicyUrlPatterns -TenantId $PPTenantId ` - -PolicyName $policyNameValue ` + -PolicyName $PolicyName ` -NewUrlPatterns $body ` -Verbose } @@ -203,7 +200,7 @@ function Set-TargetResource elseif ($Ensure -eq 'Absent') { Write-Verbose -Message "Removing Url Patterns for Policy {$($PolicyNameValue)}" - Remove-PowerAppPolicyUrlPatterns -TenantId $PPTenantId -PolicyName $policyNameValue + Remove-PowerAppPolicyUrlPatterns -TenantId $PPTenantId -PolicyName $PolicyName } } diff --git a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 index 815cde6893..3482e986ff 100644 --- a/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 +++ b/Modules/Microsoft365DSC/Dependencies/Manifest.psd1 @@ -114,7 +114,7 @@ }, @{ ModuleName = 'Microsoft.PowerApps.Administration.PowerShell' - RequiredVersion = '2.0.200' + RequiredVersion = '2.0.202' }, @{ ModuleName = 'MicrosoftTeams' @@ -138,7 +138,7 @@ }, @{ ModuleName = 'ReverseDSC' - RequiredVersion = '2.0.0.22' + RequiredVersion = '2.0.0.23' } ) }