diff --git a/scripts/dataverse-check-security-role-assignments/README.md b/scripts/dataverse-check-security-role-assignments/README.md new file mode 100644 index 000000000..b38edd4a8 Binary files /dev/null and b/scripts/dataverse-check-security-role-assignments/README.md differ diff --git a/scripts/dataverse-check-security-role-assignments/assets/example.png b/scripts/dataverse-check-security-role-assignments/assets/example.png new file mode 100644 index 000000000..f5a66c053 Binary files /dev/null and b/scripts/dataverse-check-security-role-assignments/assets/example.png differ diff --git a/scripts/dataverse-check-security-role-assignments/assets/preview.png b/scripts/dataverse-check-security-role-assignments/assets/preview.png new file mode 100644 index 000000000..72a9255df Binary files /dev/null and b/scripts/dataverse-check-security-role-assignments/assets/preview.png differ diff --git a/scripts/dataverse-check-security-role-assignments/assets/sample.json b/scripts/dataverse-check-security-role-assignments/assets/sample.json new file mode 100644 index 000000000..70e837a25 Binary files /dev/null and b/scripts/dataverse-check-security-role-assignments/assets/sample.json differ diff --git a/scripts/dataverse-check-security-role-assignments/dataverse-check-security-role-assignments.ps1.ps1 b/scripts/dataverse-check-security-role-assignments/dataverse-check-security-role-assignments.ps1.ps1 new file mode 100644 index 000000000..72c018e06 --- /dev/null +++ b/scripts/dataverse-check-security-role-assignments/dataverse-check-security-role-assignments.ps1.ps1 @@ -0,0 +1,84 @@ +# ============================================================ +# Dataverse Security Role Assignment Checker +# ============================================================ + +$orgUrl = "https://org4131a97e.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 \ No newline at end of file