Forum Discussion
User account access to the dashboard via API
Good afternoon!
We have a very important and urgent task.
As you all know, you can give access to a specific Power BI dashboard in the Report Server version to a specific user account or Active Directory group (through the interface in Management-Security). In our case, we cannot give access to a group, and when a request comes in for 100+ users to access a specific dashboard, it is not possible to add them one by one. In this regard, the idea came up to create a python script in which to add users through the PBIRS API. But the problem is, which of the API to use for this? There are many methods on the site, what should we apply for this task?
https://app.swaggerhub.com/apis/microsoft-rs/PBIRS/2.0#/info
Also thought about adding through SQL Server to system tables, but the method is very risky for the server's performance, so we abandoned it.
Please help us, I can't believe that there is no other method besides using Active Directory groups.
Yay, it worked. Used just the API I mentioned above (PUT request) and python script. Thanks for the help!
10 Replies
- tayloramy
Super User
Hi ReyCarter_777,
Do you have admin access to the server that RS is hosted on? If so, you can do this with PowerShell.
Below I have attached a sample PowerShell script. This script takes a single username and role, and assigns it to all reports that have broken inherentience (useful for admins to recover a report if users removed everyone in the security tab), but with some tweaks you could get it to pull from a csv file of users and add one role to all those users for a specific report.
Is there a particular reason you can't use AD groups? This is a much easier way of adding and maintaining users.
' rs.exe -v variables expected: ' userName, roleName, rootPath, forceOverlay Dim addedCount As Integer = 0 Dim skippedCount As Integer = 0 Dim alreadyHadCount As Integer = 0 Dim errorCount As Integer = 0 Public Sub Main() If rootPath Is Nothing OrElse rootPath = "" Then rootPath = "/" If roleName Is Nothing OrElse roleName = "" Then roleName = "Content Manager" Dim overlay As Boolean = False If Not (forceOverlay Is Nothing) Then Try : overlay = System.Convert.ToBoolean(forceOverlay) : Catch : overlay = False : End Try End If Console.WriteLine("Starting...") Console.WriteLine(" Root path : " & rootPath) Console.WriteLine(" User : " & userName) Console.WriteLine(" Role : " & roleName) Console.WriteLine(" Overlay? : " & overlay.ToString()) Try Dim items() As CatalogItem = rs.ListChildren(rootPath, True) Console.WriteLine("Found " & items.Length & " items. Processing...") For Each it As CatalogItem In items ProcessItem(it, overlay) Next Console.WriteLine("Done.") Console.WriteLine(" Added : " & addedCount) Console.WriteLine(" Already : " & alreadyHadCount) Console.WriteLine(" Skipped : " & skippedCount) Console.WriteLine(" Errors : " & errorCount) Catch ex As Exception Console.WriteLine("FATAL: " & ex.ToString()) End Try End Sub Sub ProcessItem(it As CatalogItem, overlay As Boolean) Try Dim inheritParent As Boolean = True Dim policies() As Policy = rs.GetPolicies(it.Path, inheritParent) ' ByRef param ' If not forcing overlay and this item still inherits, skip it. If (inheritParent AndAlso Not overlay) Then skippedCount += 1 Return End If ' Start with existing policies (if any) Dim current As New System.Collections.Generic.List(Of Policy) If Not (policies Is Nothing) Then current.AddRange(policies) ' Check if our user already has the desired role Dim hasUser As Boolean = False Dim hasRole As Boolean = False For Each p As Policy In current If StringComparer.OrdinalIgnoreCase.Equals(p.GroupUserName, userName) Then hasUser = True If Not (p.Roles Is Nothing) Then For Each r As Role In p.Roles If StringComparer.OrdinalIgnoreCase.Equals(r.Name, roleName) Then hasRole = True Exit For End If Next End If Exit For End If Next If hasUser AndAlso hasRole Then alreadyHadCount += 1 Return End If ' Merge or create our policy If hasUser Then For Each p As Policy In current If StringComparer.OrdinalIgnoreCase.Equals(p.GroupUserName, userName) Then Dim rolesList As New System.Collections.Generic.List(Of Role) If Not (p.Roles Is Nothing) Then rolesList.AddRange(p.Roles) Dim roleExists As Boolean = False For Each r As Role In rolesList If StringComparer.OrdinalIgnoreCase.Equals(r.Name, roleName) Then roleExists = True Exit For End If Next If Not roleExists Then Dim newRole As New Role() newRole.Name = roleName rolesList.Add(newRole) p.Roles = rolesList.ToArray() End If Exit For End If Next Else Dim newP As New Policy() newP.GroupUserName = userName Dim newRole As New Role() newRole.Name = roleName newP.Roles = New Role() { newRole } current.Add(newP) End If ' Apply policies (this breaks inheritance if it was inheriting and overlay=True) rs.SetPolicies(it.Path, current.ToArray()) addedCount += 1 Catch ex As Exception errorCount += 1 Console.WriteLine("ERROR on '" & it.Path & "': " & ex.Message) End Try End SubIf you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.
- ReyCarter_777
Helper I
Yes, I am the server administrator. Our task is to assign the Browser role to the specified users on a specific dashboard. This means that we specify the path or ID of the dashboard and the users at the entrance. As a result, we should have the specified users with the Browser role in the Security section of the dashboard. We cannot use AD because this server is managed by other company employees who are not interested in the development of Report Server. In this case, you will have to constantly maintain and develop your AD groups, which is a huge labor-intensive task.
- tayloramy
Super User
Hi ReyCarter_777,
How adept are you in PowerShell? Are you able to modify my powershell script to read from a csv of users and add them to a report path/ID given as a parameter?
If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.
- ReyCarter_777
Helper I
Yay, it worked. Used just the API I mentioned above (PUT request) and python script. Thanks for the help!