3

I have a 3rd party DCOM component that I need to install and configure its launch settings in an automated way within my installer (no user intervention). I'm using regsvr32.exe for .dll registration and using powershell for setting up the launch settings. Here's my registration command line:

regsvr32.exe /n /i:"C:\ProgramData\my3rdparty" "C:\Program Files (x86)\My3rdparty\engine.dll"

and here's my powershell:

$Group = 'IIS_IUSRS'
$SystemInfo = (Get-WmiObject -Class Win32_ComputerSystem)
$ComputerName = "{0}.{1}" -f $SystemInfo.Name, $SystemInfo.Domain
$Domain = $SystemInfo.Name
$ComComponentName = 'My 3rd party DCOM name'


function New-DComLaunchACE( 
    [parameter(mandatory=$true)] $Domain, 
    [parameter(mandatory=$true)] $ComputerName, 
    [parameter(mandatory=$true)] $Group )
{

#Create the Trusteee Object
$Trustee = ([WMIClass] "root\cimv2:Win32_Trustee").CreateInstance()

#Search for the user or group, depending on the -Group switch
$account = [WMI] "root\cimv2:Win32_Group.Name='$Group',Domain='$Domain'" 

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

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

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

# COM Access Mask
#   Execute         =  1,
#   Execute_Local   =  2,
#   Execute_Remote  =  4,
#   Activate_Local  =  8,
#   Activate_Remote = 16 
$ACE.AccessMask = 11 # Execute | Execute_Local | Activate_Local
$ACE.AceFlags = 0
$ACE.AceType = 0 # Access allowed
$ACE.Trustee = $Trustee
$ACE
}

function New-DComConfigurationACE( 
    [parameter(mandatory=$true)] $Domain, 
    [parameter(mandatory=$true)] $ComputerName, 
    [parameter(mandatory=$true)] $Group )
{

#Create the Trusteee Object
$Trustee = ([WMIClass] "root\cimv2:Win32_Trustee").CreateInstance()

#Search for the user or group, depending on the -Group switch
$account = [WMI] "root\cimv2:Win32_Group.Name='$Group',Domain='$Domain'" 

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

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

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

# COM Access Mask
$ACE.AccessMask = 268435456 # Full Control
$ACE.AceFlags = 0
$ACE.AceType = 0 # Access allowed
$ACE.Trustee = $Trustee
$ACE
}

# Configure the DComConfg settings for the component so it can be activated    & launched locally
$dcom = Get-WMIObject Win32_DCOMApplicationSetting -Filter  "Description='$ComComponentName'" -EnableAllPrivileges


if ($dcom -ne $null)
{
write-host "DCOM is registered! Setting up permissions"

$sd = $dcom.GetLaunchSecurityDescriptor().Descriptor
$csd = $dcom.GetConfigurationSecurityDescriptor().Descriptor

#$nsAce = $sd.Dacl | Where {$_.Trustee.Name -eq $Group}

$newAce = New-DComLaunchACE -Domain $Domain -ComputerName $ComputerName -  Group $Group
$sd.Dacl += $newAce

$newAce2 = New-DComConfigurationACE -Domain $Domain -ComputerName   $ComputerName -Group $Group
$csd.Dacl += $newAce2

# Set both the launch and the configuration descriptors ...
$dcom.SetLaunchSecurityDescriptor($sd)
$dcom.SetConfigurationSecurityDescriptor($csd)

}
else
{
Write-Host "DCOM not found."
}

My problem is that the DCOM component is not found by the powershell script even though it is successfully registered.

However, I found out that if I open mmc console with

mmc comexp.msc /32

and navigate to "DCOM Config" folder - I can see my Dcom component there... and if I run my powershell script after that - it works!

screenshot of component services window

It looks like if the system is searching in a cache and not updating the cache when a new DCOM is installed. when opening the mmc console - the system is refreshing the cache and the dcom becomes available. But these are my assumptions.

Is there something I'm doing wrong? How can I make sure that the DCOM is available to powershell script right after it is installed?

Thanks much!

  • whats the delay between running regsvr32 and your script? I'm assuming the full configuration hasn't been completed before you are accessing it. Ive used this cmd a billion times but never had a prob accessing afterwards, but there was always prob 10 seconds before reg and trying it., but I did use /i. What are you doing in your reg procedure? – Adam Tuliper Jan 15 '16 at 18:35
  • Adam - Thank you for your comment! I have tried putting delays of up to 60 seconds between the registration and the script. Didn't help. I'm using /n and /i in my registration.. is that what's you're asking? – Zohrab Broyan Jan 15 '16 at 19:55

1 Answers1

0

There's some interesting information we've published here it seems being that you are doing 32 bit on a 64 bit system (assuming the 64 bit as all modern systems are): https://msdn.microsoft.com/en-us/library/windows/desktop/ms678426(v=vs.85).aspx

So instead of the below (added just to show there's seemingly an issue related to the resolution you noted) try running it from: C:/windows/syswow64/regsvr32.exe

Dcomcnfg.exe and 64-bit Applications

On x64 operating systems from Windows XP to Windows Server 2008, the 64-bit version of DCOMCNFG.EXE does not correctly configure 32-bit DCOM applications for remote activation. This behavior causes components that are meant to be activated remotely instead being activated locally. This behavior does not occur in Windows 7 and Windows Server 2008 R2 and higher versions. The workaround is to use the 32-bit version of DCOMCNFG. Run the 32-bit version of mmc.exe and load the 32-bit version of the Component Services snap-in by using the following command line.

C:\WINDOWS\SysWOW64>mmc comexp.msc /32

The 32-bit version of Component Services correctly registers 32-bit DCOM applications for remote activation.

Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
  • Adam - Thanks for your suggestion. I tried using `C:/windows/syswow64/regsvr32.exe` but it did not resolve the problem. Just to be clear - the dll registration is successful and I get the popup window saying **"DllInstall in [PATH] succeeded"**. However, powershell script does not find the DCOM component to assign local launch permissions. When I run the mmc console - I can see the DCOM is there... and if I run the powershell after the mmc was run - then the script is successful and it can find the DCOM as well. So I think the mmc console does something that makes the DCOM available to PS. – Zohrab Broyan Jan 18 '16 at 17:38
  • @Zohrab, did you ever get this resolved? What I have found is that my PS script (similar to yours) will ONLY work if I have already added the Component Services snapin by doing: C:\WINDOWS\SysWOW64\mmc comexp.msc /32 'Component Services', 'Computers', 'MY Computer', 'DCOM Config'. Is there a way to load the snapin programmatically? – RGuggisberg Feb 28 '19 at 18:40