Last active
March 2, 2019 08:47
-
-
Save Trucido/5d5aaa5920ae3968cffbc9a6a0e8d3bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## File: Get-FileAttributesEx.ps1 | |
<# | |
.SYNOPSIS | |
Lists NTFS file or folder attributes and flags. | |
.DESCRIPTION | |
Lists many undocumented or otherwise inaccessible file attributes, flags, and ACL properties. | |
.PARAMETER Path | |
Path to file(s)/folder(s) to list properties. Wildcards and hidden or system files are supported. | |
.INPUTS System.Management.Automation.PathInfo, System.String | |
You can pipe PathInfo objects or strings that contain paths to this cmdlet. | |
.OUTPUTS System.Object, System.String | |
This cmdlet returns objects that it gets. The type is determined by the type of objects in the path. | |
.Example | |
PS> Get-FileAttributesEx ~\OneDrive\desktop.ini | |
FullName : C:\Users\User\OneDrive\desktop.ini | |
Owner : HOSTNAME\User | |
Group : HOSTNAME\None | |
Attributes : 1572870 | |
AttributesEx : FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_SYSTEM, FILE_FLAG_UNKNOWN, FILE_FLAG_OPEN_NO_RECALL | |
AttributesHex : 0x00180006 | |
IdentityReference : HOSTNAME\User | |
FileSystemRights : FullControl | |
AccessControlType : Allow | |
IsInherited : True | |
InheritanceFlags : None | |
PropagationFlags : None | |
.NOTES | |
The FlagsAttribute list is incomplete and if several flags exist on a single item, results are | |
not always accurate. Many details of the FlagsAttribute class and other APIs are unknown | |
or undocumented as of this writing. | |
#> | |
#Requires -Version 5.1 | |
function Get-FileAttributesEx { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory=$false, ValueFromPipeline=$true)] | |
[string[]] $Path | |
) | |
# Begin{} | |
Set-Strictmode -Version 'Latest' | |
# https://docs.microsoft.com/en-us/windows/desktop/FileIO/file-attribute-constants | |
# https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea | |
[FlagsAttribute()] | |
enum FileAttributesEx | |
{ | |
FILE_ATTRIBUTE_READONLY = 0x00000001 | |
FILE_ATTRIBUTE_HIDDEN = 0x00000002 | |
FILE_ATTRIBUTE_SYSTEM = 0x00000004 | |
FILE_ATTRIBUTE_DIRECTORY = 0x00000010 | |
FILE_ATTRIBUTE_ARCHIVE = 0x00000020 | |
FILE_ATTRIBUTE_DEVICE = 0x00000040 | |
FILE_ATTRIBUTE_NORMAL = 0x00000080 | |
FILE_ATTRIBUTE_TEMPORARY = 0x00000100 | |
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200 | |
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400 | |
FILE_ATTRIBUTE_COMPRESSED = 0x00000800 | |
FILE_ATTRIBUTE_OFFLINE = 0x00001000 | |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000 | |
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000 | |
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000 | |
FILE_ATTRIBUTE_VIRTUAL = 0x00010000 | |
FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000 | |
FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000 | |
FILE_FLAG_UNKNOWN = 0x00080000 | |
FILE_FLAG_OPEN_NO_RECALL = 0x00100000 | |
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 | |
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000 | |
FILE_FLAG_SESSION_AWARE = 0x00800000 | |
FILE_FLAG_POSIX_SEMANTICS = 0x01000000 | |
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 | |
FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 | |
FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000 | |
FILE_FLAG_RANDOM_ACCESS = 0x10000000 | |
FILE_FLAG_NO_BUFFERING = 0x20000000 | |
FILE_FLAG_OVERLAPPED = 0x40000000 | |
FILE_FLAG_WRITE_THROUGH = 0x80000000 | |
} | |
# Use PWD if no args. | |
if (!$Path) | |
{ | |
$Path = $PWD | |
} | |
# Assemble list of path arg(s). In the non-literal case we may need to resolve a wildcarded path. | |
foreach ($apath in $Path) | |
{ | |
# Get-Item finds hidden and system files with -Force | |
if ($apath = Get-Item $apath -Force -ErrorAction:Ignore 2>$null) | |
{ | |
$itemPaths += @($apath | Foreach-Object{$_.FullName}) | |
} | |
else | |
{ | |
$itemPaths += $apath | |
} | |
} | |
# Process{} ..the items we assembled. | |
foreach ($itempath in $itemPaths) | |
{ | |
$item = Get-Item $itemPath -Force -ErrorAction:Ignore | |
# Add properties to $item | |
$itemAttributesEx = [FileAttributesEx]$item.Attributes.Value__ | |
$itemHexAttributes = '0x{0:X8}' -f [int] $item.Attributes | |
Add-Member -InputObject $item -MemberType NoteProperty -Name AttributesEx -Value $itemAttributesEx | |
Add-Member -InputObject $item -MemberType NoteProperty -Name AttributesHex -Value $itemHexAttributes | |
$selectItemProperties = @("FullName", "Attributes", "AttributesEx", "AttributesHex") | |
# Try to add ACL properties. (Protected system files often throw error on `Get-ACL`) | |
# To list only attributes/flags; comment this entire Try/Catch block. | |
try | |
{ | |
# ACL properties | |
$itemACL = Get-Acl $item -ErrorAction:Ignore 2>$null | |
Add-Member -InputObject $item -MemberType NoteProperty -Name ACL -Value $itemACL | |
Add-Member -InputObject $item -MemberType NoteProperty -Name Owner -Value $item.ACL.Owner | |
Add-Member -InputObject $item -MemberType NoteProperty -Name Group -Value $item.ACL.Group | |
# Add-Member -InputObject $item -MemberType NoteProperty -Name sddl -Value $item.ACL.SDDL | |
$selectItemProperties = @("FullName", "Owner", "Group", "Attributes", "AttributesEx", "AttributesHex") | |
# WindowsIdentity ACL access properties | |
$userIdentity = [Security.Principal.WindowsIdentity]::GetCurrent().Name | |
$itemACLuserIdentityaccess = $item.ACL.access | Where-Object{$_.IdentityReference -eq $userIdentity} | |
Add-Member -InputObject $item -MemberType NoteProperty -Name userAccess -Value $itemACLuserIdentityaccess | |
Add-Member -InputObject $item -MemberType NoteProperty -Name FileSystemRights -Value $item.userAccess.FileSystemRights | |
Add-Member -InputObject $item -MemberType NoteProperty -Name AccessControlType -Value $item.userAccess.AccessControlType | |
Add-Member -InputObject $item -MemberType NoteProperty -Name IdentityReference -Value $item.userAccess.IdentityReference | |
Add-Member -InputObject $item -MemberType NoteProperty -Name IsInherited -Value $item.userAccess.IsInherited | |
Add-Member -InputObject $item -MemberType NoteProperty -Name InheritanceFlags -Value $item.userAccess.InheritanceFlags | |
Add-Member -InputObject $item -MemberType NoteProperty -Name PropagationFlags -Value $item.userAccess.PropagationFlags | |
$selectItemProperties += @("IdentityReference", "FileSystemRights", "AccessControlType", | |
"IsInherited", "InheritanceFlags", "PropagationFlags" ) | |
} | |
catch {} | |
# End{} return object(s) with a default set of selected properties attached; usually formatted in a table or list. | |
# Single properties may also be retrieved; Ex. (Get-FileAttributesEx "file").Owner | |
$item | Select-Object -Property $selectItemProperties | |
} | |
} | |
# If this script is invoked directly as opposed to being dot-sourced; | |
# invoke the embedded function relaying any arguments passed | |
if ($MyInvocation.ExpectingInput) | |
{ | |
# True if we have ValueFromPipeLine $input (ExpectingInput) | |
$input | Get-FileAttributesEx @args | |
} | |
elseif (-not ($MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '')) | |
{ | |
# True if not dot-sourced or is invoked directly (empty invocation line) | |
Get-FileAttributesEx @args | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment