GitHub Icon Image
GitHub

Check Dataverse Security Role Direct vs Group Assignments

Summary

As a Power Platform Admin, you may need to prove to your Security Team that all Dataverse security roles are assigned via Group Teams only, and that no direct role assignments exist. This script queries the Dataverse Web API and outputs two lists: users with direct role assignments, and users without (meaning they receive roles exclusively via Group Teams).

System and service accounts (identified by a leading # in their name) and Microsoft-internal accounts are automatically filtered out, so only real tenant users are shown.

Example Screenshot

  • PowerApps PowerShell
# ============================================================
# Dataverse Security Role Assignment Checker
# ============================================================

# Please update before running:
$orgUrl = "https://YOURORG.crm4.dynamics.com"
$maxUsers = 500

Write-Host "Getting Access Token..." -ForegroundColor Cyan
$tokenObj = Get-AzAccessToken -ResourceUrl $orgUrl
$token = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($tokenObj.Token)
)

if (-not $token) {
    Write-Error "Could not retrieve token. Please run 'Connect-AzAccount' first."
    exit
}

$headers = @{
    Authorization      = "Bearer $token"
    "OData-MaxVersion" = "4.0"
    "OData-Version"    = "4.0"
    Accept             = "application/json"
}

Write-Host "Loading users..." -ForegroundColor Cyan

$usersUrl = "$orgUrl/api/data/v9.2/systemusers?`$select=fullname,domainname,isdisabled&`$filter=isdisabled eq false and domainname ne ''&`$expand=systemuserroles_association(`$select=name)&`$top=$maxUsers"

try {
    $response = Invoke-RestMethod -Uri $usersUrl -Headers $headers -Method Get
} catch {
    Write-Error "API call failed: $_"
    exit
}

$users = $response.value | Where-Object { 
    $_.fullname -notlike "#*" -and 
    $_.domainname -notlike "*@microsoft.com" 
}

Write-Host "$($users.Count) users loaded." -ForegroundColor Cyan

$directAssignment = @()
$noDirectAssignment = @()

foreach ($user in $users) {
    $roles = $user.systemuserroles_association
    $roleNames = if ($roles -and $roles.Count -gt 0) {
        ($roles | ForEach-Object { $_.name }) -join ", "
    } else { "" }

    $obj = [PSCustomObject]@{
        Name     = $user.fullname
        Username = $user.domainname
        Roles    = $roleNames
    }

    if ($roles -and $roles.Count -gt 0) {
        $directAssignment += $obj
    } else {
        $noDirectAssignment += $obj
    }
}

Write-Host ""
Write-Host "================================================" -ForegroundColor Red
Write-Host " USERS WITH DIRECT ROLE ASSIGNMENT ($($directAssignment.Count))" -ForegroundColor Red
Write-Host "================================================" -ForegroundColor Red
if ($directAssignment.Count -gt 0) {
    $directAssignment | Format-Table
} else {
    Write-Host "No users with direct assignment found." -ForegroundColor Green
}

Write-Host ""
Write-Host "================================================" -ForegroundColor Green
Write-Host " USERS WITHOUT DIRECT ASSIGNMENT - VIA GROUP ONLY ($($noDirectAssignment.Count))" -ForegroundColor Green
Write-Host "================================================" -ForegroundColor Green
$noDirectAssignment | Format-Table

Check out the Microsoft Graph PowerShell SDK to learn more at: https://learn.microsoft.com/powershell/microsoftgraph/get-started

Prerequisites

  • Az.Accounts PowerShell module (Install-Module -Name Az.Accounts -Scope CurrentUser)
  • PowerShell 5.1 or newer
  • Dataverse role: System Administrator or System Customizer
  • Run Connect-AzAccount before executing the script

Contributors

Author(s)
Michael Roth

Disclaimer

THESE SAMPLES ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

Back to top Script Samples
Generated by DocFX with Material UI