Logo
Add SharePoint Online Sites.Selected Permissions Using Graph PowerShell (Get-MgSitePermission)
PowerShell; SharePoint

Add SharePoint Online Sites.Selected Permissions Using Graph PowerShell (Get-MgSitePermission)

10 May 2024 By Hal Sclater

A very frequent request from developers is to grant access to a SharePoint site from a service principal. This is how we typically do this, using an app registration along with sites.selected API permission.

The Sites.Selected permission in Microsoft Graph provides several benefits when it comes to controlling app-specific access to specific SharePoint sites:

  1. Granular Access Control: Using Sites.Selected along with the Sites permissions endpoint allows you to set specific site collections and access levels for individual applications.
  2. Application-Specific Permissions: You can assign read or write permissions to targeted sites for a specific application.
  3. Background Application Scenarios: Perfect for running applications in the background without user interaction.

Process Summary

  1. Create an app registration for the developer requesting the site.
  2. Get the SharePoint site ID of the target site.
  3. Create an app registration for PowerShell with Sites.FullControl.All permission.
  4. Connect to Microsoft Graph PowerShell using the app registration and certificate.
  5. Add the Sites.Selected permission for the target app.

Step 1: Create the Target App Registration

Image 2

This will be the app reg that the developer or app will use.

  • Create a new app registration in Entra ID.
  • Add API permissions: Graph API > Application > Sites.Selected
  • After adding the permissions, click Grant admin consent.

Note that Sites.Read.All is not required and should not be added, since this gives read access to all sites.

Step 2: Get the SharePoint Site ID

You can use Graph Explorer or PowerShell:

Using Graph Explorer:

  1. Login at https://developer.microsoft.com/en-us/graph/graph-explorer
  2. Run the following GET query:
    https://graph.microsoft.com/v1.0/sites/{tenant}.sharepoint.com:/sites/{sitename}
  3. Note the complete ID in the response.

Step 3: Create a PowerShell App Registration with Certificate

Create a local certificate:

$CertParam = @{
    'KeyAlgorithm'      = 'RSA'
    'KeyLength'         = 2048
    'KeyExportPolicy'   = 'NonExportable'
    'DnsName'           = 'powershell.domain.com'
    'FriendlyName'      = 'Graph PowerShell app'
    'CertStoreLocation' = 'Cert:\CurrentUser\My\'
    'NotAfter'          = (Get-Date).AddYears(2)
}
$Cert = New-SelfSignedCertificate @CertParam
Export-Certificate -Cert $Cert -FilePath c:\temp\GraphPowerShellApp.cer
  • Create a new app registration called Graph PowerShell.
  • Upload the certificate.
  • Add Microsoft.Graph Sites.FullControl.All application permission.

Step 4: Connect to Graph with PowerShell

Install or update the Microsoft.Graph module:

Install-Module Microsoft.Graph -Scope CurrentUser

Connect using the app registration and certificate:

$AppId = "your-app-id"
$TenantId = "your-tenant-id"
$Certificate = Get-ChildItem Cert:\CurrentUser\My\ | Where-Object { $_.Subject -like "*Graph PowerShell*" }
Connect-MgGraph -TenantId $TenantId -AppId $AppId -Certificate $Certificate

Step 5: Add the Permission

$siteId = "tenant.sharepoint.com,xxxxxx-6710-417e-bd83-xxxxx,xxxxxx-b61c-49dd-af50-xxxxx"

$params = @{
    roles = @("write")
    grantedToIdentities = @(
        @{
            application = @{
                id = "target-app-client-id"
                displayName = "TargetAppName"
            }
        }
    )
}

New-MgSitePermission -SiteId $siteId -BodyParameter $params

Or use the full script which gets the Site ID automatically:

$siteURL = "https://tenant.sharepoint.com/sites/sitename"
$siteFix = $siteURL -replace "https://", ""
$siteFix = $siteFix -replace "sharepoint.com", "sharepoint.com:"

try {
    $Site = Get-MgSite -siteId $siteFix
} catch {
    Write-Host "Site not found" -ForegroundColor Red
    Exit
}
$siteId = $Site.Id
Write-Host "Found site: $($Site.DisplayName) $($Site.WebUrl)" -ForegroundColor Green

$params = @{
    roles = @("write")
    grantedToIdentities = @(
        @{
            application = @{
                id = "target-app-client-id"
                displayName = "TargetAppName"
            }
        }
    )
}

New-MgSitePermission -SiteId $siteId -BodyParameter $params

Using Get-MgSitePermission to Verify Permissions

After granting Sites.Selected permissions, use Get-MgSitePermission to verify what permissions are applied to a site:

# Get all permissions for a specific site
$siteId = "tenant.sharepoint.com,xxxxxx-6710-417e-bd83-xxxxx,xxxxxx-b61c-49dd-af50-xxxxx"
Get-MgSitePermission -SiteId $siteId

# Filter to show only application permissions
Get-MgSitePermission -SiteId $siteId | Where-Object { $_.GrantedToIdentities.Application -ne $null }

# View permissions in a readable format
Get-MgSitePermission -SiteId $siteId | ForEach-Object {
    $app = $_.GrantedToIdentities.Application
    if ($app) {
        [PSCustomObject]@{
            AppName   = $app.DisplayName
            AppId     = $app.Id
            Roles     = $_.Roles -join ", "
        }
    }
}

You can also use this to audit which apps have access to which sites across your tenant.

CmdletPurpose
Get-MgSitePermissionList permissions applied to a SharePoint site
New-MgSitePermissionGrant Sites.Selected permission to an app
Update-MgSitePermissionModify existing site permissions (e.g., change roles)
Remove-MgSitePermissionRevoke an app’s access to a specific site
Get-MgSiteRetrieve a SharePoint site by URL or ID
Get-MgSubSiteList sub-sites under a parent site

These cmdlets give you full control over SharePoint site permissions via Microsoft Graph PowerShell, whether you’re granting, auditing, or revoking access.

Conclusion

Sites.Selected provides fine-grained control over which sites an application can access, allowing you to tailor permissions to your specific use case. It’s easy to use PowerShell and Microsoft Graph to add this.

See Microsoft’s official blog post for more details.