@@ -8544,6 +8544,287 @@ https://social.technet.microsoft.com/Forums/windowsserver/en-US/df3bfd33-c070-4a
8544
8544
}
8545
8545
8546
8546
8547
+ function Remove-DomainObjectAcl {
8548
+ <#
8549
+ .SYNOPSIS
8550
+
8551
+ Removes an ACL from a specific active directory object.
8552
+
8553
+ Author: Will Schroeder (@harmj0y)
8554
+ License: BSD 3-Clause
8555
+ Required Dependencies: Get-DomainObject
8556
+
8557
+ .DESCRIPTION
8558
+
8559
+ This function modifies the ACL/ACE entries for a given Active Directory
8560
+ target object specified by -TargetIdentity. Available -Rights are
8561
+ 'All', 'ResetPassword', 'WriteMembers', 'DCSync', or a manual extended
8562
+ rights GUID can be set with -RightsGUID. These rights are removed from the target
8563
+ object for the specified -PrincipalIdentity.
8564
+
8565
+ .PARAMETER TargetIdentity
8566
+
8567
+ A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
8568
+ SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
8569
+ for the domain object to modify ACLs for. Required. Wildcards accepted.
8570
+
8571
+ .PARAMETER TargetDomain
8572
+
8573
+ Specifies the domain for the TargetIdentity to use for the modification, defaults to the current domain.
8574
+
8575
+ .PARAMETER TargetLDAPFilter
8576
+
8577
+ Specifies an LDAP query string that is used to filter Active Directory object targets.
8578
+
8579
+ .PARAMETER TargetSearchBase
8580
+
8581
+ The LDAP source to search through for targets, e.g. "LDAP://OU=secret,DC=testlab,DC=local"
8582
+ Useful for OU queries.
8583
+
8584
+ .PARAMETER PrincipalIdentity
8585
+
8586
+ A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
8587
+ SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
8588
+ for the domain principal to add for the ACL. Required. Wildcards accepted.
8589
+
8590
+ .PARAMETER PrincipalDomain
8591
+
8592
+ Specifies the domain for the TargetIdentity to use for the principal, defaults to the current domain.
8593
+
8594
+ .PARAMETER Server
8595
+
8596
+ Specifies an Active Directory server (domain controller) to bind to.
8597
+
8598
+ .PARAMETER SearchScope
8599
+
8600
+ Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree).
8601
+
8602
+ .PARAMETER ResultPageSize
8603
+
8604
+ Specifies the PageSize to set for the LDAP searcher object.
8605
+
8606
+ .PARAMETER ServerTimeLimit
8607
+
8608
+ Specifies the maximum amount of time the server spends searching. Default of 120 seconds.
8609
+
8610
+ .PARAMETER Tombstone
8611
+
8612
+ Switch. Specifies that the searcher should also return deleted/tombstoned objects.
8613
+
8614
+ .PARAMETER Credential
8615
+
8616
+ A [Management.Automation.PSCredential] object of alternate credentials
8617
+ for connection to the target domain.
8618
+
8619
+ .PARAMETER Rights
8620
+
8621
+ Rights to add for the principal, 'All', 'ResetPassword', 'WriteMembers', 'DCSync'.
8622
+ Defaults to 'All'.
8623
+
8624
+ .PARAMETER RightsGUID
8625
+
8626
+ Manual GUID representing the right to add to the target.
8627
+
8628
+ .EXAMPLE
8629
+
8630
+ $UserSID = Get-DomainUser user | Select-Object -ExpandProperty objectsid
8631
+ Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID}
8632
+
8633
+ [no results returned]
8634
+
8635
+ Add-DomainObjectAcl -TargetIdentity user2 -PrincipalIdentity user -Rights ResetPassword
8636
+
8637
+ Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID }
8638
+
8639
+ AceQualifier : AccessAllowed
8640
+ ObjectDN : CN=user2,CN=Users,DC=testlab,DC=local
8641
+ ActiveDirectoryRights : ExtendedRight
8642
+ ObjectAceType : User-Force-Change-Password
8643
+ ObjectSID : S-1-5-21-883232822-274137685-4173207997-2105
8644
+ InheritanceFlags : None
8645
+ BinaryLength : 56
8646
+ AceType : AccessAllowedObject
8647
+ ObjectAceFlags : ObjectAceTypePresent
8648
+ IsCallback : False
8649
+ PropagationFlags : None
8650
+ SecurityIdentifier : S-1-5-21-883232822-274137685-4173207997-2104
8651
+ AccessMask : 256
8652
+ AuditFlags : None
8653
+ IsInherited : False
8654
+ AceFlags : None
8655
+ InheritedObjectAceType : All
8656
+ OpaqueLength : 0
8657
+
8658
+
8659
+ Remove-DomainObjectAcl -TargetIdentity user2 -PrincipalIdentity user -Rights ResetPassword
8660
+
8661
+ Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID }
8662
+
8663
+ [no results returned]
8664
+
8665
+ .LINK
8666
+
8667
+ https://social.technet.microsoft.com/Forums/windowsserver/en-US/df3bfd33-c070-4a9c-be98-c4da6e591a0a/forum-faq-using-powershell-to-assign-permissions-on-active-directory-objects?forum=winserverpowershell
8668
+ #>
8669
+
8670
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
8671
+ [CmdletBinding()]
8672
+ Param (
8673
+ [Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
8674
+ [Alias('DistinguishedName', 'SamAccountName', 'Name')]
8675
+ [String[]]
8676
+ $TargetIdentity,
8677
+
8678
+ [ValidateNotNullOrEmpty()]
8679
+ [String]
8680
+ $TargetDomain,
8681
+
8682
+ [ValidateNotNullOrEmpty()]
8683
+ [Alias('Filter')]
8684
+ [String]
8685
+ $TargetLDAPFilter,
8686
+
8687
+ [ValidateNotNullOrEmpty()]
8688
+ [String]
8689
+ $TargetSearchBase,
8690
+
8691
+ [Parameter(Mandatory = $True)]
8692
+ [ValidateNotNullOrEmpty()]
8693
+ [String[]]
8694
+ $PrincipalIdentity,
8695
+
8696
+ [ValidateNotNullOrEmpty()]
8697
+ [String]
8698
+ $PrincipalDomain,
8699
+
8700
+ [ValidateNotNullOrEmpty()]
8701
+ [Alias('DomainController')]
8702
+ [String]
8703
+ $Server,
8704
+
8705
+ [ValidateSet('Base', 'OneLevel', 'Subtree')]
8706
+ [String]
8707
+ $SearchScope = 'Subtree',
8708
+
8709
+ [ValidateRange(1, 10000)]
8710
+ [Int]
8711
+ $ResultPageSize = 200,
8712
+
8713
+ [ValidateRange(1, 10000)]
8714
+ [Int]
8715
+ $ServerTimeLimit,
8716
+
8717
+ [Switch]
8718
+ $Tombstone,
8719
+
8720
+ [Management.Automation.PSCredential]
8721
+ [Management.Automation.CredentialAttribute()]
8722
+ $Credential = [Management.Automation.PSCredential]::Empty,
8723
+
8724
+ [ValidateSet('All', 'ResetPassword', 'WriteMembers', 'DCSync')]
8725
+ [String]
8726
+ $Rights = 'All',
8727
+
8728
+ [Guid]
8729
+ $RightsGUID
8730
+ )
8731
+
8732
+ BEGIN {
8733
+ $TargetSearcherArguments = @{
8734
+ 'Properties' = 'distinguishedname'
8735
+ 'Raw' = $True
8736
+ }
8737
+ if ($PSBoundParameters['TargetDomain']) { $TargetSearcherArguments['Domain'] = $TargetDomain }
8738
+ if ($PSBoundParameters['TargetLDAPFilter']) { $TargetSearcherArguments['LDAPFilter'] = $TargetLDAPFilter }
8739
+ if ($PSBoundParameters['TargetSearchBase']) { $TargetSearcherArguments['SearchBase'] = $TargetSearchBase }
8740
+ if ($PSBoundParameters['Server']) { $TargetSearcherArguments['Server'] = $Server }
8741
+ if ($PSBoundParameters['SearchScope']) { $TargetSearcherArguments['SearchScope'] = $SearchScope }
8742
+ if ($PSBoundParameters['ResultPageSize']) { $TargetSearcherArguments['ResultPageSize'] = $ResultPageSize }
8743
+ if ($PSBoundParameters['ServerTimeLimit']) { $TargetSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
8744
+ if ($PSBoundParameters['Tombstone']) { $TargetSearcherArguments['Tombstone'] = $Tombstone }
8745
+ if ($PSBoundParameters['Credential']) { $TargetSearcherArguments['Credential'] = $Credential }
8746
+
8747
+ $PrincipalSearcherArguments = @{
8748
+ 'Identity' = $PrincipalIdentity
8749
+ 'Properties' = 'distinguishedname,objectsid'
8750
+ }
8751
+ if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain }
8752
+ if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server }
8753
+ if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope }
8754
+ if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize }
8755
+ if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
8756
+ if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone }
8757
+ if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential }
8758
+ $Principals = Get-DomainObject @PrincipalSearcherArguments
8759
+ if (-not $Principals) {
8760
+ throw "Unable to resolve principal: $PrincipalIdentity"
8761
+ }
8762
+ }
8763
+
8764
+ PROCESS {
8765
+ $TargetSearcherArguments['Identity'] = $TargetIdentity
8766
+ $Targets = Get-DomainObject @TargetSearcherArguments
8767
+
8768
+ ForEach ($TargetObject in $Targets) {
8769
+
8770
+ $InheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] 'None'
8771
+ $ControlType = [System.Security.AccessControl.AccessControlType] 'Allow'
8772
+ $ACEs = @()
8773
+
8774
+ if ($RightsGUID) {
8775
+ $GUIDs = @($RightsGUID)
8776
+ }
8777
+ else {
8778
+ $GUIDs = Switch ($Rights) {
8779
+ # ResetPassword doesn't need to know the user's current password
8780
+ 'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' }
8781
+ # allows for the modification of group membership
8782
+ 'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' }
8783
+ # 'DS-Replication-Get-Changes' = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
8784
+ # 'DS-Replication-Get-Changes-All' = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
8785
+ # 'DS-Replication-Get-Changes-In-Filtered-Set' = 89e95b76-444d-4c62-991a-0facbeda640c
8786
+ # when applied to a domain's ACL, allows for the use of DCSync
8787
+ 'DCSync' { '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', '89e95b76-444d-4c62-991a-0facbeda640c'}
8788
+ }
8789
+ }
8790
+
8791
+ ForEach ($PrincipalObject in $Principals) {
8792
+ Write-Verbose "[Remove-DomainObjectAcl] Granting principal $($PrincipalObject.distinguishedname) '$Rights' on $($TargetObject.Properties.distinguishedname)"
8793
+
8794
+ try {
8795
+ $Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$PrincipalObject.objectsid)
8796
+
8797
+ if ($GUIDs) {
8798
+ ForEach ($GUID in $GUIDs) {
8799
+ $NewGUID = New-Object Guid $GUID
8800
+ $ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'ExtendedRight'
8801
+ $ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $NewGUID, $InheritanceType
8802
+ }
8803
+ }
8804
+ else {
8805
+ # deault to GenericAll rights
8806
+ $ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'GenericAll'
8807
+ $ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $InheritanceType
8808
+ }
8809
+
8810
+ # remove all the specified ACEs from the specified object directory entry
8811
+ ForEach ($ACE in $ACEs) {
8812
+ Write-Verbose "[Remove-DomainObjectAcl] Granting principal $($PrincipalObject.distinguishedname) rights GUID '$($ACE.ObjectType)' on $($TargetObject.Properties.distinguishedname)"
8813
+ $TargetEntry = $TargetObject.GetDirectoryEntry()
8814
+ $TargetEntry.PsBase.Options.SecurityMasks = 'Dacl'
8815
+ $TargetEntry.PsBase.ObjectSecurity.RemoveAccessRule($ACE)
8816
+ $TargetEntry.PsBase.CommitChanges()
8817
+ }
8818
+ }
8819
+ catch {
8820
+ Write-Warning "[Remove-DomainObjectAcl] Error granting principal $($PrincipalObject.distinguishedname) '$Rights' on $($TargetObject.Properties.distinguishedname) : $_"
8821
+ }
8822
+ }
8823
+ }
8824
+ }
8825
+ }
8826
+
8827
+
8547
8828
function Find-InterestingDomainAcl {
8548
8829
<#
8549
8830
.SYNOPSIS
@@ -11357,6 +11638,7 @@ http://richardspowershellblog.wordpress.com/2008/05/25/system-directoryservices-
11357
11638
}
11358
11639
}
11359
11640
11641
+
11360
11642
function Remove-DomainGroupMember {
11361
11643
<#
11362
11644
.SYNOPSIS
@@ -11480,6 +11762,7 @@ http://richardspowershellblog.wordpress.com/2008/05/25/system-directoryservices-
11480
11762
}
11481
11763
}
11482
11764
11765
+
11483
11766
function Get-DomainFileServer {
11484
11767
<#
11485
11768
.SYNOPSIS
0 commit comments