locked
Change DCOM permission RRS feed

  • Question

  • I'm creating a function for modifying DCOM permissions. I'm able to add a user, but I'm not able to modify or remove a user.

    The script is below. I want to modify the AccessMask of an existing entry (or first delete the entry and then add it again).

    Function Set-DcomPermissions ($User, $Domain, $Permission, $Rights)
    {
        [int]$AccesMask = 1
        foreach ($Right in $Rights)
        {
            switch ($Right)
            {
                "Local launch"      {$AccesMask = $AccesMask + 2}
                "Remote Launch"     {$AccesMask = $AccesMask + 4}
                "Local Activation"  {$AccesMask = $AccesMask + 8}
                "Remote Activation" {$AccesMask = $AccesMask + 16}
            }
        }
        $wmi = Get-WmiObject -Class Win32_DCOMApplicationSetting -EnableAllPrivileges | Where-Object {$_.LocalService -eq "SrvCtrl"}
    
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$desc  = $wmi.GetLaunchSecurityDescriptor().descriptor}
            "AccessPermission"              {$desc  = $wmi.GetAccessSecurityDescriptor().descriptor}
            "ConfigurationPermission"       {$desc  = $wmi.GetConfigurationSecurityDescriptor().descriptor}
        }
    
        #Check if user already has permissions
        If (($Domain -in $desc.DACL.Trustee.Domain) -and ($User -in $desc.DACL.Trustee.Name))
        {
            write-host "Modify User"
            $nsAce = $desc.DACL |  where-object {$_.Trustee.Name -eq $User -and $_.Trustee.Domain -eq $Domain}
            $nsAce.AccessMask = $AccesMask
        }
        Else
        {
            write-host "Add User"
            $trusteeObj = ([wmiclass]'Win32_Trustee').psbase.CreateInstance()
            $trusteeObj.Domain = $Domain
            $trusteeObj.Name = $User
    
            $ace = ([wmiclass]'Win32_ACE').psbase.CreateInstance()
            $ace.AccessMask = $AccesMask
            $ace.trustee = $trusteeObj
    
            $desc.DACL += [System.Management.ManagementBaseObject]$ace
        }
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$wmi.SetLaunchSecurityDescriptor($desc)}
            "AccessPermission"              {$wmi.SetAccessSecurityDescriptor($desc)}
            "ConfigurationPermission"       {$wmi.SetAccessSecurityDescriptor($desc)}
        }
    }
    
    $LocalGroup = "SQL-AuditSQLConfig"
    $Domain = "Server1"
    
    Set-DcomPermissions -User $LocalGroup -Domain $Domain -Permission "LaunchAndActivationPermission" -Rights @("Local launch", "Local Activation")
    

    Regards,
    Marco

    Thursday, June 22, 2017 12:41 PM

Answers

  • Hi Marco,

    >>The script is below. I want to modify the AccessMask of an existing entry (or first delete the entry and then add it again)

    I didn't find out how to modify, but i'd prefer to use GPO to modify, as it is really simple.

    Here is the location:

    Group Policy object: Computer Configuration \Windows Settings \Local Policies \Security Options

    Besides, try: SubInACL.exe:

    https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=23510

    Best regards,

    Andy


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    • Marked as answer by Marco1234567 Monday, June 26, 2017 9:10 AM
    Friday, June 23, 2017 6:54 AM
  • Andy,

    I do agree that GPO's are the way to go. I have also found a solution for the problem above. I create an empty Win32_SecurityDescriptor object and add all the DACL's (except the one I want to change) to it. After that I add the user.

    In the future I will start using GPO's instead of this method.

    Function Set-DcomPermissions ($User, $Domain, $Permission, $Rights)
    {
        [int]$AccesMask = 1
        foreach ($Right in $Rights)
        {
            switch ($Right)
            {
                "Local launch"      {$AccesMask = $AccesMask + 2}
                "Remote Launch"     {$AccesMask = $AccesMask + 4}
                "Local Activation"  {$AccesMask = $AccesMask + 8}
                "Remote Activation" {$AccesMask = $AccesMask + 16}
            }
        }
        write-host $AccesMask
        $wmi = Get-WmiObject -Class Win32_DCOMApplicationSetting -EnableAllPrivileges | Where-Object {$_.LocalService -eq "SrvCtrl"}
    
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$desc  = $wmi.GetLaunchSecurityDescriptor().descriptor}
            "AccessPermission"              {$desc  = $wmi.GetAccessSecurityDescriptor().descriptor}
            "ConfigurationPermission"       {$desc  = $wmi.GetConfigurationSecurityDescriptor().descriptor}
        }
    
        #Create empty Win32_SecurityDescriptor object
        $sclass = [wmiclass]”\\.\root\cimv2:Win32_SecurityDescriptor”
        $newdesc = $sclass.CreateInstance()
        $newdesc.ControlFlags = $desc.ControlFlags
        $newdesc.Group = $desc.Group
        $newdesc.Owner = $desc.Owner
        $newdesc.SACL = $desc.SACL
        $newdesc.Owner = $desc.Owner
    
        #Remove user if it already has permissions
        ForEach ($oace in $desc.DACL)
        {
            If (($Domain -in $oace.Trustee.Domain) -and ($User -in $oace.Trustee.Name))
            { 
                #Nothing: This removes the user from the list of DACL's
            }
            Else
            {
                $newdesc.DACL += $oace
            }
        }
       
        # Add user (again) with correct permissions
        $trusteeObj = ([wmiclass]'Win32_Trustee').psbase.CreateInstance()
        $trusteeObj.Domain = $Domain
        $trusteeObj.Name = $User
    
        $ace = ([wmiclass]'Win32_ACE').psbase.CreateInstance()
        $ace.AccessMask = $AccesMask
        $ace.trustee = $trusteeObj
    
        $newdesc.DACL += [System.Management.ManagementBaseObject]$ace
    
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$wmi.SetLaunchSecurityDescriptor($newdesc)}
            "AccessPermission"              {$wmi.SetAccessSecurityDescriptor($newdesc)}
            "ConfigurationPermission"       {$wmi.SetAccessSecurityDescriptor($newdesc)}
        }
    }
    
    $LocalGroup = "SQL-AuditSQLConfig"
    $Domain = "Server1"
    
    Set-DcomPermissions -User $LocalGroup -Domain $Domain -Permission "LaunchAndActivationPermission" -Rights @("Local launch", "Local Activation") #Local launch, Remote Launch, Local Activation ,Remote Activation 
    

    • Marked as answer by Marco1234567 Monday, June 26, 2017 9:10 AM
    Monday, June 26, 2017 9:10 AM

All replies

  • Hi Marco,

    >>The script is below. I want to modify the AccessMask of an existing entry (or first delete the entry and then add it again)

    I didn't find out how to modify, but i'd prefer to use GPO to modify, as it is really simple.

    Here is the location:

    Group Policy object: Computer Configuration \Windows Settings \Local Policies \Security Options

    Besides, try: SubInACL.exe:

    https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=23510

    Best regards,

    Andy


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    • Marked as answer by Marco1234567 Monday, June 26, 2017 9:10 AM
    Friday, June 23, 2017 6:54 AM
  • Andy,

    I do agree that GPO's are the way to go. I have also found a solution for the problem above. I create an empty Win32_SecurityDescriptor object and add all the DACL's (except the one I want to change) to it. After that I add the user.

    In the future I will start using GPO's instead of this method.

    Function Set-DcomPermissions ($User, $Domain, $Permission, $Rights)
    {
        [int]$AccesMask = 1
        foreach ($Right in $Rights)
        {
            switch ($Right)
            {
                "Local launch"      {$AccesMask = $AccesMask + 2}
                "Remote Launch"     {$AccesMask = $AccesMask + 4}
                "Local Activation"  {$AccesMask = $AccesMask + 8}
                "Remote Activation" {$AccesMask = $AccesMask + 16}
            }
        }
        write-host $AccesMask
        $wmi = Get-WmiObject -Class Win32_DCOMApplicationSetting -EnableAllPrivileges | Where-Object {$_.LocalService -eq "SrvCtrl"}
    
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$desc  = $wmi.GetLaunchSecurityDescriptor().descriptor}
            "AccessPermission"              {$desc  = $wmi.GetAccessSecurityDescriptor().descriptor}
            "ConfigurationPermission"       {$desc  = $wmi.GetConfigurationSecurityDescriptor().descriptor}
        }
    
        #Create empty Win32_SecurityDescriptor object
        $sclass = [wmiclass]”\\.\root\cimv2:Win32_SecurityDescriptor”
        $newdesc = $sclass.CreateInstance()
        $newdesc.ControlFlags = $desc.ControlFlags
        $newdesc.Group = $desc.Group
        $newdesc.Owner = $desc.Owner
        $newdesc.SACL = $desc.SACL
        $newdesc.Owner = $desc.Owner
    
        #Remove user if it already has permissions
        ForEach ($oace in $desc.DACL)
        {
            If (($Domain -in $oace.Trustee.Domain) -and ($User -in $oace.Trustee.Name))
            { 
                #Nothing: This removes the user from the list of DACL's
            }
            Else
            {
                $newdesc.DACL += $oace
            }
        }
       
        # Add user (again) with correct permissions
        $trusteeObj = ([wmiclass]'Win32_Trustee').psbase.CreateInstance()
        $trusteeObj.Domain = $Domain
        $trusteeObj.Name = $User
    
        $ace = ([wmiclass]'Win32_ACE').psbase.CreateInstance()
        $ace.AccessMask = $AccesMask
        $ace.trustee = $trusteeObj
    
        $newdesc.DACL += [System.Management.ManagementBaseObject]$ace
    
        Switch ($Permission)
        {
            "LaunchAndActivationPermission" {$wmi.SetLaunchSecurityDescriptor($newdesc)}
            "AccessPermission"              {$wmi.SetAccessSecurityDescriptor($newdesc)}
            "ConfigurationPermission"       {$wmi.SetAccessSecurityDescriptor($newdesc)}
        }
    }
    
    $LocalGroup = "SQL-AuditSQLConfig"
    $Domain = "Server1"
    
    Set-DcomPermissions -User $LocalGroup -Domain $Domain -Permission "LaunchAndActivationPermission" -Rights @("Local launch", "Local Activation") #Local launch, Remote Launch, Local Activation ,Remote Activation 
    

    • Marked as answer by Marco1234567 Monday, June 26, 2017 9:10 AM
    Monday, June 26, 2017 9:10 AM