Using PowerShell to Modify DCOM Launch & Activation Settings

A few weeks ago I had the need to customize DCOM launch & activation permissions for a COM component.  I came up with this hack, er script, that I thought I would share “as-is”.  If anybody wants to take this and run with it – go for it.

function New-DComAccessControlEntry {
param(
[Parameter(Mandatory=$true, Position=0)]
[string]
$Domain,

[Parameter(Mandatory=$true, Position=1)]
[string]
$Name,

[string]
$ComputerName = ".",

[switch]
$Group
)

#Create the Trusteee Object
$Trustee = ([WMIClass] "\\$ComputerName\root\cimv2:Win32_Trustee").CreateInstance()
#Search for the user or group, depending on the -Group switch
if (!$group) {
$account = [WMI] "\\$ComputerName\root\cimv2:Win32_Account.Name='$Name',Domain='$Domain'" }
else {
$account = [WMI] "\\$ComputerName\root\cimv2:Win32_Group.Name='$Name',Domain='$Domain'"
}

#Get the SID for the found account.
$accountSID = [WMI] "\\$ComputerName\root\cimv2:Win32_SID.SID='$($account.sid)'"

#Setup Trusteee object
$Trustee.Domain = $Domain
$Trustee.Name = $Name
$Trustee.SID = $accountSID.BinaryRepresentation

#Create ACE (Access Control List) object.
$ACE = ([WMIClass] "\\$ComputerName\root\cimv2:Win32_ACE").CreateInstance()

# COM Access Mask
# Execute = 1,
# Execute_Local = 2,
# Execute_Remote = 4,
# Activate_Local = 8,
# Activate_Remote = 16

#Setup the rest of the ACE.
$ACE.AccessMask = 11 # Execute | Execute_Local | Activate_Local
$ACE.AceFlags = 0
$ACE.AceType = 0 # Access allowed
$ACE.Trustee = $Trustee
$ACE
}

$Name = 'IUsr'
$ComComponentName = 'foo'

# Configure the DComConfg settings for the component so it can be activated & launched locally
$dcom = Get-WMIObject Win32_DCOMApplicationSetting `
            -Filter "Description='$ComComponentName'" -EnableAllPrivileges
$sd = $dcom.GetLaunchSecurityDescriptor().Descriptor
$nsAce = $sd.Dacl | Where {$_.Trustee.Name -eq $Name}
if ($nsAce) {
$nsAce.AccessMask = 11
}
else {
$newAce = New-DComAccessControlEntry $env:COMPUTERNAME -Name $Name
$sd.Dacl += $newAce
}

$dcom.SetLaunchSecurityDescriptor($sd)

Have fun!

This entry was posted in PowerShell. Bookmark the permalink.

9 Responses to Using PowerShell to Modify DCOM Launch & Activation Settings

  1. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #39 - Flo's Datacenter Report

  2. Pingback: Dell Community

  3. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #39 - Dell TechCenter - TechCenter - Dell Community

  4. G.K says:

    Thanks Keith, this script is very useful, Thanks again!

  5. Chris Ranney says:

    Any example using CIM available?

  6. Blake says:

    I wrote a script based off of your example. The changes work, but they aren’t persisting. When I get the appropriate Win32_DCOMApplicationSetting object, I enable all privileges. Also, when setting properties on this object explicitly, like
    $WMIObject.AuthenticationLevel = 1
    I have to call the Put() method afterwards on the object for the setting to persist.

    Is there something similar I have to do to make the SetLaunchSecurityDescriptor() method call persist? It works, because if I output the DACL I modified directly afterwards, it shows the correct AccessMask I modified. However, that change does not persist.

    Here’s my script:

    ****************************************************
    $WMIObject = Get-WMIObject -Class Win32_DCOMApplicationSetting -Filter “Caption=’$AppToGet'” -EnableAllPrivileges
    $WMIObject.AuthenticationLevel = 1 # Sets to “None”
    $WMIObject.Put() # Saves property set
    $serviceDescriptor = $WMIObject.GetLaunchSecurityDescriptor().Descriptor
    $accessControl = $serviceDescriptor.DACL | Where {$_.Trustee.Name -eq ‘ANONYMOUS LOGON’}
    $accessControl.AccessMask = 31
    $WMIObject.SetLaunchSecurityDescriptor($serviceDescriptor)
    ****************************************************

    The access mask change does not persist. Any thoughts? And thank you for your script.

  7. Kirk Junker says:

    Thanks for this script. I found that I would needed to cast the $newAce object to a System.Management.ManagementBaseObject before adding it to the DACL list, otherwise I got an invalid cast error from PSObject to ManagementBaseObject. Solution found here: http://measureofchaos.wordpress.com/2012/03/09/modifying-embedded-properties-in-wmi-using-powershell/

    Like so:

    In the Else statement:

    $newAce = New-DComAccessControlEntry $env:COMPUTERNAME -Name $Name
    #cast to a ManagementBaseObject
    $newAce = [System.Management.ManagementBaseObject] $newAce
    $sd.Dacl += $newAce

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 )

Connecting to %s