Get Internet Explorer Version Remotely

Get Internet Explorer Version Remotely

There are many ways to get Internet Explorer’s version remotely, in this post I’ll show you how to do this with Powershell and grab it from a list of machines. Let’s start with the command that does that.

[System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Program Files\Internet Explorer\iexplore.exe").Fileversion

If you run this on your machine, you’ll get something like this:

get-version-info

As you can see, it works and it gets Internet Explorer’s version. Now let’s see how to do it remotely for just one client:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\COMPUTERNAME\C$\Program Files\Internet Explorer\iexplore.exe").Fileversion

Where COMPUTERNAME is the hostname or IP address of the remote machine. Obviously you must be running this as an administrator of the target machine or else it won’t work. So this would be it, however I will also show you 2 quick scripts to perform this on multiple machines. The first one is pretty straight forward and simple (quick script), the other one is pretty cool instead as it’ll use multithreading. 🙂

Note that the scripts can be modified in order to get the version of any other software!

Quick script

So the quick script is easy and will get Internet Explorer’s version remotely based on a list of machines taken from Active Directory. I’ve commented the script as much as I could so that every line is explained.

#Import AD's module
	Import-Module ActiveDirectory

#Grab a list of computer names from Active Directory (in City 3)
$ComputerList = Get-ADComputer -Filter * -searchbase "OU=City 3,OU=EU,DC=itdroplets,DC=com" | select-object Name

#Output file
	$csvOutput = 'C:\Users\itdroplets\desktop\tmp\GetITversion_output.csv'
#Deletes the output file if it exists
	If (Test-Path $csvOutput){
		Remove-Item $csvOutput
	}
	#Fills in the first line of the output file with the headline
	Add-Content -Path $csvOutput -Value "Name,Pingable,IEversion"

#Go through each computer in the List
$ComputerList | % {
	
	#Put the current computer name in a variable called $ComputerName
	$ComputerName = $_.Name
	
	#Ping the remote computer
	$Ping = Test-Connection $ComputerName -Count 2 -EA Silentlycontinue
	
	If ($ping){
		#If Ping is successfull, try to grab IE's version and put it in $IEVersionString's variable.
		$IEVersionString = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\$ComputerName\C$\Program Files\Internet Explorer\iexplore.exe").Fileversion
		#Edit the CSV file and add an extra line with the results of the above operations (Ping/IE Version)
		Add-Content -Path $csvOutput -Value "$($ComputerName),YES,$($IEVersionString)"
		#Write console output and show what computer is being processed and IE's version
		Write-Host "$($ComputerName) - $($IEVersionString)"
	}
	Else{
		#If we're here, the machine is NOT pingable
		
		#Edit the CSV file and add an extra line with the results of the Ping (No)
		Add-Content -Path $csvOutput -Value "$($ComputerName),NO,N/A"
		#Write console output and show what computer is being processed and state that it's not pingable
		Write-Host "$($ComputerName) - Not Pingable"
	}
	
}

Note: This is going to take ages if you’re planning to run it against loads of machines. Imagine ping one machine per time, then try accessing and grabbing IE’s version and finally adding the results to a file. Hence why the multithreading script that follows is really handy. Count that when using 200 threads (I ran it from my laptop so I didn’t care if it died) it took about 40 seconds to process 350 machines on the same network. When I ran the above script it took this time to grab info from 12 machines circa. Note that the network infrastructure is also critical. If the remote machine is located on a slow connection (for instance in another site with limited vpn connectivity) then it’ll take a bit longer to query and return the info either ways.

Multithreading script

This is my favourite. 🙂 As per what I said before, it’s really fast. Make sure you test it against a limited amount of computers to make sure it’s working correctly before waiting for the whole domain to be processed..

#Import AD's module
Import-Module ActiveDirectory

#Grab a list of computer names from Active Directory (in City 3)
$ComputerList = (Get-ADComputer -Filter * -searchbase "OU=City3,OU=EU,DC=itdroplets,DC=com" | select-object Name).Name

#Output file
	$csvOutput = 'C:\Users\itdroplets\Desktop\tmp\GetITversion_output.csv'
#Deletes the output file if it exists
	If (Test-Path $csvOutput){
		Remove-Item $csvOutput
	}
	#Fills in the first line of the output file with the headline
	Add-Content -Path $csvOutput -Value "Name,Pingable,IEversion"
	
# Number of threads
	$Throttle = 5
	
############ SCRIPT BLOCK #################################
# The script block is what runs in multithreading
	$ScriptBlock = {
	   Param (
		#The computer name that is being passed to the script block from the list.
		  [string]$Computer
	   )
	   
	   #Ping the remote computer
	   $ping = Test-Connection $Computer -Count 1 -EA Silentlycontinue
	   
	   If ($ping)
	   {
			#If Ping is successfull, try to grab IE's version and put it in $IEVersion's variable.
			$IEVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\$Computer\C$\Program Files\Internet Explorer\iexplore.exe").Fileversion
			
			#Store the results of the above operations (Computername, Pingable, IE Version) in an array
			$temp_array = New-Object PSObject -Property @{
				Computer = $Computer
				Pingable = "Yes"
				IEversion = $IEVersion
			}
	   }
	   Else
	   {	#If we're here, the machine is NOT pingable
	   
			#Store the Computername, the Ping info and N/A in IEversion in an array.
			$temp_array = New-Object PSObject -Property @{
				Computer = $Computer
				Pingable = "No"
				IEVersion = "N/A"
			}
	   }
		#Return the array to the main script
	   Return $temp_array
	}
###########################

#Create the runspace pool based on the throttle set above.
	$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $Throttle)
	$RunspacePool.Open()
	#Create an array where all results will be stored
	$Jobs = @()

#Go through each computer in the List
$computerlist | % {
#Run the script block for each computer based on the number of threads chosen (RunspacePool)
   $Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($_)
   $Job.RunspacePool = $RunspacePool
   $Jobs += New-Object PSObject -Property @{
      RunNum = $_
      Pipe = $Job
      Result = $Job.BeginInvoke()
   }
}

#Writes Waiting.. in console without adding a carriage return at the end.
Write-Host "Waiting.." -NoNewline
Do {
	#Keep adding a dot every one second appending it to the previous line without a carriage return
		#The final output of the while loop will be like: Waiting.......... All jobs completed!
   Write-Host "." -NoNewline
   Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false) #Run the loop until the above job is completed. 
Write-Host " All jobs completed!"
 
#Finally store the results contained in Job in an array called $Results.
$Results = @()
ForEach ($Job in $Jobs)
{   $Results += $Job.Pipe.EndInvoke($Job.Result)
}


#Populating CSV
	$Results | %{
		#Add a new line to the csv file (something like: LAP001,No,N/A)
		Add-Content -Path $csvOutput -Value "$($_.Computer), $($_.Pingable), $($_.IEVersion)"
	}

#Free up some memory afterwards:
	if (($i % 200) -eq 0)
	{
	[System.GC]::Collect()
	}

Gook luck!

Note:

When I say $tmp_array, it’s not an array, that’s an hash!

IT Droplets

IT Droplets