Implementing Row-Level Security in Dataverse using PowerShell

Loading

Row-Level Security (RLS) in Microsoft Dataverse allows you to control access to individual records based on user roles, teams, and ownership. Implementing RLS via PowerShell helps automate security assignments efficiently.

This guide covers:
Understanding Row-Level Security in Dataverse
Assigning Security Roles to Users/Teams
Setting Up Ownership-Based Security
Defining Access Control with Field Security Profiles
Testing and Verifying Permissions


Step 1: Prerequisites

1. Permissions Required

  • System Administrator or a role with permissions to manage security settings.
  • Power Platform API enabled for access via PowerShell.

2. Install and Import Required PowerShell Modules

Ensure the Power Platform PowerShell modules are installed.

# Install Dataverse PowerShell module
Install-Module -Name Microsoft.PowerPlatform.Cds.Client -Scope CurrentUser -Force

# Import the module
Import-Module Microsoft.PowerPlatform.Cds.Client

Step 2: Connect to Dataverse Using PowerShell

Option 1: Interactive Login

# Connect to Dataverse interactively
$connection = Connect-CdsService -ConnectionString "AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;Prompt=Login"

A sign-in window will appear for authentication.

Option 2: Using Service Principal (App Registration)

For automation scripts, use Azure AD App Registration credentials.

# Define credentials
$clientId = "your-app-client-id"
$clientSecret = "your-app-client-secret"
$tenantId = "your-tenant-id"
$orgUrl = "https://yourorg.crm.dynamics.com"

# Convert secret to secure string
$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($clientId, $secureSecret)

# Connect to Dataverse
$connection = Connect-CdsService -Url $orgUrl -ClientId $clientId -ClientSecret $secureSecret -TenantId $tenantId

Step 3: Assign a Security Role to a User

Security roles control what actions users can perform on records.

# Define parameters
$securityRoleName = "Salesperson" # Change this as needed
$userEmail = "user@example.com"

# Get the user ID from email
$user = Get-CdsRecord -Connection $connection -EntityLogicalName systemuser -Filter "internalemailaddress eq '$userEmail'"
$userId = $user.systemuserid

# Get the security role ID
$role = Get-CdsRecord -Connection $connection -EntityLogicalName role -Filter "name eq '$securityRoleName'"
$roleId = $role.roleid

# Assign the role to the user
New-CdsEntityAssociation -Connection $connection -EntityLogicalName systemuser -Id $userId -RelationshipName systemuserroles_association -RelatedEntityLogicalName role -RelatedEntitiesIds @($roleId)

Write-Host "Security role '$securityRoleName' assigned to user $userEmail."

This script:
Finds a user by email
Finds a security role by name
Assigns the role to the user


Step 4: Assign a Security Role to a Team

Teams allow you to manage permissions for multiple users at once.

# Define parameters
$teamName = "Sales Team"
$securityRoleName = "Salesperson"

# Get the team ID
$team = Get-CdsRecord -Connection $connection -EntityLogicalName team -Filter "name eq '$teamName'"
$teamId = $team.teamid

# Get the security role ID
$role = Get-CdsRecord -Connection $connection -EntityLogicalName role -Filter "name eq '$securityRoleName'"
$roleId = $role.roleid

# Assign the role to the team
New-CdsEntityAssociation -Connection $connection -EntityLogicalName team -Id $teamId -RelationshipName teamroles_association -RelatedEntityLogicalName role -RelatedEntitiesIds @($roleId)

Write-Host "Security role '$securityRoleName' assigned to team '$teamName'."

This script assigns a security role to a specific team.


Step 5: Assign a User as an Owner of Specific Records

To implement record-level security, assign ownership of records.

# Define parameters
$userEmail = "user@example.com"
$tableName = "account"
$recordId = "GUID-of-the-record"

# Get user ID
$user = Get-CdsRecord -Connection $connection -EntityLogicalName systemuser -Filter "internalemailaddress eq '$userEmail'"
$userId = $user.systemuserid

# Assign ownership
Set-CdsRecord -Connection $connection -EntityLogicalName $tableName -Id $recordId -Fields @{ "ownerid" = $userId; "owneridtype" = "systemuser" }

Write-Host "Record ownership transferred to $userEmail."

This script:
Finds the user ID by email
Updates the record ownership


Step 6: Creating a Field Security Profile

Field Security Profiles allow restricting access to specific fields.

# Define profile name
$profileName = "Restricted Fields"

# Create a new field security profile
$profile = New-CdsRecord -Connection $connection -EntityLogicalName fieldsecurityprofile -Fields @{ "name" = $profileName }
$profileId = $profile.fieldsecurityprofileid

Write-Host "Field Security Profile '$profileName' created successfully!"

This creates a new Field Security Profile for sensitive fields.


Step 7: Assign Users to a Field Security Profile

# Define parameters
$profileName = "Restricted Fields"
$userEmail = "user@example.com"

# Get profile ID
$profile = Get-CdsRecord -Connection $connection -EntityLogicalName fieldsecurityprofile -Filter "name eq '$profileName'"
$profileId = $profile.fieldsecurityprofileid

# Get user ID
$user = Get-CdsRecord -Connection $connection -EntityLogicalName systemuser -Filter "internalemailaddress eq '$userEmail'"
$userId = $user.systemuserid

# Assign user to profile
New-CdsEntityAssociation -Connection $connection -EntityLogicalName fieldsecurityprofile -Id $profileId -RelationshipName fieldsecurityprofile_systemuser -RelatedEntityLogicalName systemuser -RelatedEntitiesIds @($userId)

Write-Host "User '$userEmail' assigned to Field Security Profile '$profileName'."

Now, the user will have restricted access to sensitive fields.


Step 8: Testing and Verifying Permissions

1. List Users Assigned to a Role

# Define security role
$securityRoleName = "Salesperson"

# Get role ID
$role = Get-CdsRecord -Connection $connection -EntityLogicalName role -Filter "name eq '$securityRoleName'"
$roleId = $role.roleid

# Get users assigned to this role
$users = Get-CdsRecord -Connection $connection -EntityLogicalName systemuserroles_association -Filter "roleid eq '$roleId'"
$users | Select-Object fullname, internalemailaddress

2. Check Record Ownership

# Define table and record ID
$tableName = "account"
$recordId = "GUID-of-the-record"

# Fetch record owner
$record = Get-CdsRecord -Connection $connection -EntityLogicalName $tableName -Id $recordId
Write-Host "Record Owner ID: $($record.ownerid)"

Leave a Reply

Your email address will not be published. Required fields are marked *