Private/ConvertFrom-ADSearchFlags.ps1
|
<#
.SYNOPSIS Decode the 'searchFlags' attribute of a schema attribute into named booleans. .DESCRIPTION 'searchFlags' is a bit field carried by every attributeSchema object. Reading it as a raw integer tells nobody anything, so it is decoded here once and reused by every function that reports on the schema. Reference: https://learn.microsoft.com/windows/win32/adschema/a-searchflags | Bit | Name | Meaning | |------|------------------------|----------------------------------------------------------------------| | 1 | fATTINDEX | Indexed | | 2 | fPDNTATTINDEX | Indexed in each container, for one level searches | | 4 | fANR | Part of the Ambiguous Name Resolution set | | 8 | fPRESERVEONDELETE | Kept on the tombstone when the object is deleted | | 16 | fCOPY | Copied when the object is copied | | 32 | fTUPLEINDEX | Tuple index, speeds up searches with a leading wildcard | | 64 | fSUBTREEATTINDEX | Subtree index, for VLV searches | | 128 | fCONFIDENTIAL | Confidential, reading it requires CONTROL_ACCESS | | 256 | fNEVERVALUEAUDIT | Value auditing disabled | | 512 | fRODCFilteredAttribute | NOT replicated to read only domain controllers | Two names deserve attention, because getting them backwards inverts the conclusion of an audit: - bit 256 does not enable auditing, it disables it. The property is named 'NeverAudit'. - bit 512 does not mean the attribute works on an RODC, it means it is filtered out and never replicated to one. The property is named 'RodcFiltered'. ms-LAPS-Password is the reference example, with a 'searchFlags' of 904: 512 + 256 + 128 + 8, so filtered out of the RODCs, never audited, confidential and preserved on delete. .PARAMETER SearchFlags The raw 'searchFlags' value. A null value is treated as zero, which is what an attribute with no flag looks like. .EXAMPLE ConvertFrom-ADSearchFlags -SearchFlags 904 Returns the decoded flags of ms-LAPS-Password. .OUTPUTS System.Management.Automation.PSCustomObject .NOTES Author : Bastien Perez - ITPro-Tips (https://itpro-tips.com) #> function ConvertFrom-ADSearchFlags { [CmdletBinding()] [OutputType([PSCustomObject])] param ( [Parameter(Position = 0, ValueFromPipeline)] [AllowNull()] [System.Nullable[int]]$SearchFlags ) process { # An attribute with no flag at all has an empty searchFlags rather than a zero if ($null -eq $SearchFlags) { $flags = 0 } else { $flags = [int]$SearchFlags } [PSCustomObject][ordered]@{ SearchFlags = $flags Indexed = [bool]($flags -band 1) ContainerIndexed = [bool]($flags -band 2) ANR = [bool]($flags -band 4) PreserveOnDelete = [bool]($flags -band 8) CopyOnCopy = [bool]($flags -band 16) TupleIndexed = [bool]($flags -band 32) SubtreeIndexed = [bool]($flags -band 64) Confidential = [bool]($flags -band 128) NeverAudit = [bool]($flags -band 256) RodcFiltered = [bool]($flags -band 512) } } } |