private/new-OUPermission.ps1
function new-oupermission { [CmdletBinding(DefaultParameterSetName = 'Normal')] Param ( # The principal that the ACE refers to [Parameter(mandatory, parametersetname = "Normal", ValueFromPipelineByPropertyName )] [Parameter(mandatory, parametersetname = "Extended", ValueFromPipelineByPropertyName )] [ValidateScript( { [System.Security.Principal.NTAccount]::new($_).translate([System.security.Principal.SecurityIdentifier]) })] $Principal, # The principal that the ACE refers to [Parameter(mandatory, parametersetname = "IdentityNormal", ValueFromPipelineByPropertyName )] [Parameter(mandatory, parametersetname = "IdentityExtended", ValueFromPipelineByPropertyName )] [System.Security.Principal.IdentityReference] $Identity, # ADRight: Generally CreateChild, DeleteChild, GenericAll, or something involving "ExtendedRight". [Parameter(ValueFromPipelineByPropertyName )] [System.directoryservices.ActiveDirectoryRights] $ADRight, # a specific extended right, which must be a proper AD Schema extendedright [Parameter(parametersetname = "IdentityExtended", mandatory, ValueFromPipelineByPropertyName )] [Parameter(parametersetname = "Extended", Mandatory, ValueFromPipelineByPropertyName )] #[ArgumentCompleter( { (Get-ADObjectGUIDs | where-object { $_.type -eq "Right" }).name })] #[ValidateScript( { $myArg = $_; (Get-ADObjectGUIDs | where-object { $_.name -eq $myArg -and $_.type -eq "Right" }) })] [String]$ExtendedRight, # If ADRight is "writeproperty", this can be the target attribute. If it's createchild, it's the child object type. Must be a valid AD Schema object [Parameter(parametersetname = "IdentityNormal", ValueFromPipelineByPropertyName )] [Parameter(parametersetname = "Normal", ValueFromPipelineByPropertyName )] #[ArgumentCompleter( { (Get-ADObjectGUIDs | where-object { $_.type -eq "Object" }).name })] #[ValidateScript( { $myArg = $_; (Get-ADObjectGUIDs | where-object { $_.name -eq $myArg -and $_.type -eq "Object" }) })] [String[]]$TargetObject, # Also known as InheritedObjectType, shown as "Applies to" in the GUI. This is an object GUID. This must be a valid AD Schema object name or array of objects [Parameter(ValueFromPipelineByPropertyName )] #[ArgumentCompleter( { (Get-ADObjectGUIDs | where-object { $_.type -eq "Object" }).name })] #[ValidateScript( { $myArg = $_; (Get-ADObjectGUIDs | where-object { $_.name -eq $myArg -and $_.type -eq "Object" }) })] [String[]]$AppliesTo, # Whether the ACE is an allow or deny entry [Parameter(ValueFromPipelineByPropertyName )] [Validateset("Allow", "Deny")] [System.security.AccessControl.AccessControlType] $Action = "Allow", # Whether and how the inheritance applies to descendents [Parameter(ValueFromPipelineByPropertyName )] [System.DirectoryServices.ActiveDirectorySecurityInheritance] $InheritanceType = "All", [Parameter()] $ObjectGUIDs = $(write-warning "This is slow!"; get-ADObjectGUIDs) ) Begin { $sw = [System.Diagnostics.Stopwatch]::StartNew() $acesCreated = 0 } Process { try { if (-not $identity) { write-loghandler -level "Debug" -message "Resolving principal to identity" -indentLevel 1 $PrincipalName = $principal $principalSID = [System.Security.Principal.NTAccount]::new($principalName).translate([System.security.Principal.SecurityIdentifier]) $identity = [System.Security.Principal.IdentityReference] $principalSID } else { write-loghandler -level "Debug" -message "Resolving identity to principal" -indentLevel 1 $principalName = $identity.translate([System.Security.Principal.NTAccount]).value.toString() } write-loghandler -level "Debug" -message "Resolving AppliesTo to IOTs" -indentLevel 1 try { $inheritedObjectTypeList = @( If ($appliesTo) { $AppliesTo | foreach-object { $IOTName = $_ @{ Name = $IOTName GUID = ($($ObjectGUIds).where({ $_.name -eq $IOTName -and $_.type -eq "Object" })).GUID } } } else { @{ Name = "(All / Unspec)" GUID = [GUID]"00000000-0000-0000-0000-000000000000" } } ) } catch { Write-LogHandler -level "Warning" -message "Failed to resolve appliesTo ($appliesTo) to an IOT GUID." throw $_ } write-loghandler -level "Debug" -message "Resolving ADRights / ExtendedRights" If ($ExtendedRight -and -not $ADRight) { write-loghandler -level "Debug" -message "Setting ADRight to 'ExtendedRight'" -indentLevel 2 $ADRight = [System.directoryservices.ActiveDirectoryRights]"ExtendedRight" } write-loghandler -level "Debug" -message "Resolving ObjectTypes" try { $ObjectTypeList = $( if ($extendedRight) { write-loghandler -level "Debug" -message "ObjectType as extended right ($extendedRight)" -indentLevel 2 @{ Name = $extendedRight Type = "ExtendedRight" GUID = $($ObjectGUIDs).where( { $_.name -eq $extendedRight -and $_.type -eq "Right"} ).GUID } } elseif ($targetObject) { write-loghandler -level "Debug" -message "ObjectType as schema class or attribute" -indentLevel 2 $targetObject | foreach-object { $objectName = $_ @{ Name = $objectName Type = "Schema class or attribute" GUID = $($ObjectGUIDs).where( { $_.name -eq $objectName -and $_.type -eq "object"} ).GUID } } write-loghandler -level "Debug" -message "finished resolving objectType" -indentLevel 2 } else { write-loghandler -level "Debug" -message "Setting null (wildcard) objectType / attribute" -indentLevel 2 @{ Name = "Null" Type = "(Unknown / wildcard)" GUID = [GUID]"00000000-0000-0000-0000-000000000000" } } ) } catch { write-loghandler -level "Warning" -message "Failed to resolve an objectType from extendedRight($extendedRight)/targetObject($targetObject)" -indentLevel 1 throw $_ } write-loghandler -level "Debug" -message "Cycling through IOT and object lists to create single master list" -indentLevel 1 $ACEParamList = @( foreach ($InheritedObjectType in $inheritedObjectTypeList) { foreach ($ObjectType in $ObjectTypeList) { @{ PrincipalName = $principalName Identity = $Identity ADRight = $ADRight Action = $Action objectType = $ObjectType['GUID'] InheritanceType = $InheritanceType InheritedObjectType = $inheritedObjectType['GUID'] } write-loghandler -level "Debug" -target $Principalname -message ("{0,-5} {1,-16} on: {2,-24} IOT: {3,-24} {4}" -f $action, $ADRight, ($ExtendedRight + $objectType['Name']), $inheritedObjectType['Name'], $PrincipalName) -indentLevel 1 } } ) $ACEParamList | foreach-object -parallel { New-object System.DirectoryServices.ActiveDirectoryAccessRule($_['Identity'], $_['ADRight'], $_['Action'], $_['objectType'], $_['InheritanceType'], $_['inheritedObjectType']) } $acesCreated +=$ACEParamList.count } catch { $_ | format-list * -force write-loghandler -level "warning" -message "WHOOPS" } } End{ $sw.stop() write-loghandler -level "Debug" -message "Created $AcesCreated ACEs in $($sw.ElapsedMilliseconds) ms" } } |