Windows equivalent to the unix “stat” command

command linentfsstatwindows

So, I'm looking for a command-line approach to get a short(ish) textual dump of relatively low-level metadata for a file, approximately the same way that stat does on *nix systems.

In other words, information that's readily available through Win32 or NT file APIs without actually reading the contents of the file, and definitely without having to go anywhere near the Shell (as seen in Explorer and the Save/Open dialogs, and anything using shell32.dll).

On NTFS, this info would tend be stored in the file's MFT entry, though I've heard that exactly which attributes end up in the MFT proper depends largely is largely a matter of which will fit, since many attributes are optional, repeatable, and/or variable size, some can be , though it's also possible to use more than one slot in the MFT. (In fact, it's even possible to store a file/directory's full contents in the MFT if the other attributes don't take too much space!) So, um, obviously "appears in the MFT" can't be use to actually define what I'm looking for.

Also, I'm not looking for tools that parse NTFS itself, or only work on NTFS filesystems: I only mention NTFS because, well, what other local FS is going to support more NT-specific things?

For concreteness, here's the stat on the Debian box I'm using as a router:

hydrogen% stat .
  File: ‘.’
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fe00h/65024d    Inode: 507974      Links: 4
Access: (0755/drwxr-xr-x)  Uid: ( 1000/ naesten)   Gid: ( 1000/ naesten)
Access: 2016-08-31 14:12:47.650440935 -0400
Modify: 2016-09-20 17:26:15.935591584 -0400
Change: 2016-09-20 17:26:15.935591584 -0400
 Birth: -
hydrogen%

And here's the one from Git for Windows:

colored raster version of below "screenshot"

Sam@Sam-laptop MINGW64 ~
$ git --version
git version 2.8.2.windows.1

Sam@Sam-laptop MINGW64 ~
$ stat .
  File: '.'
  Size: 0               Blocks: 32         IO Block: 65536  directory
Device: 147ac391h/343589777d    Inode: 1970324836977201  Links: 1
Access: (0755/drwxr-xr-x)  Uid: (197608/     Sam)   Gid: (197121/ UNKNOWN)
Access: 2016-09-18 18:32:28.072538600 -0400
Modify: 2016-09-18 18:32:28.072538600 -0400
Change: 2016-09-18 18:32:28.072538600 -0400
 Birth: 2014-08-21 18:52:08.217444400 -0400

Sam@Sam-laptop MINGW64 ~
$

At this point, I was going to say that the "Birth" timestamp field is a Windowsism, but clearly that's not quite true because Debian's stat shows the field, only it's empty above because the filesystem doesn't actually have that field. (Which is, at least, much clearer than the "Access" timestamps: neither system is updating those in the traditional strictatime manner.)

Also note how the Windows port is displaying made-up file access permissions, an implausibly-large "inode number", and what I can only assume are also made up UID/GID numbers (on account of how NT uses variable-length hierarchical identifiers rather than fixed-size numbers to identify users and groups, and doesn't permit both user and group ownership at the same time; that is, on NT a file is owned by a single user OR group, and anyone else just gets their rights from the ACL).

Does MS provide a tool of this sort, presumably one that shows more actual information and less fairyland information?


My original text follows:

Yes, I know there are ports of stat, but (a) I'm concerned that information might fall through the cracks if:

  1. It doesn't commonly appear in Unix stat output
  2. It's missing from whichever stat upstream's code (if any)
  3. The porter(s) either
    1. Don't notice Windows provides the information
    2. Are building on a POSIX layer that doesn't plumb it through
    3. Aren't sure how best to present the information (or that it's even appropriate to do so) in the context of stat
    4. Don't have an unlimited amount of time on their hands

and (b) I was wondering if Microsoft supplied any analogous tool(s).

But really, any command-line way get sort of information stat might provide (regardless of whether it involves a program called stat), along with a description of the more-or-less NTFS-specific information it provides, would be of interest.

P.S. I'm on Windows 7, but don't let that stop you from mentioning things first shipped for/in later versions of Windows.

Best Answer

I just threw together a PowerShell script. It includes pretty much everything that makes sense for Windows, except the access controls, which are usually too large to fit in a summary. You can see them with the icacls utility.

$obj = $args[0]
If ($obj.GetType().Name -eq 'String') {$obj = gi $obj}
'File: ' + $obj.FullName
'Size: ' + $obj.Length
$extents = [string](fsutil file queryextents "$($obj.FullName)")
If (-$extents.StartsWith('i')) {
  'Clusters: ' + ($extents.Substring(26) -split 'LCN')[0]
  'LCN: ' + $extents.Substring(42)
} Else {
  'Clusters: stored in file table'
}
'Attributes: ' + $obj.Attributes
$volumeinfo = (fsutil fsinfo volumeinfo "$([System.IO.Path]::GetPathRoot($obj.FullName)[0] + ':')")
$volumeinfo | ? {$_.StartsWith('Volume Serial')} | % {$_.Replace(' :', ':')}
$fileid = (fsutil file queryfileid "$($obj.FullName)")
'File ID: ' + $fileid.Substring(11)
$links = (fsutil hardlink list "$($obj.FullName)")
'Links: ' + ([string[]]$links).Length
'Owner: ' + $obj.GetAccessControl().Owner
''
'Access: ' + $obj.LastAccessTime
'Modify: ' + $obj.LastWriteTime
'Create: ' + $obj.CreationTime
'' # Extra blank line for readability

It uses the normal .NET/PowerShell file system entry properties and calls out to the fsutil utility for the tricky stuff. Since that utility isn't a PowerShell cmdlet, I had to do some messy string chopping to get the right information.

To use it, save it as a .ps1 file and see the Enabling Scripts section of the PowerShell tag wiki. Example of output:

File: C:\Users\Ben\test\blank.ps1
Size: 8
Clusters: stored in file table
Attributes: Archive
Volume Serial Number: 0x9c67b42c
File ID: 0x0000000000000000000700000014428b
Links: 1
Owner: POWERSHELL\Ben

Access: 07/29/2016 20:01:25
Modify: 07/29/2016 20:02:43
Create: 07/29/2016 20:01:25
Related Question