Is there a way to get file metadata from the command line?

20

6

Is there a way to get a file's metadata from the command line in Windows XP and above?

Particularly, I'm interested in getting the information one might normally see on the "Details" tab of a file's "Properties" dialog in Windows 7. ("Version" tab in XP.) Screenshots of both are below, to give an idea of what I'm after.

If possible, I'd rather do this through cmd.exe or something else that comes standard with Windows XP SP3 and above. If this is not possible, my preferred alternatives would be:

  • PowerShell
  • A SysInternals utility
  • A Nirsoft utility
  • Some other tool from a similarly reputable and well-recognized developer.

Windows XP screenshot:
Windows XP - Version tab in File Properties

Windows 7 screenshot:
Windows 7 - Details tab in File Properties

Iszi

Posted 2011-12-01T03:40:20.060

Reputation: 11 686

1

You can install FILEVER from the Windows CD.

– William Jackson – 2011-12-01T03:45:06.073

1@WilliamJackson - That sounds like a possible answer. Mind posting it as one, and maybe fleshing it out a bit with some of the info that's in that KB article? Also, could you suggest something for higher versions of Windows? I understand from some searching that FILEVER is not included on those CDs, and so may not be a supported tool for those versions. – Iszi – 2011-12-01T04:07:13.703

Answers

20

You can use WMIC.exe to get most of the way there:

C:\>wmic datafile where Name="C:\\Windows\\System32\\cmd.exe" get Manufacturer,Name,Version
Manufacturer           Name                         Version
Microsoft Corporation  c:\windows\system32\cmd.exe  6.1.7601.17514

Note the escaping of the backslashes \ in the path (it does not work otherwise).

bobbymcr

Posted 2011-12-01T03:40:20.060

Reputation: 1 992

extension of this method to compare versions in a batch: http://superuser.com/a/904535/131936

– LogicDaemon – 2015-04-22T08:03:13.427

You can get just about any OS info you need for most operations through WMI but it comes with a major caveat; it's quite slow. Orders of magnitude slower than most of the more direct routes. That said, it does work for a lot of queries and monitoring. – kayleeFrye_onDeck – 2016-10-17T17:35:31.173

This give an error: wmic : Unexpected switch at this level. on W81, same for Iszi soulution. – not2qubit – 2017-03-09T08:25:08.110

wmic datafile get doesnt really offer most of the info im looking for. any other way to do this? for instance, any way to get the company, authors, legal trademark, copyright, etc, fields of a given file? – oldboy – 2020-01-22T04:11:30.147

2

What you are looking for can be pulled with a combination of dsofile.dll (not needed if you have Office installed) and autoit or any .NET language.

I also found a powershell method, but I haven't been able to test it.

I wrote up a little script with autoit that still needs some tweaking. I am on Vista and I can't get the few dsofile.dll calls to function as I would expect, though it still provides some output that you might be interested in. I'll work on this more in the morning when I have access to an XP and win7 VM. Note that you need to change the path in the dll functions to wherever you install dsofile.dll.

#include <file.au3>
Dim $file, $objFile, $Path, $encoding, $attrib, $attributes, $dt, $stamp, $szDrive, $szDir, $szFName, $szExt

If $CmdLine[0] = 0 Then
    ConsoleWrite("You must specify a file")
Else
    $file = $CmdLine[1]
    If FileExists($file) Then
        _DLLstartup()
        $objFile = ObjCreate("DSOFile.OleDocumentProperties")
        If Not IsObj($objFile) Then Exit
        $objFile.Open(FileGetLongName($file))
        $Path = _PathSplit($file, $szDrive, $szDir, $szFName, $szExt)
        ConsoleWrite("Filename: " & $Path[3] & $Path[4] & @CRLF)
        ConsoleWrite("Size: " & FileGetSize($file) & " bytes" & @CRLF)
        ConsoleWrite("Version: " & FileGetVersion($file) & @CRLF)
        ConsoleWrite("Company: " & $objFile.SummaryProperties.Company & @CRLF)
        ConsoleWrite("Author: " & $objFile.SummaryProperties.Author & @CRLF)
        $encoding = FileGetEncoding($file)
            Select
            Case $encoding = 0
                $encoding = "ANSI"
            Case $encoding = 32
                $encoding = "UTF16 Little Endian"
            Case $encoding = 64
                $encoding = "UTF16 Big Endian"
            Case $encoding = 128
                $encoding = "UTF8 (with BOM)"
            Case $encoding = 256
                $encoding = "UTF8 (without BOM)"
            EndSelect
        ConsoleWrite("Encoding: " & $encoding & @CRLF)
        $attrib = FileGetAttrib($file)
        $attributes = ""
            If StringInStr($attrib, "R") <> 0 Then
                $attributes = $attributes & " READONLY"
            EndIf
            If StringInStr($attrib, "A") <> 0 Then
                $attributes = $attributes & " ARCHIVE"
            EndIf
            If StringInStr($attrib, "S") <> 0 Then
                $attributes = $attributes & " SYSTEM"
            EndIf
            If StringInStr($attrib, "H") <> 0 Then
                $attributes = $attributes & " HIDDEN"
            EndIf
            If StringInStr($attrib, "N") <> 0 Then
                $attributes = $attributes & " NORMAL"
            EndIf
            If StringInStr($attrib, "D") <> 0 Then
                $attributes = $attributes & " DIRECTORY"
            EndIf
            If StringInStr($attrib, "O") <> 0 Then
                $attributes = $attributes & " OFFLINE"
            EndIf
            If StringInStr($attrib, "C") <> 0 Then
                $attributes = $attributes & " COMPRESSED"
            EndIf
            If StringInStr($attrib, "T") <> 0 Then
                $attributes = $attributes & " TEMPORARY"
            EndIf
        ConsoleWrite("Attributes:" & $attributes & @CRLF)
        $dt = FileGetTime($file, 1)
        $stamp = $dt[0] & "-" & $dt[1] & "-" & $dt[2] & " " & $dt[3] & ":" & $dt[4] & ":" & $dt[5]
        ConsoleWrite("Created: " & $stamp & @CRLF)
        $dt = FileGetTime($file, 0)
        $stamp = $dt[0] & "-" & $dt[1] & "-" & $dt[2] & " " & $dt[3] & ":" & $dt[4] & ":" & $dt[5]
        ConsoleWrite("Accessed: " & $stamp & @CRLF)
        $dt = FileGetTime($file, 2)
        $stamp = $dt[0] & "-" & $dt[1] & "-" & $dt[2] & " " & $dt[3] & ":" & $dt[4] & ":" & $dt[5]
        ConsoleWrite("Modified: " & $stamp & @CRLF)
        ConsoleWrite("Short Name: " & FileGetShortName($file, 1) & @CRLF)
        ConsoleWrite("Long Name: " & FileGetLongName($file, 1))
        $objFile.Close
        _DLLshutdown()
    Else
        ConsoleWrite("Can't find file")
    EndIf
EndIf

Func _DLLstartup($DLLpath = '')  ;borrowed from Andrew Goulart
    If $DLLpath = Default Or $DLLpath = '' Then $DLLpath = "C:\DsoFile\dsofile.dll";@ScriptDir & '\dsofile.dll'
    ShellExecuteWait('regsvr32', '/s /i ' & $DLLpath, @WindowsDir, 'open', @SW_HIDE)
EndFunc

Func _DLLshutdown($DLLpath = '') ;borrowed from Andrew Goulart
    If $DLLpath = Default Or $DLLpath = '' Then $DLLpath = "C:\DsoFile\dsofile.dll";@ScriptDir & '\dsofile.dll'
    ShellExecuteWait('regsvr32', ' /s /u ' & $DLLpath, @WindowsDir, 'open', @SW_HIDE)
EndFunc

MaQleod

Posted 2011-12-01T03:40:20.060

Reputation: 12 560

1

Just to expand on @bobbymcr 's answer above (which I found very helpful, thank you!); you can simplify the command and broaden the results by using the LIST BRIEF or LIST FULL options.

Check > wmic datafile list /? for more details.

This solution helped me:
> wmic datafile "c:\\path\\to\\file.exe" list full

Note: As mentioned by @bobbymcr, remember to escape the \, else it won't work.

S3DEV

Posted 2011-12-01T03:40:20.060

Reputation: 113

This doesn't work... – not2qubit – 2017-03-09T08:21:21.513

Sorry this isn't working for you. I've just tried it again and it does work. Win7, admin rights. Full file path, and escaped ''. – S3DEV – 2018-03-21T12:16:10.113