Packer.Images/scripts/ADDS/payload/scripts/04.Delegation of Control.ps1

133 lines
5.3 KiB
PowerShell

#Requires -Modules 'ActiveDirectory'
Param(
[Parameter(Mandatory)]
[hashtable]$Parameter
)
# Only executed on primary or standalone Domain Controller
If (@('primary','standalone') -contains $Parameter['deployment.type']) {
$PSDrive = Get-PSDrive -Name 'AD'
If ([boolean]$PSDrive -eq $False) {
$NewPSDriveSplat = @{
Name = 'ADDS'
Root = ''
PSProvider = 'ActiveDirectory'
}
$PSDrive = New-PSDrive @NewPSDriveSplat
}
$GetContentSplat = @{
Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', ".yml")
Raw = $True
}
$RawContent = Get-Content @GetContentSplat
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
# Check if the respective .yml file declared substitutions which need to be parsed
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
ForEach ($Pattern in $YamlDocuments[-1].Variables) {
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
}
# Perform conversion to Yaml again, now with parsed file contents
$ConvertFromYamlSplat = @{
Yaml = $RawContent
AllDocuments = $True
}
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
$Delegations = $YamlDocuments[0..($YamlDocuments.Count - 2)]
}
Else {
$Delegations = $YamlDocuments
}
# Store GUIDs for all known AD schema classes
$GUIDMap, $GetADObjectSplat = @{}, @{
SearchBase = (Get-ADRootDSE).SchemaNamingContext
LDAPFilter = '(schemaidguid=*)'
Properties = 'lDAPDisplayName','schemaIDGUID'
}
Get-ADObject @GetADObjectSplat | ForEach-Object {
$GUIDMap[$_.lDAPDisplayName] = [GUID]$_.schemaIDGUID
}
# Store GUIDs for all extended rights
$GetADObjectSplat = @{
SearchBase = (Get-ADRootDSE).ConfigurationNamingContext
LDAPFilter = '(&(objectclass=controlAccessRight)(rightsguid=*))'
Properties = 'displayName','rightsGuid'
}
Get-ADObject @GetADObjectSplat | ForEach-Object {
$GUIDMap[$_.displayName] = [GUID]$_.rightsGuid
}
$GUIDMap['null'] = [Guid]::Empty
ForEach ($Entry in $Delegations.DelegationEntries) {
$GetADObjectSplat = @{
Filter = "sAMAccountName -eq '$($Entry.Principal)'"
Properties = 'objectSID'
}
$Principal = Get-ADObject @GetADObjectSplat
ForEach ($OU in $Entry.OrganizationalUnit) {
$GetADObjectSplat = @{
Identity = ($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))
ErrorAction = 'SilentlyContinue'
}
$OU = Get-ADObject @GetADObjectSplat
If ([boolean]$OU) {
$GetACLSPlat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
}
$ACL = Get-ACL @GetACLSPlat
}
Else {
# Respective OU was not found in Active Directory; skipping permission assignment
Continue
}
ForEach ($Rule in $Entry.AccessRules) {
If ($Rule.ObjectType -eq '') {
$Rule.ObjectType = 'null'
}
If ($Rule.InheritedObjectType -eq '') {
$Rule.InheritedObjectType = 'null'
}
$NewACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
# An IdentityReference object that identifies the trustee of the access rule.
[System.Security.Principal.IdentityReference]$Principal.objectSID,
# A combination of one or more of the ActiveDirectoryRights enumeration values that specifies the rights of the access rule.
[System.DirectoryServices.ActiveDirectoryRights]$Rule.ActiveDirectoryRights,
# One of the AccessControlType enumeration values that specifies the access rule type.
[System.Security.AccessControl.AccessControlType]$Rule.AccessControlType,
# The schema GUID of the object to which the access rule applies.
[Guid]$GUIDMap[$Rule.ObjectType],
# One of the ActiveDirectorySecurityInheritance enumeration values that specifies the inheritance type of the access rule.
[System.DirectoryServices.ActiveDirectorySecurityInheritance]$Rule.ActiveDirectorySecurityInheritance,
# The schema GUID of the child object type that can inherit this access rule.
[Guid]$GUIDMap[$Rule.InheritedObjectType]
)
$ACL.AddAccessRule($NewACE)
}
$SetAclSplat = @{
Path = "$($PSDrive.Name):\$($OU.DistinguishedName)"
AclObject = $ACL
ErrorAction = 'Continue'
}
Set-Acl @SetAclSplat
}
}
If ([boolean]($PSDrive.Name -eq 'ADDS') -eq $True) {
$RemovePSDriveSplat = @{
Name = 'ADDS'
Force = $True
Confirm = $False
}
Remove-PSDrive @RemovePSDriveSplat | Out-Null
}
}