Created
March 11, 2019 09:23
-
-
Save Trucido/02dc6b7f43df1eb6f0e5146f77282143 to your computer and use it in GitHub Desktop.
This file contains 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 and flags. | |
.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\Documents\* | Format-List | |
FullName : C:\Users\User\OneDrive\Documents\test.txt | |
Attributes : 5242912 | |
AttributesEx : FILE_ATTRIBUTE_ARCHIVE, FILE_FLAG_OPEN_NO_RECALL, FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS | |
AttributesHex : 0x00500020 | |
.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. | |
#> | |
function Get-FileAttributesEx { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory=$false, ValueFromPipeline=$true)] | |
[string[]] $Path | |
) | |
Set-Strictmode -Version 'Latest' | |
# List of known Attributes/Flags. | |
# Note: | |
# This also can done using [FlagsAttribute()] class instead of Csharp TypeDef | |
# Refs: | |
# 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 | |
Add-Type -Language Csharp -TypeDefinition @' | |
using System; | |
[FlagsAttribute] | |
public enum FileAttributesEx : uint { | |
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, // Undocumented | |
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 wildcard paths. | |
foreach ($apath in $Path) | |
{ | |
# Get-Item finds hidden and system files with -Force, try-catch needed due to -EA not catching all. | |
try{$apath = Get-Item $apath -Force -ErrorAction SilentlyContinue}catch{} | |
if ($apath -and (Test-Path $apath)) | |
{ | |
$itemPaths += @($apath | Foreach-Object{$_.FullName}) | |
} | |
else | |
{ | |
$itemPaths += $apath | |
} | |
} | |
# Add members to each items we assembled and add AttributesEx and AttributesHex. | |
# This approach has the benefit | |
# of returning objects which can be further proessed with these properties, | |
# as apposed to string output using custom format-list/format-table/select-object commands | |
foreach ($itempath in $itemPaths) | |
{ | |
$item = Get-Item $itemPath -Force -ErrorAction:Ignore | |
# Add properties to $item | |
$itemAttributesEx = [FileAttributesEx]$item.Attributes.Value__ | |
$itemAttributesHex = '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 $itemAttributesHex | |
# Return object(s) with a default set of selected properties attached, usually auto-formatted in a wide table. | |
# Single properties may also be retrieved; Ex. (Get-FileAttributesEx "file").AttributesEx or using Select-Object | |
$selectItemProperties = @("FullName", "Attributes", "AttributesEx", "AttributesHex") | |
# Note: If we Format-List here, we only get string output. Better to run this script/function piped to Format-List instead | |
# e.x. Get-FileAttributesEx .\file | format-list | |
# Or Get-FileAttributesEx .\Documents\* | format-list -Property fullname,attributesex | |
#$item | Select-Object -Property $selectItemProperties | Format-List | |
$item | Select-Object -Property $selectItemProperties | |
} | |
} | |
# If script is called directly with ValueFromPipeLine data; invoke the embedded function with $input piped to it and any args | |
if ($MyInvocation.ExpectingInput) | |
{ | |
$input | Get-FileAttributesEx @args | |
} | |
# ElseIf script is called directly; invoke the embedded function passing args | |
elseif (!($MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '')) | |
{ | |
Get-FileAttributesEx @args | |
} | |
# Else we're being dot-sourced so do nothing. | |
else {} | |
# Local Variables: | |
# mode: PowerShell; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; | |
# End: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment