@@ -6400,6 +6400,330 @@ scriptpath
6400
6400
}
6401
6401
6402
6402
6403
+ function ConvertFrom-LDAPLogonHours {
6404
+ <#
6405
+ .SYNOPSIS
6406
+
6407
+ Converts the LDAP LogonHours array to a processible object.
6408
+
6409
+ Author: Lee Christensen (@tifkin_)
6410
+ License: BSD 3-Clause
6411
+ Required Dependencies: None
6412
+
6413
+ .DESCRIPTION
6414
+
6415
+ Converts the LDAP LogonHours array to a processible object. Each entry
6416
+ property in the output object corresponds to a day of the week and hour during
6417
+ the day (in UTC) indicating whether or not the user can logon at the specified
6418
+ hour.
6419
+
6420
+ .PARAMETER LogonHoursArray
6421
+
6422
+ 21-byte LDAP hours array.
6423
+
6424
+ .EXAMPLE
6425
+
6426
+ $hours = (Get-DomainUser -LDAPFilter 'userworkstations=*')[0].logonhours
6427
+ ConvertFrom-LDAPLogonHours $hours
6428
+
6429
+ Gets the logonhours array from the first AD user with logon restrictions.
6430
+
6431
+ .OUTPUTS
6432
+
6433
+ PowerView.LogonHours
6434
+ #>
6435
+
6436
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
6437
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
6438
+ [OutputType('PowerView.LogonHours')]
6439
+ [CmdletBinding()]
6440
+ Param (
6441
+ [Parameter( ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
6442
+ [ValidateNotNullOrEmpty()]
6443
+ [byte[]]
6444
+ $LogonHoursArray
6445
+ )
6446
+
6447
+ Begin {
6448
+ if($LogonHoursArray.Count -ne 21) {
6449
+ throw "LogonHoursArray is the incorrect length"
6450
+ }
6451
+
6452
+ function ConvertTo-LogonHoursArray {
6453
+ Param (
6454
+ [int[]]
6455
+ $HoursArr
6456
+ )
6457
+
6458
+ $LogonHours = New-Object bool[] 24
6459
+ for($i=0; $i -lt 3; $i++) {
6460
+ $Byte = $HoursArr[$i]
6461
+ $Offset = $i * 8
6462
+ $Str = [Convert]::ToString($Byte,2).PadLeft(8,'0')
6463
+
6464
+ $LogonHours[$Offset+0] = [bool] [convert]::ToInt32([string]$Str[7])
6465
+ $LogonHours[$Offset+1] = [bool] [convert]::ToInt32([string]$Str[6])
6466
+ $LogonHours[$Offset+2] = [bool] [convert]::ToInt32([string]$Str[5])
6467
+ $LogonHours[$Offset+3] = [bool] [convert]::ToInt32([string]$Str[4])
6468
+ $LogonHours[$Offset+4] = [bool] [convert]::ToInt32([string]$Str[3])
6469
+ $LogonHours[$Offset+5] = [bool] [convert]::ToInt32([string]$Str[2])
6470
+ $LogonHours[$Offset+6] = [bool] [convert]::ToInt32([string]$Str[1])
6471
+ $LogonHours[$Offset+7] = [bool] [convert]::ToInt32([string]$Str[0])
6472
+ }
6473
+
6474
+ $LogonHours
6475
+ }
6476
+ }
6477
+
6478
+ Process {
6479
+ $Output = @{
6480
+ Sunday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[0..2]
6481
+ Monday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[3..5]
6482
+ Tuesday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[6..8]
6483
+ Wednesday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[9..11]
6484
+ Thurs = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[12..14]
6485
+ Friday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[15..17]
6486
+ Saturday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[18..20]
6487
+ }
6488
+
6489
+ $Output = New-Object PSObject -Property $Output
6490
+ $Output.PSObject.TypeNames.Insert(0, 'PowerView.LogonHours')
6491
+ $Output
6492
+ }
6493
+ }
6494
+
6495
+
6496
+ function New-ADObjectAccessControlEntry {
6497
+ <#
6498
+ .SYNOPSIS
6499
+
6500
+ Creates a new Active Directory object-specific access control entry.
6501
+
6502
+ Author: Lee Christensen (@tifkin_)
6503
+ License: BSD 3-Clause
6504
+ Required Dependencies: None
6505
+
6506
+ .DESCRIPTION
6507
+
6508
+ Creates a new object-specific access control entry (ACE). The ACE could be
6509
+ used for auditing access to an object or controlling access to objects.
6510
+
6511
+ .PARAMETER PrincipalIdentity
6512
+
6513
+ A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local),
6514
+ SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201)
6515
+ for the domain principal to add for the ACL. Required. Wildcards accepted.
6516
+
6517
+ .PARAMETER PrincipalDomain
6518
+
6519
+ Specifies the domain for the TargetIdentity to use for the principal, defaults to the current domain.
6520
+
6521
+ .PARAMETER PrincipalSearchBase
6522
+
6523
+ The LDAP source to search through for principals, e.g. "LDAP://OU=secret,DC=testlab,DC=local"
6524
+ Useful for OU queries.
6525
+
6526
+ .PARAMETER Server
6527
+
6528
+ Specifies an Active Directory server (domain controller) to bind to.
6529
+
6530
+ .PARAMETER SearchScope
6531
+
6532
+ Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree).
6533
+
6534
+ .PARAMETER ResultPageSize
6535
+
6536
+ Specifies the PageSize to set for the LDAP searcher object.
6537
+
6538
+ .PARAMETER ServerTimeLimit
6539
+
6540
+ Specifies the maximum amount of time the server spends searching. Default of 120 seconds.
6541
+
6542
+ .PARAMETER Tombstone
6543
+
6544
+ Switch. Specifies that the searcher should also return deleted/tombstoned objects.
6545
+
6546
+ .PARAMETER Credential
6547
+
6548
+ A [Management.Automation.PSCredential] object of alternate credentials
6549
+ for connection to the target domain.
6550
+
6551
+ .PARAMETER Right
6552
+
6553
+ Specifies the rights set on the Active Directory object.
6554
+
6555
+ .PARAMETER AccessControlType
6556
+
6557
+ Specifies the type of ACE (allow or deny)
6558
+
6559
+ .PARAMETER AuditFlag
6560
+
6561
+ For audit ACEs, specifies when to create an audit log (on success or failure)
6562
+
6563
+ .PARAMETER ObjectType
6564
+
6565
+ Specifies the GUID of the object that the ACE applies to.
6566
+
6567
+ .PARAMETER InheritanceType
6568
+
6569
+ Specifies how the ACE applies to the object and/or its children.
6570
+
6571
+ .PARAMETER InheritedObjectType
6572
+
6573
+ Specifies the type of object that can inherit the ACE.
6574
+
6575
+ .EXAMPLE
6576
+
6577
+ $Guids = Get-DomainGUIDMap
6578
+ $AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name
6579
+ $CompPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'Computer'} | select -ExpandProperty name
6580
+ $ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity itadmin -Right ExtendedRight,ReadProperty -AccessControlType Allow -ObjectType $AdmPropertyGuid -InheritanceType All -InheritedObjectType $CompPropertyGuid
6581
+ $OU = Get-DomainOU -Raw Workstations
6582
+ $DsEntry = $OU.GetDirectoryEntry()
6583
+ $dsEntry.PsBase.Options.SecurityMasks = 'Dacl'
6584
+ $dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)
6585
+ $dsEntry.PsBase.CommitChanges()
6586
+
6587
+ Adds an ACE to all computer objects in the OU "Workstations" permitting the
6588
+ user "itadmin" to read the confidential ms-Mcs-AdmPwd computer property.
6589
+
6590
+ .OUTPUTS
6591
+
6592
+ System.Security.AccessControl.AuthorizationRule
6593
+ #>
6594
+
6595
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
6596
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
6597
+ [OutputType('System.Security.AccessControl.AuthorizationRule')]
6598
+ [CmdletBinding()]
6599
+ Param (
6600
+ [Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, Mandatory = $True)]
6601
+ [Alias('DistinguishedName', 'SamAccountName', 'Name')]
6602
+ [String]
6603
+ $PrincipalIdentity,
6604
+
6605
+ [ValidateNotNullOrEmpty()]
6606
+ [String]
6607
+ $PrincipalDomain,
6608
+
6609
+ [ValidateNotNullOrEmpty()]
6610
+ [Alias('DomainController')]
6611
+ [String]
6612
+ $Server,
6613
+
6614
+ [ValidateSet('Base', 'OneLevel', 'Subtree')]
6615
+ [String]
6616
+ $SearchScope = 'Subtree',
6617
+
6618
+ [ValidateRange(1, 10000)]
6619
+ [Int]
6620
+ $ResultPageSize = 200,
6621
+
6622
+ [ValidateRange(1, 10000)]
6623
+ [Int]
6624
+ $ServerTimeLimit,
6625
+
6626
+ [Switch]
6627
+ $Tombstone,
6628
+
6629
+ [Management.Automation.PSCredential]
6630
+ [Management.Automation.CredentialAttribute()]
6631
+ $Credential = [Management.Automation.PSCredential]::Empty,
6632
+
6633
+ [Parameter(Mandatory = $True)]
6634
+ [ValidateSet('AccessSystemSecurity', 'CreateChild','Delete','DeleteChild','DeleteTree','ExtendedRight','GenericAll','GenericExecute','GenericRead','GenericWrite','ListChildren','ListObject','ReadControl','ReadProperty','Self','Synchronize','WriteDacl','WriteOwner','WriteProperty')]
6635
+ $Right,
6636
+
6637
+ [Parameter(Mandatory = $True, ParameterSetName=’AccessRuleType’)]
6638
+ [ValidateSet('Allow', 'Deny')]
6639
+ [String[]]
6640
+ $AccessControlType,
6641
+
6642
+ [Parameter(Mandatory = $True, ParameterSetName=’AuditRuleType’)]
6643
+ [ValidateSet('Success', 'Failure')]
6644
+ [String]
6645
+ $AuditFlag,
6646
+
6647
+ [Parameter(Mandatory = $False, ParameterSetName=’AccessRuleType’)]
6648
+ [Parameter(Mandatory = $False, ParameterSetName=’AuditRuleType’)]
6649
+ [Parameter(Mandatory = $False, ParameterSetName=’ObjectGuidLookup’)]
6650
+ [Guid]
6651
+ $ObjectType,
6652
+
6653
+ [ValidateSet('All', 'Children','Descendents','None','SelfAndChildren')]
6654
+ [String]
6655
+ $InheritanceType,
6656
+
6657
+ [Guid]
6658
+ $InheritedObjectType
6659
+ )
6660
+
6661
+ Begin {
6662
+ $PrincipalSearcherArguments = @{
6663
+ 'Identity' = $PrincipalIdentity
6664
+ 'Properties' = 'distinguishedname,objectsid'
6665
+ }
6666
+ if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain }
6667
+ if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server }
6668
+ if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope }
6669
+ if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize }
6670
+ if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit }
6671
+ if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone }
6672
+ if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential }
6673
+ $Principal = Get-DomainObject @PrincipalSearcherArguments
6674
+ if (-not $Principal) {
6675
+ throw "Unable to resolve principal: $PrincipalIdentity"
6676
+ } elseif($Principal.Count -gt 1) {
6677
+ throw "PrincipalIdentity matches multiple AD objects, but only one is allowed"
6678
+ }
6679
+
6680
+ $ADRight = 0
6681
+ foreach($r in $Right) {
6682
+ $ADRight = $ADRight -bor (([System.DirectoryServices.ActiveDirectoryRights]$r).value__)
6683
+ }
6684
+ $ADRight = [System.DirectoryServices.ActiveDirectoryRights]$ADRight
6685
+
6686
+ $Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$Principal.objectsid)
6687
+ }
6688
+
6689
+ Process {
6690
+ if($PSCmdlet.ParameterSetName -eq 'AuditRuleType') {
6691
+
6692
+ if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
6693
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag
6694
+ } elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
6695
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType)
6696
+ } elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) {
6697
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType), $InheritedObjectType
6698
+ } elseif($ObjectType -ne $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
6699
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType
6700
+ } elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
6701
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType, $InheritanceType
6702
+ } elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) {
6703
+ New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType, $InheritanceType, $InheritedObjectType
6704
+ }
6705
+
6706
+ } else {
6707
+
6708
+ if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
6709
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType
6710
+ } elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
6711
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType)
6712
+ } elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) {
6713
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType), $InheritedObjectType
6714
+ } elseif($ObjectType -ne $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) {
6715
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType
6716
+ } elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) {
6717
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType, $InheritanceType
6718
+ } elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) {
6719
+ New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType, $InheritanceType, $InheritedObjectType
6720
+ }
6721
+
6722
+ }
6723
+ }
6724
+ }
6725
+
6726
+
6403
6727
function Set-DomainObjectOwner {
6404
6728
<#
6405
6729
.SYNOPSIS
@@ -6910,15 +7234,6 @@ for the domain principal to add for the ACL. Required. Wildcards accepted.
6910
7234
6911
7235
Specifies the domain for the TargetIdentity to use for the principal, defaults to the current domain.
6912
7236
6913
- .PARAMETER PrincipalLDAPFilter
6914
-
6915
- Specifies an LDAP query string that is used to filter for the Active Directory object principal.
6916
-
6917
- .PARAMETER PrincipalSearchBase
6918
-
6919
- The LDAP source to search through for principals, e.g. "LDAP://OU=secret,DC=testlab,DC=local"
6920
- Useful for OU queries.
6921
-
6922
7237
.PARAMETER Server
6923
7238
6924
7239
Specifies an Active Directory server (domain controller) to bind to.
0 commit comments