Terminal.ps1
$ScriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent . ($ScriptDir + "/Global.ps1") $TerminalProductName = "Terminal" $TerminalPackageName = "B158BDD8.LogetoTerminal" $TerminalProcessName = "Logeto.Client.Windows.Terminal" $TerminalDownloadFolderPath = $LogetoFolder + $TerminalProductName + "\" + $DownloadFolder $TerminalUpdateFolderPath = $LogetoFolder + $TerminalProductName + "\" + $UpdateFolder $TerminalSystemUpdateFolderPath = $LogetoFolder + $TerminalProductName + "\" + $SystemUpdateFolder $MinWinVersionMajor = 10 $MinWinVersionMinor = 0 $MinWinVersionBuild = 14393 <# Return Json file for Terminal appx, if there is no newer version null is returned. #> function Get-LogetoTerminalUpdateInfo { Write-LogetoDebug "Getting Terminal Update Info." $scope = Get-LogetoScope Write-LogetoDebug "Get scope $TerminalProductName $scope." $appxVersion = Get-LogetoAppxVersion $TerminalPackageName Write-LogetoDebug "Getting Terminal Update Info $TerminalProductName $scope $appxVersion." return Get-LogetoUpdateInfo -Product $TerminalProductName -Scope $scope -Version $appxVersion } <# Install Logeto Terminal #> function Install-LogetoTerminal { Param( [parameter(Mandatory=$true)] $UpdateInfo ) Write-LogetoDebug "Installing terminal" Get-LogetoProduct $UpdateInfo $TerminalProductName Write-LogetoProgress "Installing terminal after download" "ModuleInstallLogetoProductTerminal" Install-Package # Clear download folder Remove-Item -Path $TerminalDownloadFolderPath -Recurse -ErrorAction SilentlyContinue } <# Uninstall Logeto Terminal #> function Uninstall-LogetoTerminal { Write-LogetoDebug "Uninstalling terminal" # Uninstall AppxPackage $package = Get-AppxPackage -Name $TerminalPackageName if ($package) { Stop-Process -Name $TerminalProcessName -ErrorAction SilentlyContinue Remove-AppxPackage $package } } <# Return Json file from the URL for set product and scope. If version parameter is set it returns Json file only if higher version was found, otherwise returns null. #> function Clear-LogetoTerminalEnvironment { Param( [parameter(Mandatory=$true)] [ValidateSet('Uninstaller', 'UpdateTask', 'SystemUpdateTask')] $Components ) # Allow uninstalling of an application if ($Components -eq 'Uninstaller') { Write-LogetoDebug "Clearing uninstall option" $keyname = "LogetoTerminal" $regname = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $fullpath = $regname + "\" + $keyname if (Test-Path $fullpath) { Remove-Item -Path $fullpath -Recurse } } if ($Components -eq 'UpdateTask') { Write-LogetoDebug "Clearing Scheduler Update Task" $N = [Environment]::UserName $name = "Logeto Terminal Update ($N)" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if ($taskExists) { Write-LogetoDebug "Logeto Terminal Update task revert" -Debug Write-LogetoProgress "Removing old Terminal Update task" "ScriptUnRegisterAppxUpdateTaskRemovingTask" UnRegister-ScheduledTask -TaskName $name -Confirm:$false } else { Write-LogetoDebug "Cannot uninstal Logeto Terminal Update task" -Debug } Remove-Item -Path $TerminalUpdateFolderPath -Recurse -ErrorAction SilentlyContinue } if ($Components -eq 'SystemUpdateTask') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Removing System Update Task can be done only as an administrator!" "" $ResultExceptionThrown 0 } Write-LogetoDebug "Clearing Scheduler Update Task" $name = "Logeto Terminal System Update" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if ($taskExists) { Write-LogetoDebug "Logeto Terminal System Update task revert" -Debug Write-LogetoProgress "Removing old appx task" "ScriptUnRegisterAppxUpdateTaskRemovingTask" UnRegister-ScheduledTask -TaskName $name -Confirm:$false } else { Write-LogetoDebug "Cannot uninstal Logeto Terminal System Update task" -Debug } Remove-Item -Path $TerminalSystemUpdateFolderPath -Recurse -ErrorAction SilentlyContinue } } function Set-LogetoTerminalEnvironment { Param( [parameter(Mandatory=$true)] [ValidateSet('Sideloading', 'SystemartCertificate', 'Uninstaller', 'LoopbackExemption', 'UpdateTask', 'SystemUpdateTask')] $Components ) # Allow sideloading if ($Components -eq 'Sideloading') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Allow sideloading can be run only as an admin!" "" $ResultExceptionThrown 0 } Write-LogetoDebug "Allowing sideloading" $keyname = "AllowAllTrustedApps" $regname = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" if (Test-Path $regname) { $regvalue = (Get-ItemProperty -Path $regname).$keyname if ($regvalue -lt 1) { New-ItemProperty -Path $regname -Name $keyname -Value 1 -PropertyType DWORD -Force } } } # Allow uninstalling of an application if ($Components -eq 'Uninstaller') { Write-LogetoDebug "Allowing uninstall" $keyname = "LogetoTerminal" $regname = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $fullpath = $regname + "\" + $keyname if (-Not (Test-Path $fullpath)) { New-Item -Path $regname -Name $keyname } New-ItemProperty -Path $fullpath -Name "DisplayName" -Value "Logeto Terminal Cleanup" -Force $value = "$LogetoFolder$TerminalProductName\Uninstall\Uninstall.exe -uninstallAsCurrentUser" New-ItemProperty -Path $fullpath -Name "UninstallString" -Value $value -Force New-ItemProperty -Path $fullpath -Name "Publisher" -Value "Systemart s.r.o." -Force $value = "$LogetoFolder$TerminalProductName\Uninstall\ProductLogo.ico" New-ItemProperty -Path $fullpath -Name "DisplayIcon" -Value $value -Force } # Install Systemart certificate if ($Components -eq 'SystemartCertificate') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Installing systemart certificate can be run only as an admin!" "" $ResultExceptionThrown 0 } Write-LogetoDebug "Installing systemart certificate" $cert = "$LogetoFolder$TerminalProductName\Install\SystemartCertificationAuthority.crt" Write-LogetoDebug "Installing certificate" "ScriptTerminalCertificateInstalling" Import-Certificate -FilePath $cert -CertStoreLocation Cert:\LocalMachine\Root } if ($Components -eq 'LoopbackExemption') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Allow sideloading can be run only as an admin!" "" $ResultExceptionThrown 0 } Write-LogetoDebug "Allowing Loopback Exemption" $packageFamilyName = (Get-AppxPackage -AllUsers -Name "$TerminalPackageName").PackageFamilyName CheckNetIsolation LoopbackExempt -a -n="$packageFamilyName" } if ($Components -eq 'UpdateTask') { Write-LogetoDebug "Creating Scheduler Update Task" Write-LogetoDebug "Path to file: $PSScriptRoot\TerminalUpdate.vbs" Write-LogetoDebug "Destination path: $TerminalUpdateFolderPath" New-Item -ItemType Directory $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalUpdate.vbs" -Destination $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalUpdate.ps1" -Destination $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\InstallLogetoModule.ps1" -Destination $TerminalUpdateFolderPath -Force $A = New-ScheduledTaskAction –Execute $TerminalUpdateFolderPath\TerminalUpdate.vbs `"$TerminalUpdateFolderPath\TerminalUpdate.ps1`" $T = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 60) $U = $(whoami) $N = [Environment]::UserName $S = New-ScheduledTaskSettingsSet $name = "Logeto Terminal Update ($N)" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if ($taskExists) { Write-LogetoDebug "Logeto Terminal Appx Update task exists" Write-LogetoProgress "Removing old appx task" "ScriptRegisterAppxUpdateTaskRemovingTask" UnRegister-ScheduledTask -TaskName $name -Confirm:$false } else { Write-LogetoDebug "Logeto Terminal Appx Update task do not exists" } Write-LogetoProgress "Registering new appx task" "ScriptRegisterAppxUpdateTaskRegisteringTask" Register-ScheduledTask -TaskName $name -Action $A -Trigger $T -Settings $S -User $U -Force } if ($Components -eq 'SystemUpdateTask') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Creating System Update Task for Terminal can be run only as an admin!" "" $ResultExceptionThrown 0 } Write-LogetoDebug "Creating Scheduler System Update Task" Write-LogetoDebug "Path to file: $PSScriptRoot\TerminalSystemUpdate.vbs" Write-LogetoDebug "Destination path: $TerminalSystemUpdateFolderPath" New-Item -ItemType Directory $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalSystemUpdate.vbs" -Destination $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalSystemUpdate.ps1" -Destination $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\InstallLogetoModule.ps1" -Destination $TerminalSystemUpdateFolderPath -Force $A = New-ScheduledTaskAction –Execute $TerminalSystemUpdateFolderPath\TerminalSystemUpdate.vbs `"$TerminalSystemUpdateFolderPath\TerminalSystemUpdate.ps1`" $T = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 60) $S = New-ScheduledTaskSettingsSet $P = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType S4U -RunLevel Highest $name = "Logeto Terminal System Update" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if ($taskExists) { Write-LogetoDebug "Logeto Terminal System Update task exists" -Debug Write-LogetoProgress "Removing old service task" "ScriptRegisterServiceUpdateTaskRemovingTask" UnRegister-ScheduledTask -TaskName $name -Confirm:$false } else { Write-LogetoDebug "Logeto Terminal System Update task do not exists" -Debug } Write-LogetoProgress "Registering new service task" "ScriptRegisterServiceUpdateTaskRegisteringTask" Register-ScheduledTask -TaskName $name -Action $A -Trigger $T -Settings $S -Principal $P -Force } } Function Install-Package { Write-Host "Updating package `"$TerminalPackageName`"" -ForegroundColor Yellow $oldAppxVersion = Get-LogetoAppxVersion $TerminalPackageName $addPackageSucceeded = $false Test-WindowsVersion Get-DependencyPackages $packagePath = Get-PlatformPackage if (!($packagePath)) { throw [System.IO.FileNotFoundException] "Application package not found" } if ($TerminalProcessName) { $appProcess = Get-Process $TerminalProcessName -ErrorAction SilentlyContinue } $aaProcess = Get-Process "AssignedAccessLockApp" -ErrorAction SilentlyContinue $package = Get-AppxPackage -Name "$TerminalPackageName" if ($package) { Write-Host "Stopping service process" Stop-Process -Name $TerminalProcessName -ErrorAction SilentlyContinue Write-Host "Waiting for 5 seconds" Start-Sleep -s 5 } Write-Host "Installing new package..." -ForegroundColor Cyan if ($global:dependecies.FullName.Count -gt 0) { Add-AppxPackage -Path $packagePath.FullName -DependencyPath $global:dependecies.FullName -ForceApplicationShutdown -Verbose -EV addPackageError } else { Add-AppxPackage -Path $packagePath.FullName -ForceApplicationShutdown -Verbose -EV addPackageError } $addPackageSucceeded = $? if (!$addPackageSucceeded) { $reportMessage = "Failed to update package `"$TerminalPackageName`"" Write-Host $reportMessage -ForegroundColor Red -BackgroundColor Black if ($addPackageError -and ($addPackageError.Count -gt 0)) { $found = $addPackageError[0] -match 'Get-AppxLog -ActivityID (?<activityID>\w\w\w\w\w\w\w\w-\w\w\w\w-\w\w\w\w-\w\w\w\w-\w\w\w\w\w\w\w\w\w\w\w\w)' if ($found) { Write-Host 'Getting AppxLog' -NoNewline # Sometimes Get-AppxLog returns the old log (or nothing) when it's called too early after Add-AppxPackage for ($i = 0; $i -lt 5; $i++) { Start-Sleep -S 1 Write-Host '.' -NoNewline } $activityLog = 'Activity log:' + (Get-AppxLog -ActivityId $matches['activityID'] | Out-String) $reportMessage += ' - More information in the activity log' Write-Host } } Send-ReportToHockeyApp $reportMessage $exception $activityLog exit $resultExceptionThrown } Update-LogetoTerminal $oldAppxVersion (Get-LogetoAppxVersion $TerminalPackageName) if ($aaProcess) { Write-Host "Restarting computer..." Restart-Computer -Force } # Restart app if not in Assigned Access and app was running elseif ($appProcess) { Write-Host "Restarting app..." Start-Process -FilePath "explorer.exe" -ArgumentList "shell:AppsFolder\$($package.PackageFamilyName)!App" } } Function Test-WindowsVersion { $version = (Get-WmiObject Win32_OperatingSystem).Version.Split(".") $major = $version[0] -as [int] $minor = $version[1] -as [int] $build = $version[2] -as [int] if (($major -lt $MinWinVersionMajor) -or (($minor -lt $MinWinVersionMinor) -and ($major -le $MinWinVersionMajor)) -or ($build -lt $MinWinVersionBuild)) { throw [System.NotSupportedException] "Unsupported Windows version: $major.$minor.$build - required at least: $MinWinVersionMajor.$MinWinVersionMinor.$MinWinVersionBuild" } } Function Get-DependencyPackages { $dependencyPackagesDir = (Join-Path $TerminalDownloadFolderPath "\Dependencies") $dependencyPackages = @() if (Test-Path $dependencyPackagesDir) { # Get architecture-neutral dependencies $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" } $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "*.msix") | Where-Object { $_.Mode -NotMatch "d" } # Get architecture-specific dependencies if (($Env:Processor_Architecture -eq "x86" -or $Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $dependencyPackagesDir "x86"))) { $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "x86\*.appx") | Where-Object { $_.Mode -NotMatch "d" } $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "x86\*.msix") | Where-Object { $_.Mode -NotMatch "d" } } if (($Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $dependencyPackagesDir "x64"))) { $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "x64\*.appx") | Where-Object { $_.Mode -NotMatch "d" } $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "x64\*.msix") | Where-Object { $_.Mode -NotMatch "d" } } if (($Env:Processor_Architecture -eq "arm") -and (Test-Path (Join-Path $dependencyPackagesDir "arm"))) { $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "arm\*.appx") | Where-Object { $_.Mode -NotMatch "d" } $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "arm\*.msix") | Where-Object { $_.Mode -NotMatch "d" } } } if ($dependencyPackages.FullName.Count -gt 0) { Write-Host "Found $($dependencyPackages.FullName.Count) dependecies:" -ForegroundColor Cyan Write-Host ($dependencyPackages.FullName | Out-String) } $global:dependecies = $dependencyPackages } Function Find-PlatformPackage($processorArch, $packageArch) { if ($Env:Processor_Architecture -eq $processorArch) { if ($result = Get-ChildItem (Join-Path $TerminalDownloadFolderPath "\*_$packageArch.msix")) { Write-Host "Found application package ($processorArch-$packageArch) $($result.FullName)" return $result } if ($result = Get-ChildItem (Join-Path $TerminalDownloadFolderPath "\*_$packageArch.appx")) { Write-Host "Found application package ($processorArch-$packageArch) $($result.FullName)" return $result } Write-Host "Unable to find application package ($processorArch-$packageArch)" } else { Write-Host "Skipping incompatible application packages for processor architecture $processorArch" } return $null } Function Get-PlatformPackage { if ($package = Find-PlatformPackage 'amd64' 'x64') { return $package } if (($package = Find-PlatformPackage 'x86' 'x86') -or ($package = Find-PlatformPackage 'amd64' 'x86')) { return $package } if ($package = Find-PlatformPackage 'arm' 'arm') { return $package } return $null } Function Update-LogetoTerminalEnvironment { Param( [parameter(Mandatory=$true)] [ValidateSet('All', 'UpdateTask', 'Uninstaller')] $Components ) if (($Components -eq 'UpdateTask') -or ($Components -eq 'All')) { $A = New-ScheduledTaskAction –Execute $TerminalUpdateFolderPath\TerminalUpdate.vbs `"$TerminalUpdateFolderPath\TerminalUpdate.ps1`" $T = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 60) $U = $(whoami) $N = [Environment]::UserName $S = New-ScheduledTaskSettingsSet $name = "Logeto Terminal Update ($N)" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if (-Not($taskExists)) { Register-ScheduledTask -TaskName $name -Action $A -Trigger $T -Settings $S -User $U -Force } New-Item -ItemType Directory $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalUpdate.vbs" -Destination $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalUpdate.ps1" -Destination $TerminalUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\InstallLogetoModule.ps1" -Destination $TerminalUpdateFolderPath -Force } if (($Components -eq 'Uninstaller') -or ($Components -eq 'All')) { $localPath = $LogetoFolder + $TerminalProductName + "\Uninstall" if ((Test-Path $localPath)) { Get-ChildItem -Path $localPath | Where-Object { $_.Name -like "*.exe" } | Select-Object -Skip 1 | %{ Remove-Item -Path $_.FullName -ErrorAction SilentlyContinue } Get-ChildItem -Path $localPath | Where-Object { $_.Name -like "*.exe" } | %{ Rename-Item -LiteralPath $_.FullName -NewName "Uninstall.exe" -ErrorAction SilentlyContinue } } } } Function Update-LogetoTerminalSystemEnvironment { Param( [parameter(Mandatory=$true)] [ValidateSet('All', 'SystemUpdateTask', 'Uninstaller')] $Components ) if (($Components -eq 'SystemUpdateTask') -or ($Components -eq 'All')) { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Creating System Update Task for Terminal can be run only as an admin!" "" $ResultExceptionThrown 0 } $A = New-ScheduledTaskAction –Execute $TerminalSystemUpdateFolderPath\TerminalSystemUpdate.vbs `"$TerminalSystemUpdateFolderPath\TerminalSystemUpdate.ps1`" $T = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 60) $S = New-ScheduledTaskSettingsSet $P = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType S4U -RunLevel Highest $name = "Logeto Terminal System Update" $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if (-Not($taskExists)) { Register-ScheduledTask -TaskName $name -Action $A -Trigger $T -Settings $S -Principal $P -Force } New-Item -ItemType Directory $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalSystemUpdate.vbs" -Destination $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalSystemUpdate.ps1" -Destination $TerminalSystemUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\InstallLogetoModule.ps1" -Destination $TerminalSystemUpdateFolderPath -Force # remove this code after TerminalService will be uninstalled # BEGIN $ServiceProductName = "TerminalService" $ServiceUpdateFolderPath = $LogetoFolder + $ServiceProductName + "\" + $UpdateFolder New-Item -ItemType Directory $ServiceUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalServiceUpdate.vbs" -Destination $ServiceUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\TerminalServiceUpdate.ps1" -Destination $ServiceUpdateFolderPath -Force Copy-Item -Path "$PSScriptRoot\InstallLogetoModule.ps1" -Destination $ServiceUpdateFolderPath -Force # END } if (($Components -eq 'Uninstaller') -or ($Components -eq 'All')) { $keyname = "LogetoTerminal" $regname = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $fullpath = $regname + "\" + $keyname $value = $LogetoFolder + $TerminalProductName + "\Uninstall\Uninstall.exe -uninstallAsCurrentUser" if ((Test-Path $fullpath)) { Remove-ItemProperty -Path $fullpath -Name "UninstallString" -Force New-ItemProperty -Path $fullpath -Name "UninstallString" -Value $value -Force } } } Function Update-LogetoTerminal($oldVersion, $newVersion) { if ($DefaultVersion -eq $oldVersion) { return } Write-LogetoDebug "Update-LogetoTerminal $oldVersion $newVersion" -Debug $patchVersion = "7.7.0" if (([System.Version]$patchVersion -gt [System.Version]$oldVersion) -And ([System.Version]$patchVersion -le [System.Version]$newVersion)) { $N = [Environment]::UserName $name = "Logeto Terminal Appx Update ($N)" Write-LogetoDebug "Trying delete task wit name $name" -Debug $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name }) if ($taskExists) { UnRegister-ScheduledTask -TaskName $name -Confirm:$false } } } |