04 April, 2024

TeamViewer 'Console' - Manual automated update

 Some context may help...

We use TeamViewer to remotely support our users.

I don't know what the app used to manage / connect to others is actually called - So I call it the 'Console'.
'Host' is the client installed on all of the computers we support.

NOTE:
The 'Console' installs to this folder: C:\Program Files\TeamViewer\TeamViewer.exe
The 'Host' installs to this folder: C:\Program Files (x86)\TeamViewer\TeamViewer.exe


The console also acts as a 'Client' - So having the 'Client installed on my home computer, allows me to remote connect to my work computer and WFH easily... And conversely, from work, I can easily access my home computer, if needed.

From home - I kept running into (infrequently) not being able to connect to my work computer...
The computer would show, but as 'offline'...

  1. The updated file / installer would download...
  2. That installer would shutdown the current TeamViewer...
  3. And then the installer would fail to complete

(I think its ESET AV - but I am not going to try and explain this to my boss who controls that config - to much work - He turns everything into an argument.)

The end result - Teamviewer is not running, so I cant connect to the work computer...

I put together the below PoSh Script to get past the above problem...
It is a scheduled task that runs at 3AM every day - It takes about 6 minutes to complete
It downloads the most recent version of the Powershell 'Console'...
Compares the 'version info' of that download, to the 'version info' of the currently installed...

If needed, it proceeds to kill Teamviewer, and run the install from that download.
It presents a pop-up window beforehand with a warning, and other useful info...

After that completes, it restarts TeamViewer.
Verifies the downloaded vs. installed versions.

Even if no updates are needed - Regardless, it checks to see if TeamViewwer is running and if not will (attempt to) restart it.

Additionally, it logs all of the pertinent info (currently set to only hold 50 lines)
Log examples:
2024 APR 04, 03:08:39 AM | ~ UPDATED ~ From ver.: 15.52.3.0,  To ver.: 15.52.4.0 | Tv Running?: yes
2024 APR 04, 03:07:01 AM | Installed: 15.52.3.0 vs. Downloaded: 15.52.4.0 - Update needed?: YES | Tv Running?: yes
2024 APR 03, 03:06:55 AM | Installed: 15.52.3.0 vs. Downloaded: 15.52.3.0 - Update needed?: no | Tv Running?: yes
2024 APR 02, 03:06:55 AM | Installed: 15.52.3.0 vs. Downloaded: 15.52.3.0 - Update needed?: no | Tv Running?: yes


Here is the script (forgive my command abbreviations - That's just how I roll):

$LogFile_Path = "C:\Users\richie\Documents\PoSh_Stuff\TvUpdateReport.txt"

$DL_Path = "C:\Users\Public\Downloads"

$App_Path = "C:\Program Files\TeamViewer\TeamViewer.exe"
Function Running { Get-Process | ? { $_.Path -eq $App_Path } }

Function Report {"$Report`n$(gc $LogFile_Path | Select -First 50 | Out-String)" | Out-File $LogFile_Path -Force}

$URL = "https://download.teamviewer.com/download/TeamViewer_Setup_x64.exe"
$SaveFile = "$DL_Path\$(Split-path $URL -Leaf)" 
iwr -Uri "$URL" -OutFile $SaveFile

$DataInfo = gci $SaveFile | Select Name, FullName

If (!$DataInfo) {Break}
$DL_Path = ($DataInfo).FullName
#####################################
$shellfolder = $null; $shellfolder = (New-Object -COMObject Shell.Application).Namespace($(Split-Path ($DataInfo).FullName))
$shellfile = $null; $shellfile = $shellfolder.ParseName($(Split-Path ($DataInfo).FullName -Leaf))

$Downloaded = $null; $Downloaded = [System.Version]::Parse($($shellfolder.GetDetailsOf($shellfile, 166) )) # 166 is the metatag value for the "File version" tag.
$Installed = $null; $Installed = (Get-Item $App_Path).VersionInfo.FileVersionRaw

$D_version = "$($Downloaded.Major).$($Downloaded.Minor).$($Downloaded.Build).$($Downloaded.Revision)"
$I_version = "$($Installed.Major).$($Installed.Minor).$($Installed.Build).$($Installed.Revision)"
$NeedsUpdate = "no"
If ($Downloaded -gt $Installed) {$NeedsUpdate = "YES"}

$Tv_Running = "NO"; If ( Running ) { $Tv_Running = "yes" }
If ($Tv_Running -ne "yes") {Start $App_Path}

$FormatDate = $((Get-Date).ToString("yyyy '$(((Get-Culture).DateTimeFormat.GetAbbreviatedMonthName(((Get-Date)).Month)).ToUpper())' dd, hh:mm:ss tt"))
$Report = "$FormatDate | Installed: $I_version vs. Downloaded: $D_version - Update needed?: $NeedsUpdate | Tv Running?: $Tv_Running"
Report
##  gc $LogFile_Path

If (!$Downloaded -or !$Installed) {Break}
    If ($Downloaded -gt $Installed) {
        If ($Host.Name -match "ISE") { 
        ''; Write-Host "DOWNLOADED TeamViewer version:" -F 14 -B 2; Write-Host ($Downloaded | Out-String).Trim() -F 10
        ''; Write-Host "INSTALLED TeamViewer version:" -F 5 -B 14; Write-Host ($Installed | Out-String).Trim() -F 14
        }

$PopUpMsg = @"
In about 30 seconds...
TEAMVIEWER WILL SHUTDOWN...
It will be UPDATED... 
From: $Installed 
To  : $Downloaded
THEN Teamviewer will restart.

THIS TAKES ABOUT A MINUTE OR TWO.
You should then be able to reconnect to this comouter if needed.
"@
Msg /TIME:30 * $PopUpMsg
Sleep 29.5

Get-Process | ? {$_.Path -match "TeamViewer.exe" } | Stop-Process -Force
Sleep 3; cmd.exe /c "$SaveFile" /S
Sleep 3; Start $App_Path
}

If (!( Running )) {
Sleep 10; Start $App_Path
}

If ($Host.Name -match "ISE") { If ($Downloaded -le $Installed) { Write-Host "TeamViewer is Up-to-date..." -F 10 -B 2} }

If ($Downloaded -gt $Installed) {
$Prev_I_version = $I_version
$Installed = $null; $Installed = (Get-Item $App_Path).VersionInfo.FileVersionRaw
$I_version = "$($Installed.Major).$($Installed.Minor).$($Installed.Build).$($Installed.Revision)"
Sleep 10
$Tv_Running = "NO"; If ( Running ) { $Tv_Running = "yes" }
If ($Tv_Running -ne "yes") {Start $App_Path}

$FormatDate = $((Get-Date).ToString("yyyy '$(((Get-Culture).DateTimeFormat.GetAbbreviatedMonthName(((Get-Date)).Month)).ToUpper())' dd, hh:mm:ss tt"))
$Report = "$FormatDate | ~ UPDATED ~ From ver.: $Prev_I_version,  To ver.: $I_version | Tv Running?: $Tv_Running"
Report
##  gc $LogFile_Path
}

No comments:

Post a Comment