PowerShell Script autoUpdate

Posted by : on

Category : powershell   scripts   update   git   autoupdate


Auto Update for PowerShell scripts

This script will check the remote repository to se if there’s a new version of he current script file, if so, it will update it and re-run it.

Initializaton, get the git exe path and the current script path


  $GitCmd = (Get-Command "git.exe")
  if($Null -eq $GitCmd){ throw "git.exe not found" }
  $GitExe = $GitCmd.Source
  $ScriptPath = "$PSCommandPath"

Get the branches names for the local and the remote branch…

  $RemoteBranch = & "$GitExe" 'for-each-ref' '--format=%(upstream:short)' "`"$(git symbolic-ref -q HEAD)`""
  $LocalBranch  = & "$GitExe" 'branch' '--show-current'

Get the current number of new revisions available, 0 if we are up to date

  [uint32]$NewVers = & "$GitExe" 'diff' "$RemoteBranch..$LocalBranch"  "$ScriptPath" | Measure-Object -Line | Select -ExpandProperty Lines

How to test

  1. Clone the repo at 2 different locations
  2. Update the AutoUpdate.ps1 script in one location (location 1) and commit/push
  3. Go to location #2, and run . .\AutoUpdate.ps1

You will get this:

  > . .\AutoUpdate.ps1

  This script was updated and will restart.
  Hello World

Check for New Version

This Test-NewScriptVersion function will get the local and remote branches names and use them to diff the local script ( $PSCommandPath ) with the version in the repo. If there is a difference, we know we need to update.


  function Test-NewScriptVersion{
    [CmdletBinding(SupportsShouldProcess)]
    param() 

    begin{
      try{
        $GitCmd = (Get-Command "git.exe")
        if($Null -eq $GitCmd){ throw "git.exe not found" }
        $GitExe = $GitCmd.Source
        $ScriptPath = "$PSCommandPath"
        if(-not(Test-Path -Path "$ScriptPath")){ throw "file not found" }
      }catch{
        write-error "$_"
      }
    }
    process{
      try{
        $RemoteBranch = & "$GitExe" 'for-each-ref' '--format=%(upstream:short)' "`"$(git symbolic-ref -q HEAD)`""
        $LocalBranch  = & "$GitExe" 'branch' '--show-current'
        Write-Verbose "Remote Branch: `"$RemoteBranch`""
        Write-Verbose "Local  Branch: `"$LocalBranch`""
        $Output = & "$GitExe" 'fetch' *> "$ENV:Temp\gitout.txt" | Out-Null
        $HeadRev = & "$GitExe"  'log' '-n' '1' '--no-decorate' '--pretty=format:%H'  "$ScriptPath"
        $Ret = $False
        [uint32]$NewVers = & "$GitExe" 'diff' "$RemoteBranch..$LocalBranch"  "$ScriptPath" | Measure-Object -Line | Select -ExpandProperty Lines
        if($NewVers -gt 0){
            Write-Verbose "A new version is available for `"$ScriptPath`"" 
            Write-Verbose "Head Rev: `"$HeadRev`""
            $Ret = $True
            
        }else{
             Write-Verbose "No updates for `"$ScriptPath`"" 
             Write-Verbose "Head Rev: `"$HeadRev`"" 
        }

        $Ret
      }catch{
        write-error "$_"
      }
    }
  }

Update the Script

Simple Git Pull


  function Update-ScriptVersion{
    [CmdletBinding(SupportsShouldProcess)]
    param() 

    begin{
      try{
        $GitCmd = (Get-Command "git.exe")
        if($Null -eq $GitCmd){ throw "git.exe not found" }
        $GitExe = $GitCmd.Source
        $ScriptPath = "$PSCommandPath"
        if(-not(Test-Path -Path "$ScriptPath")){ throw "file not found" }
        $DirName = (Get-Item -PAth "$ScriptPath").DirectoryName
      }catch{
        write-error "$_"
      }
    }
    process{
      try{
        pushd "$DirName"
        $Output = & "$GitExe" 'pull' > "$ENV:Temp\gitout.txt" | Out-Null
        popd
      }catch{
        write-error "$_"
      }
    }
  }

Restart the Current Script

After we see we need to update and that the update was done, we restart the current script


  $NewVersionAvailable = Test-NewScriptVersion
  if($NewVersionAvailable){
    Update-ScriptVersion

    Write-Host "This script was updated and will restart."
    Start-Sleep 1
    . "$ScriptPath"
    # Start-Process pwsh.exe -ArgumentList ("-NoProfile -ExecutionPolicy Bypass -File `"{0}`"" -f $PSCommandPath)
    Exit
  }

  # To test, change the color...
  Write-Host "The script logic starts here..." -f Red



Get the code

AutoUpdateScript on GitHub

Important Note Do You have Issues accessing the core repository? Don’t be shy and send me an EMAIL to guillaumeplante.qc@gmail.com and I will fix access for you


About Guillaume Plante
Guillaume Plante

A developper with a passion for technology, music, astronomy and art. Coding range: hardware/drivers, security, ai,. c/c++, powershell

Email : guillaumeplante.qc@gmail.com

Website : https://arsscriptum.ddns.net

Useful Links