Explaining the Hyper-V authorization model, part two

Hyper-V uses a role based authorisation model for access checks. This series of articles takes a look at the model; defines the available primitives; and walks through a couple of examples. (I actually wrote most of this series many months ago – only finally found the time to post it up!).

Quick links: Part1; Part 2; Part 3; Part 4 

Part one provided information on the primitives available in the AZMan model and looked at the out-of-box Hyper-V configuration. Building on that information, part two takes a deeper look at scopes.

In part one, I talked about the top level scope (aka root or default scope) as the place where global policy is defined. I mentioned that you can also define more constrained scopes and place virtual machines in those scopes.

The first question to answer is “How can you create a ‘Virtual Machine’ scope?”.  Scopes exist at an application level. You can either right-click on an application to create a new scope, as shown in the screenshot below, or use a script if you prefer automation (as I do). (If you’re interested in the specifics of API calls, take a look at https://msdn.microsoft.com/en-us/library/aa375769(VS.85).aspx)

azman-2-1 

Note that the script is the barest minimum – obviously I would recommend you make something more resilient for general use.
Save the following code as “CreateScope.vbs”.

 ' Make sure the script is passed a scope to create
szScope = wscript.arguments.named("scope")

if szScope = "" then
    wscript.echo "CreateScope /scope:<name>"
    wscript.quit
end if

' Need to have an object referencing the store

set oAuthStore = _
   CreateObject("AZRoles.AZAuthorizationStore")
' Initialise the store so that we can update it

oAuthStore.Initialize 0, _
   "msxml://C:\ProgramData\Microsoft\Windows\" & _
   "Hyper-V\InitialStore.xml"
' Open the Hyper-V services application in the store

Set oApplication = _
    oAuthStore.OpenApplication("Hyper-V services")
' Create a new scope

Set oNewScope = _
    oApplication.CreateScope2(szScope)
' Submit it to the store

oNewScope.Submit

To create a scope called “My test VM scope”, from an elevated command prompt, type

cscript createscope.vbs /scope:“My test VM scope”

azman-2-2 

If you already have the Authorisation Manager MMC open after walking through part one, you need to reload the authorisation store by right-clicking on InitialStore.xml in the treeview on the left and selecting Reload. If the Authorisation Manager MMC is not open, open it now and load InitialStore.xml.

When you expand out the tree, you’ll see that a new scope called “My test VM scope” has been created:

azman-2-3 

You can also see that a “VM Scope” has the same primitives available under it as the “Default” Scope – Groups, Role Definitions, Task Definitions and Role Assignments.  You can use the MMC to create role definitions; assign operations to role definitions; create role assignments; link role assignments to role definitions; and assign accounts to role assignments at both the default scope level and at the VM Scope level.

Side note: Personally, to avoid confusion, I would avoid using role definitions in a VM scope unless you really need to keep a role definition so specific that is has to be tied to a particular VM scope. There is little reason to not create all the role definitions at the default scope level.  

At this point, you probably have a question: “Why would I need a ‘Virtual Machine’ scope?” And a great question it is, too. To answer it, let’s consider the following simple scenario:

You have a shared Hyper-V machine. It is used by two users called “John” and “Joe”.  Both John and Joe have a single VM of theirs on that server called “Johns VM” and “Joes VM” respectively.

You want the system configured so that John cannot even see that Joe is a user or has VMs on that machine, and visa-versa. John must be able to perform all operations on his virtual machine, and Joe must be able to perform all operations on his virtual machine. Neither Joe or John should be administrators on the physical machine.

Without virtual machine scopes, this is not possible. Let’s work through how you would configure that scenario. I’m going to start with the blank InitialStore.xml again for this. Using CreateScope.vbs, create scopes called “Johns VM Scope” and “Joes VM Scope”. Reload InitialStore.xml in Authorisation Manager.

azman-2-4 

Within each of these new VM scopes, I’ll now use Authorisation Manager to create a new role assignment called ‘Administrator’ (not to be confused with the default scope role assignment ‘Administrator’ – AZMan permits role assignments with the same name in different scopes), and link it to the default scope ‘Administrator’ role definition. 

Right-click “Role Assignments” under the VM scope and choose New Role Assignment…

azman-2-5 

In the dialog, select the role definition ‘Administrator’ in the default scope(called ‘Where Defined: Application’ in the UI) by checking it, then hit OK.

azman-2-6 
The tree view should look something like this:

azman-2-7 

The next step is to put “John” into the Administrator role assignment in the VM Scope ‘John’s VMs” and to put “Joe” into the Administrators role assignment in the VM Scope ‘Joe’s VMs”. To do this, right-click the newly added role assignment and choose Assign Users and Groups, then From Windows and Active Directory.

azman-2-8 

After making the necessary changes, your policy store should look like the following:

azman-2-9

Important to remember and note is that neither John or Joe are local administrators on the machine. Let’s take a step forward and assume that John and Joe have already created a virtual machine. In the screenshot below, I’m logged on as the local administrator. Remember that built in administrators are administrators in the default scope in the default policy store, and hence can see both virtual machines.

azman-2-10 

The magic sauce needed to make the separation is to move Joes VM into the scope ‘Joes VM Scope’ and move Johns VM into the scope ‘Johns VM Scope’. Now as much as I write my own scripts for just about everything, there are certain times where it makes no sense to reinvent the wheel. If you download BackupVMsAndScopeScripts.zip and expand the files, there is a script called SetScope.vbs

Run the script:

  • cscript setscope.vbs “Johns VM” “Johns VM Scope”
  • and cscript setscope.vbs “Joes VM” “Joes VM Scope”

You’ll get a big spew of output from each command. I’ll leave it an exercise for the reader to modify the script to their needs or develop their own. You want to look at the very last bit of the output which will say “0” if the update succeeded.

azman-2-11 

That’s it from a VM configuration standpoint, but there are still some nuances which needs resolving before John and Joe can use Hyper-V Manager to get their custom view of only their VMs.  As it’s involves several steps, I’ll cover this in part three.

Cheers,
John.