Skip to content

Instantly share code, notes, and snippets.

@paschott
Last active July 17, 2024 16:01
Show Gist options
  • Save paschott/8b38e7167c012ce37d2e253bae3756cb to your computer and use it in GitHub Desktop.
Save paschott/8b38e7167c012ce37d2e253bae3756cb to your computer and use it in GitHub Desktop.
Get Azure SQL Database Permissions
/* Get all db principals and their roles for Azure SQL */
SELECT
@@ServerName as ServerName,
DB_NAME() as DatabaseName,
pr.name AS PrincipalName,
pr.type_desc AS PrincipalType,
r.name AS RoleName,
dp.state_desc AS RoleState,
NULL as PermissionName,
NULL as PermissionState,
NULL as PermissionClass,
NULL as ObjectName
FROM
sys.database_role_members drm
JOIN sys.database_principals pr ON drm.member_principal_id = pr.principal_id
JOIN sys.database_principals r ON drm.role_principal_id = r.principal_id
LEFT JOIN sys.database_permissions dp ON pr.principal_id = dp.grantee_principal_id
WHERE
pr.type_desc IN ('SQL_USER', 'WINDOWS_USER', 'WINDOWS_GROUP', 'EXTERNAL_USER', 'EXTERNAL_GROUP', 'APPLICATION_ROLE') -- Filter for users and groups
UNION
/* Get all db principals and their explicitly granted permissions for Azure SQL */
SELECT
@@ServerName as ServerName,
DB_NAME() as DatabaseName,
pr.name AS PrincipalName,
pr.type_desc AS PrincipalType,
NULL as RoleName,
NULL as RoleState,
dp.permission_name AS PermissionName,
dp.state_desc AS PermissionState,
dp.class_desc AS PermissionClass,
OBJECT_NAME(dp.major_id) AS ObjectName
FROM
sys.database_permissions dp
JOIN sys.database_principals pr ON dp.grantee_principal_id = pr.principal_id
WHERE
pr.type_desc IN ('SQL_USER', 'WINDOWS_USER', 'WINDOWS_GROUP', 'EXTERNAL_USER', 'EXTERNAL_GROUP', 'APPLICATION_ROLE') -- Filter for users and groups
and dp.permission_name NOT IN ('CONNECT')
import-module az.sql
import-module az.resources
import-module importexcel
# Update-AzConfig -DisplayBreakingChangeWarning $false
# sign in to Azure account
Connect-AzAccount
#Folder containing sql scripts to import
$sourceFolder = "C:\AzureSQLDB Permissions\"
## adjust GUIDs to set the appropriate subscription context
Set-AzContext -Subscription "guid_here" ##Prod
# Set-AzContext -Subscription "another_guid_here" ##Dev
## Set Excel destination for current subscription
$ExcelFile = $sourceFolder + "DatabasePermissions-Prod.xlsx"
# $ExcelFile = $sourceFolder + "DatabasePermissions-DevTest.xlsx"
## Delete any existing files before starting
Remove-Item $ExcelFile -ErrorAction SilentlyContinue
## Get the query text to run against each database
$query = Get-Content ($sourceFolder + "AzureSQLPermissions.sql") -Raw
#Get Access Token to connect to SQL Servers
$AccessToken = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
#get current resource groups
$rg = Get-AzResourceGroup
## Loop through each resource group, get all Azure SQL Servers in that group
## Loop through each of their databases, excluding master
## Attempt to run the query and export contents to Excel
## If an exception, output a message indicating no access to run the query (which was my condition)
foreach ($rgname in $rg.ResourceGroupName) {
$servers = Get-AzSqlServer -ResourceGroupName $rgname | Where-Object ServerName -NotLike "*-geo*"
foreach ($servername in $servers.ServerName) {
#work with each database
$databases = Get-AzSqlDatabase -ResourceGroupName $rgname -ServerName $servername | Where-Object DatabaseName -ne "master"
foreach ($db in $databases.DatabaseName) {
$params = @{
'database' = $db
'serverInstance' = $servername + ".database.windows.net"
'AccessToken' = $AccessToken
'outputSqlErrors' = $false
'query' = $query
'Encrypt' = "Mandatory"
}
try {
Write-Host "Processsing " $servername "::" $db
$output = Invoke-SqlCmd @params -OutputAs DataRows -Verbose -ErrorAction SilentlyContinue
$output | Export-Excel -Path $ExcelFile -WorksheetName "SQLPermissions" -Append `
-ExcludeProperty @("ItemArray", "RowError", "RowState", "Table", "HasErrors") -AutoSize -AutoFilter -BoldTopRow
}
catch {Write-Host "No Access to server: " $servername}
} #databases
} #servers
} #Resource Groups
@paschott
Copy link
Author

Use PowerShell + a SQL Script to loop through all resource groups, sql servers, and databases to export permissions to an Excel workbook.

@paschott
Copy link
Author

paschott commented Sep 8, 2023

Added EXTERNAL_GROUP to the Azure SQL Permissions. Original version only picked up AAD users, not AAD groups.

@paschott
Copy link
Author

Added Windows Users to the output so this can work on-prem as well as in Azure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment