27 July 2016

PowerShell: Retrieving File Details

I have been writing a new script and was in need of getting the product name from the file details. Most everything I found when Googling came up finding the file version. I finally found this site that showed how to get a list of all 288 attributes. I decided to write a function that would get all of the attributes and the property fields that are populated. I found that still did not contain all of the data I needed, especially the product field. I compared what the script returned from the 288 attributes and what was available when right-clicking on a file and looking at the properties.

I have meshed the two together to give a pretty comprehensive dynamic list of available properties. For properties that have no associated value, they do not appear in the list. The available properties change by the file type and what the author inputs in them. The properties are returned from the function as an object. I know there are more available under the security and compatibility tabs, but I ran out of time while writing this function, as I need to finish up the other script first. I promise that I will be adding at least the compatibility tab to this function later on. I put the function into a PowerShell script so that you could see an examples of it executing. Sapien's PowerShell Studio made it possible to easily formulate and write this script.

Here is a picture of a typical output from the script:


Here is a video of the script in action:



You can download the script, which contains the function, from here.



1:  <#       
2:       .NOTES  
3:       ===========================================================================  
4:        Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.125  
5:        Created on:       7/26/2016 1:39 PM  
6:        Created by:       Mick Pletcher  
7:        Organization:         
8:        Filename:         GetFileProperties.ps1  
9:       ===========================================================================  
10:  #>  
11:    
12:  function Get-MetaData {  
13:  <#  
14:       .SYNOPSIS  
15:            Get File MetaData  
16:         
17:       .DESCRIPTION  
18:            A detailed description of the Get-MetaData function.  
19:         
20:       .PARAMETER FileName  
21:            Name of File  
22:         
23:       .EXAMPLE  
24:            PS C:\> Get-MetaData -FileName 'Value1'  
25:         
26:       .NOTES  
27:            Additional information about the function.  
28:  #>  
29:         
30:       [CmdletBinding()][OutputType([object])]  
31:       param  
32:       (  
33:                 [ValidateNotNullOrEmpty()][string]$FileName  
34:       )  
35:         
36:       $MetaDataObject = New-Object System.Object  
37:       $shell = New-Object -COMObject Shell.Application  
38:       $folder = Split-Path $FileName  
39:       $file = Split-Path $FileName -Leaf  
40:       $shellfolder = $shell.Namespace($folder)  
41:       $shellfile = $shellfolder.ParseName($file)  
42:       $MetaDataProperties = 0..287 | Foreach-Object { '{0} = {1}' -f $_, $shellfolder.GetDetailsOf($null, $_) }  
43:       For ($i = 0; $i -le 287; $i++) {  
44:            $Property = ($MetaDataProperties[$i].split("="))[1].Trim()  
45:            $Property = (Get-Culture).TextInfo.ToTitleCase($Property).Replace(' ', '')  
46:            $Value = $shellfolder.GetDetailsOf($shellfile, $i)  
47:            If ($Property -eq 'Attributes') {  
48:                 switch ($Value) {  
49:                      'A' {  
50:                           $Value = 'Archive (A)'  
51:                      }  
52:                      'D' {  
53:                           $Value = 'Directory (D)'  
54:                      }  
55:                      'H' {  
56:                           $Value = 'Hidden (H)'  
57:                      }  
58:                      'L' {  
59:                           $Value = 'Symlink (L)'  
60:                      }  
61:                      'R' {  
62:                           $Value = 'Read-Only (R)'  
63:                      }  
64:                      'S' {  
65:                           $Value = 'System (S)'  
66:                      }  
67:                 }  
68:            }  
69:            #Do not add metadata fields which have no information  
70:            If (($Value -ne $null) -and ($Value -ne '')) {  
71:                 $MetaDataObject | Add-Member -MemberType NoteProperty -Name $Property -Value $Value  
72:            }  
73:       }  
74:       [string]$FileVersionInfo = (Get-ItemProperty $FileName).VersionInfo  
75:       $SplitInfo = $FileVersionInfo.Split([char]13)  
76:       foreach ($Item in $SplitInfo) {  
77:            $Property = $Item.Split(":").Trim()  
78:            switch ($Property[0]) {  
79:                 "InternalName" {  
80:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name InternalName -Value $Property[1]  
81:                 }  
82:                 "OriginalFileName" {  
83:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name OriginalFileName -Value $Property[1]  
84:                 }  
85:                 "Product" {  
86:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name Product -Value $Property[1]  
87:                 }  
88:                 "Debug" {  
89:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name Debug -Value $Property[1]  
90:                 }  
91:                 "Patched" {  
92:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name Patched -Value $Property[1]  
93:                 }  
94:                 "PreRelease" {  
95:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name PreRelease -Value $Property[1]  
96:                 }  
97:                 "PrivateBuild" {  
98:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name PrivateBuild -Value $Property[1]  
99:                 }  
100:                 "SpecialBuild" {  
101:                      $MetaDataObject | Add-Member -MemberType NoteProperty -Name SpecialBuild -Value $Property[1]  
102:                 }  
103:            }  
104:       }  
105:         
106:       #Check if file is read-only  
107:       $ReadOnly = (Get-ChildItem $FileName) | Select-Object IsReadOnly  
108:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name ReadOnly -Value $ReadOnly.IsReadOnly  
109:       #Get digital file signature information  
110:       $DigitalSignature = get-authenticodesignature -filepath $FileName  
111:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateSubject -Value $DigitalSignature.SignerCertificate.Subject  
112:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateIssuer -Value $DigitalSignature.SignerCertificate.Issuer  
113:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateSerialNumber -Value $DigitalSignature.SignerCertificate.SerialNumber  
114:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateNotBefore -Value $DigitalSignature.SignerCertificate.NotBefore  
115:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateNotAfter -Value $DigitalSignature.SignerCertificate.NotAfter  
116:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureCertificateThumbprint -Value $DigitalSignature.SignerCertificate.Thumbprint  
117:       $MetaDataObject | Add-Member -MemberType NoteProperty -Name SignatureStatus -Value $DigitalSignature.Status  
118:       Return $MetaDataObject  
119:  }  
120:    
121:  function Get-RelativePath {  
122:  <#  
123:       .SYNOPSIS  
124:            Get the relative path  
125:         
126:       .DESCRIPTION  
127:            Returns the location of the currently running PowerShell script  
128:         
129:       .NOTES  
130:            Additional information about the function.  
131:  #>  
132:         
133:       [CmdletBinding()][OutputType([string])]  
134:       param ()  
135:         
136:       $Path = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
137:       Return $Path  
138:  }  
139:    
140:  Clear-Host  
141:  $RelativePath = Get-RelativePath  
142:  $File = $RelativePath + "scepinstall.exe"  
143:  $FileMetaData = Get-MetaData -FileName $File  
144:  #Example of displaying all returned values  
145:  $FileMetaData  
146:  #Example of retrieving just the file name  
147:  $FileMetaData.Name  
148:    
149:    

0 comments:

Post a Comment