Use PowerShell to Add Permissions to AD Container Objects for Machine Accounts Without using the AD Module

I am taking on SCCM 2012 at work, so currently, I’m working on a PowerShell script that installs all the prerequisites before installing the actual product. The list of prereqs is about a mile long, but so far, I’m batting 1.000.

One of the prereqs is to add Full Control permissions on the System Management container in AD for the machine account SCCM is being installed on. This is probably a relatively trivial task while using the AD module. However, I want the script to be a seamless process for the installer. I don’t want to have to connect to a DC or using 3rd party modules. My goal is to have the installer start the script and walk away, returning to a fully prepared machine.

I attempted to use DSACLS, but figured out that command does not support machine accounts, just user and group accounts.

Get-ACL works when you can access the AD: partition, but I can’t do that without importing the AD module.

The solution involved calling a System class called ActiveDirectoryAccessRule (New-Object System.DirectoryServices.ActiveDirectoryAccessRule). The class has several overloaded constructors that require a specific set a data in a specific order. The constructor that finally worked for me was:

ActiveDirectoryAccessRule(IdentityReference, ActiveDirectoryRights, AccessControlType, ActiveDirectorySecurityInheritance, Guid)

You can specify a GUID, but looking at the existing access rules in AD, they all appear to be NULL.

So, without further explanation, here be the script:

Function Add-CMADAccess {
  <#
  .SYNOPSIS
  Adds Full Control to System Management folder in AD
  .DESCRIPTION
  Adds Full Control to System Management folder in AD
  .EXAMPLE
  Add-CMADAccess $Domain
  #>
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$False,
    HelpMessage="In what Domain is the CM Computer located?")]
    [Alias('D')]
    [ValidateLength(3,30)]
    [string[]]$Domain = $env:USERDOMAIN
  )

  Begin {
    $LogPath = "CMAddADPerms.log"
    $CMComputer = "$CMComputer$"
  }

  Process {
    $DomainDN = ([ADSI]'').DistinguishedName
    $Path = "OU=Computers,OU=test,DC=contoso,DC=com"
    $SysManObj = [ADSI]("LDAP://CN=System Management,CN=System,$DomainDN")

    $CMNTAccount = New-Object System.Security.Principal.NTAccount("$Domain\$CMComputer")

    $ActiveDirectoryRights = "GenericAll"
    $AccessControlType = "Allow"
    $Inherit = "SelfAndChildren"
    $nullGUID = [guid]'00000000-0000-0000-0000-000000000000'

    $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $CMNTAccount, $ActiveDirectoryRights, $AccessControlType, $Inherit, $nullGUID
    $SysManObj.psbase.ObjectSecurity.AddAccessRule($ACE)
    $SysManObj.psbase.commitchanges()
  }
}

One Comment

Leave a Reply