none
Using PowerShell to Set DCOM Permissions for FIM Self-Service Password Reset

    General discussion

  •   Summary
     

    Setting the DCOM permissions is a bit tedious and prone to error, especially if you have multiple environments and both a primary and standby server to configure.
    This little script is provided as a way to simplify your deployment of FIM Self-Service Password Reset configuration tasks.

      note Note
     

    See also the script for setting WMI permissions.

     

    PARAM( 
    	[string]$Principal = $(throw "`nMissing -Principal DOMAIN\FIM PasswordSet"), 
    	$Computers = $(throw "`nMissing -Computers ('fimnode01','fimnode02')"))
    
    # USAGE: 
    #
    # .\Set-FIM-DCOM.ps1 -Principal "DOMAIN\<group or username>" -Computers ('<server1>', '<server2>',...)
    #
    # EXAMPLE:
    # .\Set-FIM-DCOM.ps1 -Principal "DOMAIN\FIM PasswordSet" -Computers ('fimsyncprimary', 'fimsyncstandby')
    #
    # Inspired by Karl Mitschke's post:
    # http://unlockpowershell.wordpress.com/2009/11/20/script-remote-dcom-wmi-access-for-a-domain-user/
    
    Write-Host "Set-FIM-DCOM - Updates DCOM Permissions for FIM Password Reset"
    Write-Host "`tWritten by Brad Turner (bturner@ensynch.com)"
    Write-Host "`tBlog: http://www.identitychaos.com"
    
    function get-sid
    {
     PARAM ($DSIdentity)
     $ID = new-object System.Security.Principal.NTAccount($DSIdentity)
     return $ID.Translate( [System.Security.Principal.SecurityIdentifier] ).toString()
    }
    
    $sid = get-sid $Principal
    
    #MachineLaunchRestriction - Local Launch, Remote Launch, Local Activation, Remote Activation
    $DCOMSDDLMachineLaunchRestriction = "A;;CCDCLCSWRP;;;$sid"
    
    #MachineAccessRestriction - Local Access, Remote Access
    $DCOMSDDLMachineAccessRestriction = "A;;CCDCLC;;;$sid"
    
    #DefaultLaunchPermission - Local Launch, Remote Launch, Local Activation, Remote Activation
    $DCOMSDDLDefaultLaunchPermission = "A;;CCDCLCSWRP;;;$sid"
    
    #DefaultAccessPermision - Local Access, Remote Access
    $DCOMSDDLDefaultAccessPermision = "A;;CCDCLC;;;$sid"
    
    #PartialMatch
    $DCOMSDDLPartialMatch = "A;;\w+;;;$sid"
    
    foreach ($strcomputer in $computers)
    {
     write-host "`nWorking on $strcomputer with principal $Principal ($sid):"
     # Get the respective binary values of the DCOM registry entries
     $Reg = [WMIClass]"\\$strcomputer\root\default:StdRegProv"
     $DCOMMachineLaunchRestriction = $Reg.GetBinaryValue(2147483650,"software\microsoft\ole","MachineLaunchRestriction").uValue
     $DCOMMachineAccessRestriction = $Reg.GetBinaryValue(2147483650,"software\microsoft\ole","MachineAccessRestriction").uValue
     $DCOMDefaultLaunchPermission = $Reg.GetBinaryValue(2147483650,"software\microsoft\ole","DefaultLaunchPermission").uValue
     $DCOMDefaultAccessPermission = $Reg.GetBinaryValue(2147483650,"software\microsoft\ole","DefaultAccessPermission").uValue
    
     # Convert the current permissions to SDDL
     write-host "`tConverting current permissions to SDDL format..."
     $converter = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper
     $CurrentDCOMSDDLMachineLaunchRestriction = $converter.BinarySDToSDDL($DCOMMachineLaunchRestriction)
     $CurrentDCOMSDDLMachineAccessRestriction = $converter.BinarySDToSDDL($DCOMMachineAccessRestriction)
     $CurrentDCOMSDDLDefaultLaunchPermission = $converter.BinarySDToSDDL($DCOMDefaultLaunchPermission)
     $CurrentDCOMSDDLDefaultAccessPermission = $converter.BinarySDToSDDL($DCOMDefaultAccessPermission)
    
     # Build the new permissions
     write-host "`tBuilding the new permissions..."
     if (($CurrentDCOMSDDLMachineLaunchRestriction.SDDL -match $DCOMSDDLPartialMatch) -and ($CurrentDCOMSDDLMachineLaunchRestriction.SDDL -notmatch $DCOMSDDLMachineLaunchRestriction))
     {
       $NewDCOMSDDLMachineLaunchRestriction = $CurrentDCOMSDDLMachineLaunchRestriction.SDDL -replace $DCOMSDDLPartialMatch, $DCOMSDDLMachineLaunchRestriction
     }
     else
     {
       $NewDCOMSDDLMachineLaunchRestriction = $CurrentDCOMSDDLMachineLaunchRestriction.SDDL += "(" + $DCOMSDDLMachineLaunchRestriction + ")"
     }
      
     if (($CurrentDCOMSDDLMachineAccessRestriction.SDDL -match $DCOMSDDLPartialMatch) -and ($CurrentDCOMSDDLMachineAccessRestriction.SDDL -notmatch $DCOMSDDLMachineAccessRestriction))
     {
      $NewDCOMSDDLMachineAccessRestriction = $CurrentDCOMSDDLMachineAccessRestriction.SDDL -replace $DCOMSDDLPartialMatch, $DCOMSDDLMachineLaunchRestriction
     }
     else
     {
       $NewDCOMSDDLMachineAccessRestriction = $CurrentDCOMSDDLMachineAccessRestriction.SDDL += "(" + $DCOMSDDLMachineAccessRestriction + ")"
     }
    
     if (($CurrentDCOMSDDLDefaultLaunchPermission.SDDL -match $DCOMSDDLPartialMatch) -and ($CurrentDCOMSDDLDefaultLaunchPermission.SDDL -notmatch $DCOMSDDLDefaultLaunchPermission))
     {
       $NewDCOMSDDLDefaultLaunchPermission = $CurrentDCOMSDDLDefaultLaunchPermission.SDDL -replace $DCOMSDDLPartialMatch, $DCOMSDDLDefaultLaunchPermission
     }
     else
     {
       $NewDCOMSDDLDefaultLaunchPermission = $CurrentDCOMSDDLDefaultLaunchPermission.SDDL += "(" + $DCOMSDDLDefaultLaunchPermission + ")"
     }
    
     if (($CurrentDCOMSDDLDefaultAccessPermission.SDDL -match $DCOMSDDLPartialMatch) -and ($CurrentDCOMSDDLDefaultAccessPermission.SDDL -notmatch $DCOMSDDLDefaultAccessPermision))
     {
       $NewDCOMSDDLDefaultAccessPermission = $CurrentDCOMSDDLDefaultAccessPermission.SDDL -replace $DCOMSDDLPartialMatch, $DCOMSDDLDefaultAccessPermision
     }
     else
     {
       $NewDCOMSDDLDefaultAccessPermission = $CurrentDCOMSDDLDefaultAccessPermission.SDDL += "(" + $DCOMSDDLDefaultAccessPermision + ")"
     }
    
     # Convert SDDL back to Binary
     write-host "`tConverting SDDL back into binary form..."
     $DCOMbinarySDMachineLaunchRestriction = $converter.SDDLToBinarySD($NewDCOMSDDLMachineLaunchRestriction)
     $DCOMconvertedPermissionsMachineLaunchRestriction = ,$DCOMbinarySDMachineLaunchRestriction.BinarySD
    
     $DCOMbinarySDMachineAccessRestriction = $converter.SDDLToBinarySD($NewDCOMSDDLMachineAccessRestriction)
     $DCOMconvertedPermissionsMachineAccessRestriction = ,$DCOMbinarySDMachineAccessRestriction.BinarySD
    
     $DCOMbinarySDDefaultLaunchPermission = $converter.SDDLToBinarySD($NewDCOMSDDLDefaultLaunchPermission)
     $DCOMconvertedPermissionDefaultLaunchPermission = ,$DCOMbinarySDDefaultLaunchPermission.BinarySD
    
     $DCOMbinarySDDefaultAccessPermission = $converter.SDDLToBinarySD($NewDCOMSDDLDefaultAccessPermission)
     $DCOMconvertedPermissionsDefaultAccessPermission = ,$DCOMbinarySDDefaultAccessPermission.BinarySD
    
     # Apply the changes
     write-host "`tApplying changes..."
     if ($CurrentDCOMSDDLMachineLaunchRestriction.SDDL -match $DCOMSDDLMachineLaunchRestriction)
     {
       write-host "`t`tCurrent MachineLaunchRestriction matches desired value."
     }
     else
     {
       $result = $Reg.SetBinaryValue(2147483650,"software\microsoft\ole","MachineLaunchRestriction", $DCOMbinarySDMachineLaunchRestriction.binarySD)
       if($result.ReturnValue='0'){write-host "  Applied MachineLaunchRestricition complete."}
     }
    
     if ($CurrentDCOMSDDLMachineAccessRestriction.SDDL -match $DCOMSDDLMachineAccessRestriction)
     {
       write-host "`t`tCurrent MachineAccessRestriction matches desired value."
     }
     else
     {
       $result = $Reg.SetBinaryValue(2147483650,"software\microsoft\ole","MachineAccessRestriction", $DCOMbinarySDMachineAccessRestriction.binarySD)
       if($result.ReturnValue='0'){write-host "  Applied MachineAccessRestricition complete."}
     }
    
     if ($CurrentDCOMSDDLDefaultLaunchPermission.SDDL -match $DCOMSDDLDefaultLaunchPermission)
     {
       write-host "`t`tCurrent DefaultLaunchPermission matches desired value."
     }
     else
     {
       $result = $Reg.SetBinaryValue(2147483650,"software\microsoft\ole","DefaultLaunchPermission", $DCOMbinarySDDefaultLaunchPermission.binarySD)
       if($result.ReturnValue='0'){write-host "  Applied DefaultLaunchPermission complete."}
     }
    
     if ($CurrentDCOMSDDLDefaultAccessPermission.SDDL -match $DCOMSDDLDefaultAccessPermision)
     {
       write-host "`t`tCurrent DefaultAccessPermission matches desired value."
     }
     else
     {
       $result = $Reg.SetBinaryValue(2147483650,"software\microsoft\ole","DefaultAccessPermission", $DCOMbinarySDDefaultAccessPermission.binarySD)
       if($result.ReturnValue='0'){write-host "  Applied DefaultAccessPermission complete."}
    
     }
    }
    #----------------------------------------------------------------------------------------------------------
     trap 
     { 
     $exMessage = $_.Exception.Message
     if($exMessage.StartsWith("L:"))
     {write-host "`n" $exMessage.substring(2) "`n" -foregroundcolor white -backgroundcolor darkblue}
     else {write-host "`nError: " $exMessage "`n" -foregroundcolor white -backgroundcolor darkred}
     Exit
     }
    #----------------------------------------------------------------------------------------------------------
    

     

      Go to the FIM ScriptBox

    Brad Turner, ILM MVP - Ensynch, Inc - www.identitychaos.com
    Sunday, June 13, 2010 12:08 AM

All replies

  • Awesome! Does this work for both Windows Server 2008 and R2? Does it solve the issue solved by http://www.wictorwilen.se/Post/Post.aspx?id=492? If so will it still work for Windows Server 2008?
    David Lundell www.ilmBestPractices.com
    Wednesday, June 23, 2010 9:57 PM
  • David, it does not fix the DCOM error in the reference article, it just sets permissions required for password reset withing DCOM.
    Brad Turner, ILM MVP - Ensynch, Inc - www.identitychaos.com [If a post helps to resolve your issue, please click the "Mark as Answer" or "Helpful" button at the top of that post. By marking a post as Answered or Helpful, you help others find the answer faster.]
    Monday, February 14, 2011 2:45 AM
  • I received the following error after running the script, any ideas on what might be casusing that?

    Error:  Cannot convert value "\\<fim>\root\default:StdRegProv" to type "System.Management.ManagementClass". Error: "The
    RPC server is unavailable. (Exception from HRESULT: 0x800706BA)"

    I'm trying to run this on Server 2008 R2

    Wednesday, April 13, 2011 12:54 PM
  • Abraham,

    You are likely encountering a connectivity or firewall issue due to the "RPC Server is unavailable" error.  I would ensure that you can resolve the system, and be able to access the registry remotely.


    Brad Turner - www.identitychaos.com [If a post helps to resolve your issue, please click the "Mark as Answer" or "Helpful" button at the top of that post. By marking a post as Answered or Helpful, you help others find the answer faster.]
    Wednesday, April 13, 2011 6:28 PM
  • Thanks for the reply. Turns out it was was syntax error on my part.
    Thursday, April 14, 2011 11:42 AM
  • $NewDCOMSDDLMachineAccessRestriction = $CurrentDCOMSDDLMachineAccessRestriction.SDDL += "(" + $DCOMSDDLMachineAccessRestriction + ")"
    Unless I'm mistaken, there is a bug in this line, and the other three lines like it. By using "+=" on the CurrentDCOMSDDLMachineAccessRestriction.SDDL property, it modifies the value and it thus when the property is used lower down to compare old vs new, you are actually comparing new vs new and it doesn't execute the update. I think this should just be "+". I found this to be a problem if I was adding a new Principal, but not when updating and existing Principal.
    marlobello@msn.com
    Friday, August 19, 2011 5:33 PM
  • Hallo,

    I don't understand the example in the script. If my domain is Fabfikam and my sync server is Server01, what shoult i write in the script?

    With regards, Guy Horn.


    GH
    Saturday, September 17, 2011 3:43 PM
  • (The syntax is in the script text..)

    .\Set-FIM-DCOM.ps1 -Principal "Fabrikam\AccountName" -Computers ('Server1')

     


    Frank C. Drewes III - Consultant: Certified Security Solutions - My blog: http://www.css-security.com/author/fdrewes
    Saturday, September 17, 2011 5:19 PM
  • Hallo. I don't know where or how to use this string: .\Set-FIM-DCOM.ps1 -Principal "Fabrikam\AccountName" -Computers ('Server1'). I tried it above and exactly where it stand but without succes.  Can you give an example? Thanks.
    GH
    Tuesday, September 20, 2011 12:42 PM
  • Amazing sir - thank you very much for this. -Fred
    Friday, February 10, 2012 1:14 PM
  • I’m researching a method to set the permissions for an application within DCOM. I work for a financial corporation and a custom financial application has been written. The software installs a few “applications” underneath the DCOM Configuration – <CustomAppName>. We have to manually edit the properties using the GUI dcomcnfg and adjust the ACL permissions often on about 300 machines throughout the year.  I’m learning powershell and I was hoping that I could modify your script to make changes to the custom application name instead of the root DCOM.

    Tuesday, May 15, 2012 3:39 PM
  • No problems, adapt as needed, rinse and repeat.

    Brad Turner - www.identitychaos.com [If a post helps to resolve your issue, please click the "Mark as Answer" or "Helpful" button at the top of that post. By marking a post as Answered or Helpful, you help others find the answer faster.]

    Wednesday, May 16, 2012 12:43 AM