The script discussed in this article will allow you to query file properties, such as file version and product version of any file that has a version associated with it (for example, DLL or EXE), on remote computers. It generates an Excel report with version information and other details.

Querying the file version of a single file is easy. You can use the Get-Item cmdlet, as shown in the following example, to get the file version information. But things become difficult when you have to do this for hundreds of computers.

(Get-Item C:\Windows\system32\tcpipcfg.dll).VersionInfo

When you want to find the version of a particular file in all computers in your environment, you need a sophisticated script that handles several error conditions and generates neat output. The script provided in this article is developed to help in such scenarios.

This script (Get-FileVersionInfoRemotely.ps1) has the following features:

  1. It takes one or more computer names as input.
  2. It takes the local path of the file that you want to query. For example, if you want to query the file version of c:\program files\app1\appinfo.dll, you can provide the file path as is rather than specify an UNC path such as \\computername\c$\program files\app1\appinfo.dll.
  3. It provides the status of each computer in the report. The value of this status column indicates the result of querying that computer. See the output screenshot at the end of this article to understand this better.
    • SUCCESS: Indicates that the script was able to query the file version on a remote computer.
    • FailedTOQuery: Indicates that script was unable to query the file version. Possible reasons include file permissions or trouble accessing the remote $ share of the drive where the file resides.
    • PathNotAccessable: Indicates that the script was unable to access the path. As a result, the file was not found in the location that was provided in the input.
    • NotReachable: Indicates that the computer you want to query did not respond to the ping.
  4. It generates a CSV output that you can easily filter using Excel and use for further processing.
  5. Along with the file version, the script gives the product version, original name of the file, product name, and file description.
  6. You can pass the output file name to the -OutputFile
[CmdletBinding()]
Param(
	[string[]]$ComputerName = $env:ComputerName,
	[Parameter(mandatory=$true)]
	[string]$Path,
	[string]$OutputFile = "c:\temp\FileVersionInfo.csv"
)

$parts = $Path -split ":\\"
$DriveLetter = $parts[0]
$PathwoRoot = $parts[1]
Write-Verbose "Drive letter is $DriveLetter"
Write-Verbose "Remaining Path is $PathwoRoot"
try {
	$Parent = [System.IO.Directory]::GetParent($OutputFile)
	if(Test-Path $Parent.FullName) {
		Write-Verbose "Output folder $($parent.FullName) exists"
	} else {
		throw "Directory $($parent.FullName) not found. Output file cannot be created"
	}
} catch {
	Write-Error "Error occurred while checking output folder. $_"
	return
}
$OutputArr = @()
foreach($Computer in $ComputerName) {
	Write-Host "Querying file version on $Computer"
	$OutputObj = New-Object -TypeName PSobject  
	$OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer 
	$OutputObj | Add-Member -MemberType NoteProperty -Name FilePath -Value $Path
	$OutputObj | Add-Member -MemberType NoteProperty -Name FileVersion -Value $null
	$OutputObj | Add-Member -MemberType NoteProperty -Name ProductVersion -Value $null
	$OutputObj | Add-Member -MemberType NoteProperty -Name Status -Value $null
	$OutputObj | Add-Member -MemberType NoteProperty -Name OriginalName -Value $null
	$OutputObj | Add-Member -MemberType NoteProperty -Name FileDescription -Value $null
	$OutputObj | Add-Member -MemberType NoteProperty -Name ProductName -Value $null
	
	if(Test-Connection -ComputerName $Computer -count 1 -quiet) {
		$TargetPath = [string]::format("\\{0}\{1}`$\{2}",$Computer,$DriveLetter,$PathwoRoot)
		Write-verbose "Trying to get $TargetPath file version"
		if(Test-Path $TargetPath) {
			try {
				$VersionInfo = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($TargetPath)
				$OutputObj.FileVersion = $VersionInfo.FileVersion
				$OutputObj.ProductVersion = $VersionInfo.ProductVersion
				$OutputObj.OriginalName = $VersionInfo.OriginalName
				$OutputObj.FileDescription = $VersionInfo.FileDescription
				$OutputObj.ProductName = $VersionInfo.ProductName
				$OutputObj.Status = "SUCCESS"
			} catch {
				$OutputObj.Status = "FailedTOQuery"
			}
		} else {
				$OutputObj.Status = "PathNotAccessable"
		}
	} else {
		$OutputObj.Status = "NotReachable"
	}
	$OutputArr += $OutputObj
	Write-Verbose $OutputObj
}

$OutputArr | Export-csv $OutputFile -NotypeInformation

Now that we have seen the script’s features, let’s look at some usage examples.

In the example below, we query the file version of a remote computer named PSDC02. The -OutputFile parameter is optional. If you don’t specify it, the script writes the output to c:\temp\fileversioninfo.csv by default.

PS C:\temp> .\Get-FileVersionInfoRemotely.ps1 -ComputerName PSDC02 -Path C:\Windows\system32\tcpipcfg.dll -OutputFile c:\temp\fileversiondetails.csv

You can use the above command to collect file version information from multiple computers as well. To do so, provide a list of computer names as comma-separated values to the -ComputerName parameter, as shown below:

PS C:\temp> .\Get-FileVersionInfoRemotely.ps1 -ComputerName PSDC02,PSDC01 -Path C:\Windows\system32\tcpipcfg.dll -OutputFile c:\temp\fileversiondetails.csv

For a large number of computers, place the computer names in a text file by entering one computer name per line. You can then pass the text file to the script, as shown below:

PS C:\temp> .\Get-FileVersionInfoRemotely.ps1 -ComputerName (get-content c:\temp\workstations.txt) -Path C:\Windows\system32\tcpipcfg.dll -OutputFile c:\temp\fileversiondetails.csv

You can place the text file anywhere, but make sure to provide the complete file path. No restriction exists with regard to the name of the text file.

The screenshots below show the script progress and the contents of the output file when the script runs against multiple computers.

Script progress

Script output

I hope this script is helpful. If you have any problems using this script or suggestions for how to improve the script, please leave a comment.

19 Comments
  1. Scott 7 years ago

    Love the script, is there a way you could specify what username and password to connect to computers with?

  2. matt 7 years ago

    Great script…I’d like to know if you can specify user/password too! thanks

  3. butirek 7 years ago

    this is so helpfull..

  4. Pablo 5 years ago

    Thank you so much! I can now get any file version from a list from computers.

    Works without glitches

    Respectfully,

    Pablo

  5. Shivang 5 years ago

    Hello Sir, Really Helpful.

    Thanks a lot.

    Please help me in getting file info for multiple files at a time from different paths.

    Reagrds

    Shivang

     

  6. Clayton 5 years ago

    You could add the items in the txt file as you did. Then you could put do a foreach loop for the files and run the QueryFileVersionsRemotely.ps1 file.

    $files = Get-Content C:\path\to\files.txt
    Foreach($line in $files){
        .\QueryFileVersionsRemotely.ps1 -ComputerName (Get-Content D:\Temp\Computerlist.txt) -Path $line -OutputFile C:\Temp\FileVersionInfo.csv
    }

    The $line Variable should be the full path of the file. The trick is now to find a way to rename the output file to a different name for each file type.

    Or if the files are in the same directory you could pipe the command as well.

    ls | .\QueryFileVersionsRemotely.ps1 -ComputerName (Get-Content D:\Temp\Computerlist.txt) -Path "." -OutputFile C:\Temp\FileVersionInfo.csv

    • Alan Page (Rank 1) 2 months ago

      I was testing your idea out a little for multiple file paths.
      I am interested in the same idea but for user profile directory. With alot of apps install exe into app data it would be very useful to use a wildcard for the username. Is something like this a possibility?

  7. Clayton (Rank 2) 5 years ago

    You could add the items in the txt file as you did. Then you could put do a foreach loop for the files and run the QueryFileVersionsRemotely.ps1 file.

    $files = Get-Content C:\path\to\files.txt
    Foreach($line in $files){
    .\QueryFileVersionsRemotely.ps1 -ComputerName (Get-Content D:\Temp\Computerlist.txt) -Path $line -OutputFile C:\Temp\FileVersionInfo.csv
    }

    The $line Variable should be the full path of the file. The trick is now to find a way to rename the output file to a different name for each file type.

    Or if the files are in the same directory you could pipe the command as well.

    ls | .\QueryFileVersionsRemotely.ps1 -ComputerName (Get-Content D:\Temp\Computerlist.txt) -Path "." -OutputFile C:\Temp\FileVersionInfo.csv

  8. Ian Brooks 4 years ago

    I know this is an older post, but I've just used this to interrogate NTDLL.dll and it's only reporting the file version for the base operating system, and ignoring any patches that have subsequently been applied. For example, on my Win 10 machine, the script reports version 10.0.16299.611 but manually looking at the details of the file it is 10.0.16299.936.

    Is there any reason that this does not match? It makes the script useless for our needs.

    avatar
    • Hi Ian,
      The FileVersion Property(Line no 44) would return the build version of the file.
      To get the current(Patch) version of the file use the below code.

      $OutputObj.FileVersion = ("{0}.{1}.{2}.{3}" -f $VersionInfo.FileMajorPart,$VersionInfo.FileMinorPart, $VersionInfo.FileBuildPart, $VersionInfo.FilePrivatePart)

  9. Alternatively, if you have PowerShell 5.0 you could also use Fileversionraw property.

    $file=Get-Item C:Windowsexplorer.exe
    $file.VersionInfo.Fileversionraw.ToString()
    avatar
  10. Here is an example to illustrate the difference.

    PS C:\> $file=Get-Item C:\Windows\explorer.exe
    PS C:\>
    PS C:\> $file.VersionInfo.Fileversion
    10.0.17134.1 (WinBuild.160101.0800)
    PS C:\>
    PS C:\> $file.VersionInfo.Fileversionraw.ToString()
    10.0.17134.677
    PS C:\>

  11. Joseph Hu 4 years ago

    Hi,

    Great script.

    How do I include Date Modified file property to the script?

    Thanks.

    • Hi Joseph,

      o get the last modified time for the file append this code after line 36
      $OutputObj | Add-Member -MemberType NoteProperty -Name LastModifiedTime -Value $null

      And insert this code after line 49
      $OutputObj.LastModifiedTime = (get-item $TargetPath).LastWriteTime

       

  12. Joseph Hu 4 years ago

    Thanks, Swapnil. That worked.

    avatar
  13. Thank you so much for the script. It's very usefull for me.

  14. Mad 3 years ago

    Hi, I know this is an old topic but this script has been useful this last weeks, I would like to know how to save the cvs file as actual date and time format , example: 1-15-20201256.csv.

    Thanks advance.

    Regards

  15. Bara 3 years ago

    awesome ! this really help! thank you!

  16. Mohan 1 year ago

    is there any way we can use it with pssession and use invoke command to reach multiple servers?

    like instead of this
    .\Get-FileVersionInfoRemotely.ps1 -ComputerName (get-content C:\Temp\Computers.txt) -Path C:\Windows\system32\ntoskrnl.exe -OutputFile C:\Temp\Output\FileVer1.csv

    Can we use like this below?

    $Computers = Get-Content “C:\Temp\Computers.txt”

    $Sessions = New-PSSession -ComputerName $Computers
    foreach($line in $Computers)
    {
    Invoke-Command -ComputerName (get-content $line) -FilePath .\Get-FileVersionInfoRemotely.ps1 -Path C:\Windows\system32\ntoskrnl.exe -OutputFile C:\Temp\Output\FileVer1.csv
    }

    I am unable to run above getting error

    I am not that much good in powershell can someone help so I can reach somany servers using winrm

Leave a reply to matt Click here to cancel the reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account