powershellauto-update

Powershell Script Self Update and Rerun


I have been attempting to create a script that will check a central location, get the hash, and if it doesn't match, replace itself with the one from the central location.

I believe I have everything I need in place, but the issue I am running into right now is that it won't replace itself.

Is this something that is physically possible?

The other script is nearly identical, I only added to the Write-Host in order to get different hashes.

#Get the current path of the running script
$mypath = $MyInvocation.MyCommand.Path

#Path of the central script for updating
$ScriptUpdateLocation = "C:\Users\user\Desktop\Scripts\Update Script if update is found\Update from me.ps1"

#Get Hashes of the currently running script and the script specified in $ScriptUpdateLocation
$MyHash = Get-FileHash -Path $mypath
$UpdateHash = Get-FileHash -Path $ScriptUpdateLocation

if ($MyHash.Hash -cne $UpdateHash.Hash){
    [void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
    $msg   = "You have an outdated version of this script, would you like to update?"
    $wshell = New-Object -ComObject Wscript.Shell
    $UpdatingScript = $wshell.Popup($msg,0,"Alert",64+4)
    If($UpdatingScript -eq 7){
        Copy-Item -Path $ScriptUpdateLocation -Destination $mypath -Force
        $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
    }
 }else{
    Write-Host "YOU ARE THE GOODIST BOI, CONGRATS, YOU ARE UPDATED!"
    Exit
}

Solution

  • Copy-Item is likely giving you an error that the file can't overwrite with itself. Try reading the .ps1 content and then Set-Content instead which seem to work for me.

    Change:

    Copy-Item -Path $ScriptUpdateLocation -Destination $mypath -Force
    

    To:

    Get-Content $ScriptUpdateLocation -Raw | Set-Content $PSCommandPath
    

    Note you could use the automatic variable $PSCommandPath.