Automating DCOM ACL with PowerShell

Sometimes you need to set explicit permissions on DCOM objects. You can do this using dcomcnfg.exe. With dcomcnfg.exe you can set permissions on all DCOM objects on a computer. However, this is doing it manually. 🙂 If you ever need to automate this step, you can do it using PowerShell, and here is how. Please note you have to run PowerShell as Administrator.

dcomcnfg

Automating DCOM ACL with PowerShell

There are 5 steps to configure DCOM ACL.

1.) Get WMI object

2.) Get Descriptor

3.) Create Trustee and assign it rights

4.) Add Trustee to Descriptor

5.) Set WMI object

In step one, we get WMI object for DCOM application we want to set permissions. In below example, we get settings for Messaging application

$wmi = Get-WmiObject -Class Win32_DCOMApplicationSetting -Filter ‘caption=”Messages”‘ -EnableAllPrivileges

In step two we get current security descriptor for this object, so we can add permissions to existing set. We can get and set permissions for all 3 types

$descL = $wmi.GetLaunchSecurityDescriptor().descriptor
$descA = $wmi.GetAccessSecurityDescriptor().descriptor
$descC = $wmi.GetConfigurationSecurityDescriptor().descriptor

Image from GUI:

dcomcnfgSec

In step three we create our own trustee object, which we will use to assign rights to. It consists of Domain, username and permissions we would like to assign to it. In this example we will set all permissions to allow to user object Interactive.

$trusteeObj = ([wmiclass]’Win32_Trustee’).psbase.CreateInstance()
$trusteeObj.Domain = “NT authority”
$trusteeObj.Name = “Interactive”

$ace = ([wmiclass]’Win32_ACE’).psbase.CreateInstance()
$ace.AccessMask = 31
$ace.trustee = $trusteeObj

If you need to set different permissions then in example above, you can get AccesssMask values by manually setting permissions in GUI as you need them and then read them using PowerShell. In step two we got current descriptor, from which we can read current permissions.

First we need to get DACL list:

$descL.[X].DACL

in this object you have current Trustee and it’s AccessMask.

From here on it is very simple…

In step four we add our object we created in step 3 to descriptor

$descL.DACL += [System.Management.ManagementBaseObject]$ace
$descA.DACL += [System.Management.ManagementBaseObject]$ace
$descC.DACL += [System.Management.ManagementBaseObject]$ace

And in step five we write is back using WMI.

$wmi.SetLaunchSecurityDescriptor($descL)
$wmi.SetAccessSecurityDescriptor($descA)
$wmi.SetConfigurationSecurityDescriptor($descC)

We can see the changes we made using dcomcnfg.exe or PowerShell

dcomcnfgSec2

Again, do not forget to run PowerShell as Administrator! 😉

Code is available for download on TechNet:

https://gallery.technet.microsoft.com/Set-DCOM-ACL-with-650fa48d

Hope this helps you.

Advertisements

12 thoughts on “Automating DCOM ACL with PowerShell

  1. I believe you mean
    $wmi.SetLaunchSecurityDescriptor($descL)
    $wmi.SetAccessSecurityDescriptor($descA)
    $wmi.SetConfigurationSecurityDescriptor($descC)

    instead of

    $wmi.SetLaunchSecurityDescriptor($descL)
    $wmi.SetAccessSecurityDescriptor($descA)
    $wmi.SetAccessSecurityDescriptor($descC)

    Like

  2. Trying this on MsDtsServer120 application and all descriptors are empty and can’t process any further with setting up local user group to have access to this application (OS 2012, SQL 2014). Any idea? Thanks

    Like

      • Here’s part of the code where $srv is simply another new-object where ComputerNamePhysicalNetBIOS provides the server name instead of SQL instance. Then I will finish with the 3 set commands.
        I’m not sure that the trustee is the issue but rather the empty descriptor from the DCOM application itself.

        $Name = ‘Distributed COM Users’
        $ComputerName = $srv.ComputerNamePhysicalNetBIOS
        #Get wmi object
        $wmi = Get-WMIObject -Class Win32_DCOMApplicationSetting -Filter ‘LocalService like “MsDtsServer%”‘ -EnableAllPrivileges

        #Get Security Descriptors
        $descL = $wmi.GetLaunchSecurityDescriptor().descriptor
        $descA = $wmi.GetAccessSecurityDescriptor().descriptor
        $descC = $wmi.GetConfigurationSecurityDescriptor().descriptor

        #Create the Trusteee Object
        $trusteeObj = ([wmiclass]’Win32_Trustee’).psbase.CreateInstance()
        $trusteeObj.Domain = $ComputerName
        $trusteeObj.Name = $Name

        Thanks

        Like

      • Hi,

        When I run your $wmi = … command it fails. Does $wmi variable at your end contain any value, or does it return error?

        Try running the following:
        $wmi = Get-WMIObject -Class Win32_DCOMApplicationSetting -Filter “LocalService like ‘MsDtsServer%'” -EnableAllPrivileges

        PS: sometimes single quotes get messed up by HTML, try retyping them.

        Like

      • Hi JanBK,
        Understandably, these quote issues do happen with copy pasting. For example, in copying over your line, poweshell would not parse it. So I had to replace them with my US english culture. Reversing the quotes provides the same info for the $wmi object. I’m curious to know if you do have SQL set up in your environment and can see securitydescriptors for MsDtsServer.
        Thanks
        Charbs

        Like

      • Hi charbs,

        I just tried on my test SQL, it works here, but PowerShell has to run as admin, if I start it as non elevated user, then I get empty descriptor. Did you try it from elevated PowerShell?

        Like

      • Got it working . The only thing left is to understand the mask for the Configuration Permissions descriptor. The 31 doesn’t reflect the Full Control and Read values.
        Thanks again.
        Charbs

        Like

  3. You know it’s going to be one of those days when…..
    I just realised that I’m in the middle of configuring a new SQL installation and testing various scripts. It’s Microsoft after all.
    Reboot !
    Now I can see results in my descriptors. Sorry for the run around on that point.

    The only thing now is that I don’t have anything set when I check in the GUI. The ‘Distributed COM Users’ local group doesn’t appear in the three Security Descriptors.
    I do have that new trustee in the descL and others though.
    I wonder if there’s an alter() somewhere to set things properly.
    Thanks
    Charbs

    Like

    • Thanks for everything JanBK
      The domain needs to be ‘BUILTIN’ for any local groups.
      The Full Control for MsDTSServer Configuration Access is 983103 and Special Permission 268435456 so I simply reused the same $ace with each value and set the descriptor accordingly.
      Charbs

      Like

  4. Pingback: DCOM machine access and launch permissions help - How to Code .NET

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s