Tag Archive for microsoft

Row Level Security in Power BI – Part 2

In Part 1 of this series, we discussed Row Level Security in Power BI, that it is different from RLS in SQL Server 2016, and then went on to demonstrate two simple scenarios where RLS can be used to filter data in a model based on Role assignment utilizing some DAX filter expressions. We introduced the USERNAME() DAX function and demonstrated its usefulness. In this second article, we’ll be diving a little deeper into RLS.

Row Level Security in Power BI Scenario 3:

Those first two scenarios from Part 1 were not that bad to implement. One line of a DAX expression and you’ve got a simple filter covered. But life seldom ever hands us a scenario that is so cut and dry. For this scenario, we’re going to add some requirements that might get handed down by the business users such as:

  • Ability to grant access to a group of countries, like continents, or regions.
  • Ability to have any one country be in multiple geo-political groups.
  • Ability to grant and revoke access to an entire group of people at once rather than needing to address each person individually
  • Ability to grant access on any one country to any one individual

For this we’re going to again go back to the database and create a few tables to help us. We already have the Country table so no need to do anything there. But we’ll add four more:

  • Users
  • Groups
  • User Group Membership
  • Country Group Membership

The T-SQL code for this can be found in the attachment, and a simple database drawing is shown here:

Row Security 3-1-1

We’ll also add some rows to the respective tables via basic INSERT statements:

For those of you who, like me, are full-blooded SQL nerds, I have included the CREATE TABLE, INSERT INTO, and CREATE VIEW scripts that can be executed in your database.  But we don’t need to import all four additional tables into your model, we simply need the distinct list of Users and the Countries to which each has access. This is represented in the [dbo].[SecurityQuery] view (Script #05). If you look at the view definition, note the DISTINCT key word in the SELECT clause, the optional fields to show the User’s Full Name and the Country Name, the absence of any fields from the [Group] or[ GroupUser] tables, and the WHERE clause at the bottom that filters for only Active records.

First, we’ll need to remove the Continent table from the model, then import the SecurityQuery dataset. Since this is not an exercise in how to import data, I’ll leave it up to you to get that done. And while you’re adding it, you might as well add the [SecurityReference] view as well and we’ll cover its usage at the end of the article.

Once you have the [SecurityQuery] in your model, it needs to be joined to the Country table, on Country code:

Row 3-1-2


Hint: If you have sufficient rows in the Security Query dataset, when you set up the relationship between [Country Code] in the Country table and the [Country Code] in the Security Query table, Power BI will recognize that this is a one-to-many relationship with the Country table being at the “one” side.

As before, we will use the Manage Roles button on the Modelling tab to configure the DAX Filter for the Roles. We’ll start with what we learned from before:  a filter on the [UserName] field and making use of the USERNAME() DAX function as before:

Row 3-1-3

But if we were to browse the model now for any one member in our set, we’ll see that he or she is limited in the rows returned by the Security Query, but NOT limited by rows returned in the Country table. Why not? It worked before. It is because the table on which the USERNAME() filter is applied is not at the top of the hierarchy, it’s at the bottom. To make things more complicated, there are two branches from the top of that hierarchy, one branch to sales, through the country table, and one branch directly to the security table. If only there was a way to filter the countries in that table based on those listed in the Security Query table. We need something more.

Enter the CONTAINS() DAX function. The description from MDSN is as follows:


CONTAINS(<table>, <columnName>, <value>[, <columnName>, <value>]…)

Return Value

A value of TRUE if each specified value can be found in the corresponding columnName, or are contained, in those columns; otherwise, the function returns FALSE.

If you’re like me, you’ll read that and think, “say WHAT?” Let’s implement it first, then we’ll sort out and explain how the parameters are used. Back under the Manage Roles, add a Filter to the Country table as the following (hint: it doesn’t matter which column you select as you will be replacing it with the entire text below):








Note: The line breaks are not required in this, but are added for clarity of reading.

Now here’s the layman’s description of how the DAX statement above works with the five parameters, in order of their appearance:

Go to the ‘SecurityQuery’ table (1st parameter), and in the column ‘SecurityColumn’[UserName] (2nd parameter), look for any rows that match the value returned by the function USERNAME() (3rd parameter).  Then for those rows, take the values in the column ‘SecurityQuery’[CountryCode] (4th), and see if those values exist in the column ‘Country’[CountryCode] (5th). If that [CountryCode] value is found return TRUE for that row, and allow it to be viewed in this context.

There are a couple of things to watch for when implementing this approach. First, you need to have a relationship defined between the Country table and the SecurityQuery table. Second, the <value> parameter (3rd parameter) of the CONTAINS() function can be just that, a single value, not a list or table. But the USERNAME() function fits this bill nicely. Third, you still need the [UserName] = USERNAME() security filter on the Security Query dataset.

If you followed the INSERT scripts included, you will recall that there were only two people involved: Fred and Bob. And you may recall that we granted Fred access to a Group called “Pacific Rim” (which included countries such as Japan, Hong Kong, and the Philippines) but that [GroupMembership] row was NOT flagged with [IsActive] = 0. Fred’s mapped data looks like this:

row 3-1-4


Now here’s where the [SecurityRefernce] dataset comes in. After adding it as part of the model, you need to make sure that A) it has NO relationships to any other tables and that B) it also has a [UserName] = USERNAME() DAX Filter expression applied.

I added a report page to my Power BI model and a simple Matrix visualization based on this table and configured it as follows:

  • Rows = [Country Name]
  • Columns = [GroupName]
  • Values = [IsActive], with a SUM aggregation
  • For the [IsActive], I set up Conditional Formatting with the following properties

row 3-1-5

The resulting visualization is a nice way to see exactly HOW a person has gotten access to any one particular country (via membership in which Group), and what countries are in any Group they have are also a member of, even if that membership is not active.

Row 3-1-6


It is true that there is a lot introduced here that may not specifically be “Row Level Security” stuff, but rather T-SQL overhead. After all, all you really need for this 3rd scenario to work is the distinct list of Users and Countries that are allowed access. But given the 173 countries in the world and say, two dozen people to which access control is required, that’s potentially up to 4,000 rows of data controlling who has access to what. Breaking it into Users and Groups and Memberships is a way to manage the mess.

About Todd: Todd Chittenden started his programming and reporting career with industrial maintenance applications in the late 1990’s. When SQL Server 2005 was introduced, he quickly became certified in Microsoft’s latest RDBMS technology and has added certifications over the years. He currently holds an MCSE in Business Intelligence . He has applied his knowledge of relational databases, data warehouses, business intelligence and analytics to a variety of projects for BlumShapiro since 2011. 

Power BI Demo CTA


Row Level Security in Power BI – Part 1

The folks at Microsoft have been steadily adding features to both the Power BI service and the downloadable Power BI Desktop over the past eighteen months since it went General Availability in July of 2015. Row Level Security is one such feature, allowing the developer to restrict which data is seen by users. Like most other major features, it was introduced into Power BI Service first, then eventually added to the Desktop. However, unlike other features, upon its addition to the Desktop, it, or most of it, was removed from the Service. After all, you really only need it in one place. Having it in both places would just cause confusion and conflicts. However, there are some lingering aspects in the Power BI service that require attention after deploying a model that has Row Level Security defined. In this post, we’ll look at this feature of Power BI, how to get it up and running in the Desktop, what needs to be done on the Service, and some common scenarios for when it might be useful.

But before we get started, you need to be made aware of two points: First is that RLS in Power BI is NOT the same as RLS in SQL Server 2016. Yes, both are great new feature in their respective products, and do pretty much the same thing of restricting user access to certain rows of data. They even share the same acronym, and the results are pretty much the same, but the implementation methods of each are quite different. RLS in SQL Server uses T-SQL functions and other artifacts inside the SQL database, while Power BI uses DAX. Another major difference is that RLS in Power BI can be used regardless of the data source type.

The second major point is that RLS and Power BI Dashboard’s Q&A feature are mutually exclusive. You can have one or the other, but not both. While some readers may not really care about that, others may simply stop reading right here based on that revelation alone. But before you click off the page because of this limitation, take a moment to voice your opinion at the Power BI Feedback site for this particular issue. Even if you don’t care, some day you might and I encourage you to vote on the item. Go ahead, we’ll wait.

Ok, you’re back? Good, let’s get started.

Row Level Security in Power BI Scenario 1

The first scenario we’re going to explore is one where you have hard-coded roles for each particular segment of data. For the demo model for all these scenarios, I generated data that was spread across the globe, and tied the access directly to continents, then later to countries. This makes it very easy to determine at a glance if data is being filtered properly. The Power BI map visualization is the ideal choice for this as your eyes can easily determine which geographic entities are represented by the data. We’ll see the map again later on, but for starters, the unfiltered data maps like this:

Row Level Security 1


Before we set the security for this data, I’ll explain a little about this particular model’s data structure: It is made up of three tables as shown here: country, customer, and Salessales. The country table lists all of the countries in the world, and which continent they are on. Also, that table is at the “one” side of a one-to-many relationship to Customer (on [CountryCode]), which is in turn on the “one” side of its relationship to the Sales table.

Row Level Security 21


If we can limit the countries to only those in, say, North America, that would limit the customers to those that are located there, and that would limit the sales, in a cascading filter sort of way. We end up seeing only sales to Customers that are in North America. It would be like adding a WHERE predicate to a SQL query which filters as follows:

SELECT * FROM dbo.Country WHERE Continent = ‘North America’

Let’s get started.

  • On the Modelling tab, click Manage Roles.
  • Click Create to add a new Role, and name it “North America”.
  • Under Tables, click the ellipsis next to Country and select Add Filter, then select the [Continent] field
  • Edit the Table Filter DAX Expression it generates, substituting “Value” for “North America”

row 3


To test out this Role, back on the Modelling tab, click View As Roles. Select the North America role. My resulting map looks like this: Row 4


Notice the yellow band at the top of the report page that not only shows the security context under which the data is being viewed, but also offers a link to go back to unfiltered data.

We’ve successfully created a Security Role for North America. With only six distinct continents in the Country table, it is a simple operation to add additional roles for the remaining five, each appropriately named.

After deploying the model to the Power BI service, we have some additional work. Locate the data set for the model, click the ellipsis next to it and select security. This is where you would specify who has membership in which role. And obviously, membership in any one role gives you access to see the data associated with that particular continent. There is nothing stopping you from adding any one name to multiple roles. As you can see from the screenshot below, I have already added someone to the North America role.

row 5


Get used to this operation as it will be referenced in each of the other two scenarios, but not directly explained again as the operation is exactly the same. Only the name of the Role(s) will change.

This Row Level Security approach is useful if you have a relatively small number of distinct values at the top of a hierarchy (Continent / Country / Sales in this case), and that list is not likely to change. Changes in that list of values would dictate corresponding changes to the Roles, and re-deployments of the Power BI model. But I think we’re safe with our six continents on this earth for at least another googol years or so.

Row Level Security in Power BI Scenario 2

In this scenario, we’re going to take the security role assignments out of the Power BI Service and hold them at the database layer. We’ll use the same model from the previous scenario, minus the six roles we defined before. This model includes one additional table, Continent as shown below: row 6

And as you can imagine, this table now moves the top of our de-facto hierarchy, with a one-to-many relationship between it and the Country table, on field [Continent]:

row 7

To set security in the model we will do the same thing using the Manage Roles dialog box. If you are continuing on from Scenario 1 and have added the Continent table, you can delete the six Roles you added before as they are not needed here. But this time the single role of “Users” will filter on the Continent table, with the DAX expression of: [UserName] = USERNAME()

Row 8


The DAX USERNAME() function returns the login name and domain of the logged in user in the format of <name>@<domain>. This returned value ties nicely with the [UserName] column of the Continent table.

To test out this method of securing the data, we will again go to the View As Roles button on the Modelling tab, but this time we’ll check off both the Role of “Users”, and also fill in the “Other user” option by supplying a user name. If you recall the Continent table above, Eustice is assigned to Europe, so she only sees data for Europe. Notice below also how the Continent slicer gets filtered to just one value, and the Country slicer below it gets filtered as well to only Countries to which Eustice has access — those in Europe.

Row 9

After deploying the model, we still need to add email addresses to our User role just like before, but this time we have one role to worry about, and so all six names can be added under that one Role. Control over who gets to see what continent is defined in the rows of the Continent table back in the database. By changing or removing a name and refreshing the data to Power BI, we will alter data access rights without the need to redeploy the model or make adjustments to the Dataset’s Security settings on the site.

This scenario is handy when you again have a clearly defined top-down hierarchy, and when the users’ access is mutually exclusive. One and only one person can have access to each continent. I foresee this being implemented in a model where a salesperson table is at the head of the hierarchy and by filtering the salesperson, the customers and their respective sales get filtered as well. One certainly would not want to be creating a role for each salesperson, re-deploying the model, and then assigning each salesperson to their respective role as we did in Scenario 1. Instead, this approach handles the security assignment dynamically with the USERNAME() function.

Stay tuned for Part 2 where we will look at a third scenario which is a bit more involved, with multiple users, multiple groups, multiple group memberships, and multiple geo-political regions.

About Todd: Todd Chittenden started his programming and reporting career with industrial maintenance applications in the late 1990’s. When SQL Server 2005 was introduced, he quickly became certified in Microsoft’s latest RDBMS technology and has added certifications over the years. He currently holds an MCSE in Business Intelligence . He has applied his knowledge of relational databases, data warehouses, business intelligence and analytics to a variety of projects for BlumShapiro since 2011. 

Power BI Demo CTA

On the Leading Edge of New Technology

Finger about to press future button with blue light over black and grey background. Concept image for illustration of change or strategic vision.

Being on the leading edge of any technology can be exciting, but it’s often frustrating and even costly. There is an inherent risk associated with adopting technology that is new. Lack of community support or documentation if something goes wrong are just a couple of the issues that can arise. However, there are benefits to being an early adopter. For example, working hands-on with a new technology is the best way to understand how it works. As technology consultants, we view it as our job to understand what’s coming so we can advise our clients with a clear eye to the future.


A client asked us about alternatives to their current Remote Desktop Services (RDS) implementation which was being hosted by a third-party vendor. There were a few issues with their current setup, namely cost and maintaining multiple logins, and they didn’t have any type of domain or user directory. After exploring a few different RDS deployment scenarios, they ultimately decided on using a preview version of Azure Active Directory Domain Services (AD DS) on Azure virtual machines.

They really liked the idea of using Azure AD DS because of the promised benefits; no servers (on-premises or in the cloud) to maintain, simplified user interface, etc. We shared our assessment of the risks and unknowns of using an untested technology, but the client whole heartedly accepted these risks because there were so many more upsides to using Azure AD DS for their specific setup. So, we set out to implement Remote Desktop Services using Azure Active Directory Domain Services…and we learned a couple of things along the way which we are happy to share with you.

Sometimes the Leading Edge is the Bleeding Edge

The first lesson learned was that with Azure AD DS, you cannot be added as a Domain Admin or Global Admin. They have their own security group called AAD DC Administrators that you have to create yourself. A good thing to note when dealing with Azure AD DS. Which lead us right to our second lesson learned.

When trying to add the Licensing Manager as a member of the AD group Terminal Server License Servers group, a permissions error popped up:

The computer account for license server [ServerName] cannot be added to the Terminal Server License Servers group in Active Directory Domain Services (AD DS) because of insufficient privileges.

Leading Edge

Thinking back to that security group, I thought, “I am not a Domain Admin, I cannot be a Domain Admin.” I felt a little helpless. Thankfully the computer didn’t need to be added to the group since all RDS servers were on the same domain. But still, I couldn’t help feeling like something might be a miss later.

As a Microsoft partner we have top tier access to Microsoft support, who recommended a few solutions to this issue…which resulted in the same permissions’ roadblock.

When the Microsoft support engineer mentioned this was the first he has heard of someone trying this, I thought, I must be a pioneer attempting this while AD DS was still in beta. But one thing was for sure, the Azure AD DS team liked the idea that someone was trying out an RDS implementation with it.

When you work with a beta version or when you install something without waiting for Service Pack 2 to be released you are blazing a new trail. When you do something new there is a thrill of being the first person to try something, and a long-standing honor in the tech world to be the first to figure something out.

In the end, after another hiccup or two, the rest of the Remote Desktop Services deployment went well, without any additional permission issues. And the result showed us that Remote Desktop Services does work well with Azure Active Directory Domain Services and was able to accomplish the client’s goals.

Once the beta for Azure Active Directory Domain Services is complete, I’m wondering if RDS will be on the list of supported technologies. Then I will feel like a true trailblazer cutting a path for others to follow.

Our experience with Microsoft tools gives us an inside track and an ability to work with these new technologies because we deeply understand the underlying platform. While being on the bleeding edge of technology can be risky, having experts to help guide you, navigate any issues and provide needed support can help mitigate some of these risks. And in the end, the benefits to your organization will outweigh any roadblocks encountered along the way.

About Brent:


Brent Harvey has over 10 years of software development experience with a specific focus on SharePoint, Project Server, and C #and web development. Brent is an Architect at BlumShapiro Consulting, working on projects across varied industries (banking, manufacturing, health care, etc.). Brent is a Microsoft Certified Solutions Expert in SharePoint 2013, Solutions Associate in Windows Server 2012, Specialist in Developing Azure Solutions, and Professional Developer in SharePoint 2010.

Technology CTA (3)

The Business Value of Microsoft Azure – Part 3 – Backup

This article is part 3 of a series of articles that will focus on the Business Value of Microsoft Azure. Microsoft Azure provides a variety of cloud based technologies that can enable organizations in a number of ways. Rather than focusing on the technical aspects of Microsoft Azure (there’s plenty of that content out there) this series will focus on business situations and how Microsoft Azure services can benefit.

In our last article we focused on data security from the perspective of the ability for users to purposefully or inadvertently cause data to leave the organization. Today we’re going to focus on data loss from the standpoint of system failure, corruption or other disaster that requires access to a backup.

Many organizations still rely on tape based backup systems as the primary means of backing up critical business data. Let’s take the typical municipal office. Chances are that our fictional town of Gamehendge has either a traditional backup to tape solution or perhaps a disk-based virtual tape system where copies are then made to physical tapes. These tapes are sent offsite to a facility that manages tape archiving for disaster protection purposes. While this seems reasonable, our town faces a problem.

If a production system fails or if data needs to be restored due to user deletion/corruption it might take up to 24 hours for the IT department to work with the off-site records management company to request, locate and deliver the appropriate tape with the ensuing process to then actually recover the data.

One solution to this problem might be to set up a co-location solution with a hosting provider and replicate certain servers. Again, this is a fairly common practice. However, replicating all the servers in their environment is costly and so only a handful of the most high-priority systems are replicated. This approach, while a step in the right direction, only allows a few key systems to be restored in 2-3 hours, leaving the remaining systems to a 24 hour recovery period.

Our fictional town wants to free up their IT folks to spend time on value added activities. Right now the amount of time spent managing backups, restoring data and managing the replication processes makes this a challenge. Our town budget is just as tight as everyone else and so finding a creative way to address this issue without needing to hire another resource is critical.

Enter the Microsoft Azure StorSimple family of hybrid cloud storage solutions.

StorSimple is an on-premise enterprise storage area network that interoperates with Microsoft Azure to provide hybrid-cloud storage, data archiving, and fast disaster recovery. The solution replaces traditional backup processes with the concept of “cloud snapshots” that automate the process of creating copies of data remotely in the Azure Storage Cloud.

With our data securely backed up in Microsoft Azure Cloud Storage our town has a couple of options. They can purchase a second StorSimple appliance and deploy it at their co-location facility or they can use a virtual StorSimple appliance in the Microsoft Azure Cloud to quickly bring data or a virtual machine back online resulting in a significantly faster recovery time compare to tape storage.

Our town has realized additional benefits by pursuing this solution. Beyond the backup capability, the StorSimple device provides “bottomless” storage. With three tiers of data storage capability (SSD, HDD, and Cloud) the device intelligently transfers data from higher cost/higher performing storage (SSD) to lower cost HDD and eventually Azure Cloud Storage. This happens automatically based on usage characteristics and other criteria. Further, with the deduplication and compression technologies in the device our town has been able to reduce the total amount of storage space needed to protect its data.

There are other approaches that can be implemented as well using Microsoft Azure Cloud Storage, but with the StorSimple device it provides a significant step forward for cities and towns that have struggled to keep up with the ever growing demands for storage. Every town that has considered implementing a cop-cam officer mounted video camera solution will immediately face significant data storage and backup needs and StorSimple can play a key role in managing these costs.

As a partner with BlumShapiro Consulting, Michael Pelletier leads our Technology Consulting Practice. He consults with a range of businesses and industries on issues related to technology strategy and direction, enterprise and solution architecture, service oriented architecture and solution delivery.