Powershell – “Permission Denied” creating a new domain-based Dfs root as non-Administrator

active-directorydelegationpowershell

I have been tasked to delegate a number of everyday tasks in our domain to a group of technicians which does not have Domain Admins membership. One of these tasks is the creation of new domain-based Dfs roots (Server 2008 R2 Enterprise DCs). And this is where I am stuck.

Teh c0de

This is basically just trying to create a domain-based Dfs root, using an arbitrary (first-in-list) Domain Controller as the first Namespace Server:

$DfsnRootName="test"
$DCList = Get-ADDomainController -Filter * | ForEach-Object { ,$_.HostName } 
New-DfsnRoot -Path "\\domain.contoso.com\$DfsnRootName" -TargetPath "\\$($DCList[0])\$dfsnRootName" `
             -Description "Dfs-Root für $DfsnRootName" -EnableAccessBasedEnumeration $true -Type DomainV2
$DCList | ForEach-Object {
    New-DfsnRootTarget -Path "\\domain.contoso.com\$DfsnRootName" `
                       -TargetPath "\\$_\$dfsnRootName" -State Online
}

Teh err0r

The code above is throwing an exception mentioning missing access to a CIM resource. The path ROOT\Microsoft\Windows\DFSN\MSFT_DFSNamespace given in CategoryInfo looks like a WMI path:

New-DfsnRoot : Access to a CIM resource was not available to the client.
At line:1 char:1
+ New-DfsnRoot -Path "\\domain.contoso.com\$DfsnRootName" -TargetPath "\\$($DCList ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (MSFT_DFSNamespace:ROOT\Microsoft\...FT_DFSNamespace) [New-DfsnRoot], CimException
    + FullyQualifiedErrorId : MI RESULT 2,New-DfsnRoot


PS Z:\> $Error[0].CategoryInfo


Category   : PermissionDenied
Activity   : New-DfsnRoot
Reason     : CimException
TargetName : MSFT_DFSNamespace
TargetType : ROOT\Microsoft\Windows\DFSN\MSFT_DFSNamespace

Teh helpless res0luti0n attempts:

I have "Delegated Management permissions" via the Dfs console for the entire domain:
delegate management permissions screenshot

which is effectively just adding a "full control" ACE for the added principal to the CN=Dfs-Configuration,CN=System AD container.

And as I was getting an error indicating missing permissions on the Service Control Manager using the "Add Dfs root" Wizard in dfsmgmt.msc, I used sc sdset scmanager to manipulate the SDDL string adding the respective group with "KA" (key access) permissions, analogous to the BUILTIN\Administrators ACE which exists by default.

This way, I can use the "Add Dfs root" wizard to walk through all the steps, but the creation of the root itself is still failing – "The namespace server \ADSRV0\Test cannot be added. Access is denied"

W00t?

Best Answer

Just Enough Administration (JEA) endpoints are well suited to your task. Designing a JEA endpoint requires three main decisions:

  1. Who can call the JEA endpoint?
  2. What can the caller do?
  3. Who will the call run as?

The PowerShell endpoint in PS 5.1 isn't technically a JEA endpoint, but the mechanism is essentially the same.

Get-PSSessionConfiguration
Name : microsoft.powershell PSVersion : 5.1
StartupScript:
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

From this, the permission groups define who is allowed to call. There is no limitation on the PowerShell endpoint of what can be done, so you have full language capabilities. And lastly, with RunAsUser being blank - the code runs impersonated as the user or credentials provided.

With that basis, look at the help for Register-PSSessionConfiguration, and an overview of JEA.

For bonus points, consider using Group Managed Service Accounts (GMSA) as part of your solution, particularly as the caller.

In your case: You can restrict the endpoint to being called by your limited privilege users.

Then define specific cmdlets you want them to use. These can be built in, or exposed from custom modules you specify. Keep these specific to your task, to avoid elevation of privilege attacks with complicated arguments or too many low level commands exposed that can take advantage of being run as an elevated user.

You could use a RunAsUser of a Domain Administrator, or another account with sufficient privileges.