Quickly update Windows SysInternals executables

Discussion in 'Scripting' started by GodHand, Jul 2, 2019.

  1. GodHand

    GodHand MDL Senior Member

    Jul 15, 2016
    434
    491
    10
    This function will download the latest Windows SysInternals Suite, compare the files and update any that have been updated. This is quicker than manually downloading the entire suite package and copying over all of its contents, and can be done in a single simple command.

    This can be added to a current PowerShell module or pasted directly into PowerShell or PowerShell ISE. Further examples are included within the function.

    Code:
    Function Update-SysInternals
    {
    <#
        .SYNOPSIS
           Automatically updates any SysInternals Suite utility with its most recent file version.
       
       .DESCRIPTION
           Automatically updates any SysInternals Suite utility with its most recent file version.
       
       .PARAMETER SuitePath
           The directory path to the SysInternals Suite utilities.
       
       .EXAMPLE
           PS C:\> Update-SysInternals -SuitePath "C:\SysInternalsSuite"
           PS C:\> "C:\Tools and Utilities\SysInternals" | Update-SysInternals
    #>
        [CmdletBinding()]
        Param
        (
            [Parameter(Mandatory = $true,
                       ValueFromPipeline = $true,
                       ValueFromPipelineByPropertyName = $true,
                       Position = 0,
                       HelpMessage = 'The directory path to the SysInternals Suite utilities.')]
            [ValidateScript({ Test-Path $(Resolve-Path -Path $_) })]
            [string]$SuitePath
        )
        
        Begin
        {
            $ArchiveURL = "http://live.sysinternals.com/Files/SysinternalsSuite.zip"
            $ArchivePath = Join-Path -Path $Env:TEMP -ChildPath SysinternalsSuite.zip
        }
        Process
        {
            If (!(Test-Connection $Env:COMPUTERNAME -Quiet))
            {
                Write-Warning "The update requires an active internet connection."
                Break
            }
            Else
            {
                Write-Host "Beginning Update..." -NoNewline -ForegroundColor Cyan
                (New-Object System.Net.WebClient).DownloadFile($ArchiveURL, $ArchivePath)
                $RunningProcess = Get-Process -Name ZoomIt*, Desktops*, procexp* -ErrorAction SilentlyContinue
                $ProcessPath = $RunningProcess | Where-Object Name -NotLike "*64" | Select-Object -Property Path
                If ($RunningProcess) { $RunningProcess | Stop-Process -Force -ErrorAction SilentlyContinue }
                $Current = Get-ChildItem -Path $SuitePath -Force
                $Updated = Get-ChildItem -Path $SuitePath -Force
                Expand-Archive -LiteralPath $ArchivePath -DestinationPath $SuitePath -Force
                Compare-Object -ReferenceObject $Current -DifferenceObject $Updated | Select-Object -ExpandProperty InputObject | ForEach-Object -Process { Get-ChildItem -Path ($SuitePath + '\' + $($_)) -Force } | Select-Object -Property Name, CreationTime
                Write-Host "[Complete]" -ForegroundColor Cyan
            }
        }
        End
        {
            If ($ProcessPath) { $ProcessPath | ForEach-Object -Process { Start-Process -FilePath $_.Path -ErrorAction SilentlyContinue } }
            Remove-Item -Path $ArchivePath -Force -ErrorAction SilentlyContinue
        }
    }