How To Update All Sysinternals Tools Automatically

12

Whether you are an IT professionals or a Windows developer, you will find Sysinternals tools invaluable, helping you manage, troubleshoot and diagnose your Windows systems and applications. What’s more important, these tools regularly get updated by the team in Microsoft to keep them always ahead of the game. For example, both Sysmon and Procdump utilities are updated recently on April 28, 2016, and another one useful Sigcheck just got updated in February as well. But the problem is, it’s hard for us to keep our copy of their tools up-to-date. It would be nice if there is a better way than checking on their website regularly to find out what’s been updated.

Here is a PowerShell script that you may find very useful in this regard. It checks the tools from the Sysinternals website and downloads any newer tools if found any. The script is complete and ready to rock without any additional modules.

/Update March 9, 2018/

Download the script from the link above and update the folder path at the bottom to specify where the Sysinternals are saved on your computer.

Here is the original code in the script:

function Update-SysinternalsHTTP ($ToolsLocalDir = "c:\temp\sys")  
{ 
	if (Test-Path $ToolsLocalDir){ 
   		cd $ToolsLocalDir
   		$DebugPreference = "SilentlyContinue"
   		$wc = new-object System.Net.WebClient
   		$userAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)"
   		$wc.Headers.Add("user-agent", $userAgent)
   		$ToolsUrl = "http://live.sysinternals.com/"
   		$toolsBlock="<pre>.*</pre>"
   		$WebPageCulture = New-Object System.Globalization.CultureInfo("en-us")
   		$Tools = @{}
   		$ToolsPage = $wc.DownloadString($ToolsUrl)
   		$matches=[string] $ToolsPage |select-string -pattern  "$ToolsBlock" -AllMatches
   		foreach($match in $matches.Matches) {	
	    	$txt = ( ($match.Value  -replace "</A><br>", "`r`n") -replace  "<[^>]*?>","")
	    	foreach($lines in $txt.Split("`r`n")){
	        	$line=$lines|select-string  -NotMatch -Pattern "To Parent|^$|&lt;dir&gt;"
	        	if ($line -ne $null){
		        	$date=(([string]$line).substring(0,38)).trimstart(" ") -replace "  "," "
		         	$file=([string]$line).substring(52,(([string]$line).length-52))
                 	#Friday, May 30, 2008  4:55 PM          668 About_This_Site.txt
		         	$Tools["$file"]= [datetime]::ParseExact($date,"f",$WebPageCulture)
	        	}
	    	}
    	}

    	$Tools.keys|
		ForEach-Object {
        	$NeedUpdate=$false
	    	if (Test-Path $_)
	    	{
	        	$SubtractSeconds = New-Object System.TimeSpan 0, 0, 0, ((dir $_).lastWriteTime).second, 0
	    		$LocalFileDate= ( (dir $_).lastWriteTime ).Subtract( $SubtractSeconds )
	    		$needupdate=(($tools[$_]).touniversaltime() -lt $LocalFileDate.touniversaltime())
	    	} else {$NeedUpdate=$true}
	    	if ( $NeedUpdate ) 
	    	{
		    	Try {
	            		$wc.DownloadFile("$ToolsUrl/$_","$ToolsLocalDir$_" )
	            		$f=dir "$ToolsLocalDir$_"
	            		$f.lastWriteTime=($tools[$_])
						"Updated $_"
		       		}
		    	catch { Write-debug "An error occurred: $_" }
	    	} 
    	} 
  	}
}

cls

"Update started..."

Update-Sysinternalshttp -ToolsLocalDir "Z:\Desktop\C-20130201\PSTools"

"The End"

Replace “Z:\Desktop\C-20130201\PSTools” with the actual folder path in your case and you are good to go.

Windows PowerShell 2016 05 10 23 41 59 600x348 - How To Update All Sysinternals Tools Automatically

You can manually run it either from PowerShell console, like the screenshot above, or Command Prompt window, running the following command, assuming the Update-Sysinternals.ps1 is saved on my desktop.

powershell.exe  -executionpolicy bypass -command "c:\Users\kent\Desktop\Update-Sysinternals.ps1"

Command Prompt 2016 05 10 23 49 09 600x388 - How To Update All Sysinternals Tools Automatically

You can also use the script to download all Sysinternals tools from scratch without going to their website. Just make sure you have the folder that saves these tools ready before running the script.

And of course, you can add it in the Task Scheduler to have it run in schedule automatically.

12 COMMENTS

  1. I dont think this is an update script.
    powershell.exe -executionpolicy bypass -command “C:UsersgasDesktopUpdate-Sysinternals.ps1”
    and all the tools will be downloaded in c:prosys ( if the folder exist else do nothing…)

    You cant schedule this to run weekly or monthly, as it will do nothing if folder exists.
    If folder does exists, it will do nothing as well.
    Will only work if empty folder exists?
    What is the real purpose of this?

    • Thanks for the info about not updating when the folder exists. I tested the code manually with or without the folder existence and it worked in both cases, so I assumed it should work fine in the task scheduler.

      Anyway, I guess it’s still useful in a way that it updates all the tools in the suite automatically. If it doesn’t update when the folder exists, it’s easy to purge the folder before running the script in the scheduler.

  2. what a joke

    Update-Sysinternalshttp : The term ‘Update-Sysinternalshttp’ is not recognized as the name of a cmdlet, function, script file,
    or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:1
    + Update-Sysinternalshttp -ToolsLocalDir “c:\sysinternals”
    + ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Update-Sysinternalshttp:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    if you’re going to post an article on how to do something, at least make sure it actually works….christ alive.

  3. Thanks for the script. Although I wasn’t able to get it running. I’ve barely done anything with PowerShell but from what I understand the issue is a different date / time formatting on my machine:

    Exception calling “ParseExact” with “3” argument(s): “String was not recognized as a valid DateTime.”
    At D:\tools\UpdateSysinternals.ps1:23 char:13
    + $Tools[“$file”]= [datetime]::ParseExact($date,”f”,$WebPageCulture)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

    Exception calling “Substring” with “2” argument(s): “startIndex cannot be larger than length of string.
    Parameter name: startIndex”
    At D:\tools\UpdateSysinternals.ps1:21 char:13
    + $file=([string]$line).substring(52,(([string]$line).length-52))
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

    Value of $line: 6/28/2019 1:07 PM 761656 Autoruns.exe
    Value of $date: 6/28/2019 1:07 PM 761656 Autor

    I’m now working on my own implementation.

LEAVE A REPLY

Please enter your comment!
Please enter your name here