Terminal.ps1

$ScriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent

. ($ScriptDir + "./Global.ps1")

$TerminalProductName =  "logeto-terminal"
$TerminalPackageName = "B158BDD8.LogetoTerminal"
$TerminalProcessName = "Logeto.Client.Windows.Terminal"
$dependecies = $null

$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
    $appxVersion = Get-LogetoAppxVersion $TerminalPackageName        
    return Get-LogetoUpdateInfo -Product $TerminalProductName -Scope $scope -Version $appxVersion
}

<#
    Install logeto-terminal product
#>

function Install-LogetoTerminal {

    Param(
        [parameter(Mandatory=$true)]
        $UpdateInfo
    )

    Write-LogetoDebug "Installing terminal" 

    Get-LogetoProduct $UpdateInfo $ProductName
    
    # Support for uninstall
    $keyname = "LogetoTerminal"
    $regname = "HKCU:\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" -Force

    $value = $AppFolderPath + $ProductName + "Uninstall\LogetoInstaller.exe -uninstallAsCurrentUser"
    New-ItemProperty -Path $fullpath -Name "UninstallString" -Value $value -Force

    New-ItemProperty -Path $fullpath -Name "Publisher" -Value "Systemart s.r.o." -Force

    $value = $AppFolderPath + $ProductName + "Uninstall\ProductLogo.ico"
    New-ItemProperty -Path $fullpath -Name "DisplayIcon" -Value $value -Force

    Update-Package

    #Register task
    $A = New-ScheduledTaskAction �Execute $AppFolderPath\$ServiceProductName\TerminalAppxUpdate.vbs `"$AppFolderPath\$ServiceProductName\TerminalAppxUpdate.ps1`"
    $T = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 60)
    $U = $(whoami)
    $N = [Environment]::UserName
    $S = New-ScheduledTaskSettingsSet
    $name = "Logeto Terminal Appx 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
}

Function Get-DependencyPackages
{
    $dependencyPackagesDir = (Join-Path $DownloadFolderPath\$TerminalProductName\Dependencies") $dependencyPackages = @() if (Test-Path $dependencyPackagesDir) { # Get architecture-neutral dependencies $dependencyPackages += Get-ChildItem (Join-Path $dependencyPackagesDir "*.appx") | 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" } } 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" } } 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" } } } if ($dependencyPackages.FullName.Count -gt 0) { Write-Host "Found $($dependencyPackages.FullName.Count) dependecies:" -ForegroundColor Cyan Write-Host ($dependencyPackages.FullName | Out-String) } $dependecies = $dependencyPackages } Function Test-PlatformAndPackageFile($processorArch, $appxArch) { $path = Get-ChildItem (Join-Path $DownloadFolderPath\$TerminalProductName "\*_$appxArch.appx") if (($Env:Processor_Architecture -eq $processorArch) -and ($path)) { return $path } } Function Get-PlatformPackage { if ($appx = Test-PlatformAndPackageFile 'amd64' 'x64') { return $appx } if (($appx = Test-PlatformAndPackageFile 'x86' 'x86') -or ($appx = Test-PlatformAndPackageFile 'amd64' 'x86')) { return $appx } if ($appx = Test-PlatformAndPackageFile 'arm' 'arm') { return $appx } } Function Update-Package { Write-Host "Updating package `"$TerminalPackageName`"" -ForegroundColor Yellow $addPackageSucceeded = $false Write-Host "Phase 1" Test-WindowsVersion Write-Host "Phase 2" Get-DependencyPackages Write-Host "Phase 3" $packagePath = Get-PlatformPackage if (!($packagePath)) { throw [System.IO.FileNotFoundException] "Appx file not found" } Write-Host "Phase 4" if ($TerminalProcessName) { $appProcess = Get-Process $TerminalProcessName -ErrorAction SilentlyContinue Write-Host "Phase 5 $appProcess" } $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 "Found appx: $packagePath" Write-Host "Installing new appx..." -ForegroundColor Cyan if ($dependecies.FullName.Count -gt 0) { Add-AppxPackage -Path $packagePath.FullName -DependencyPath $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 } $filePath = Join-Path $scriptDir $systemartInstaller; if (Test-Path ($filePath)) { Copy-Item -Path $filePath -Destination (Split-Path -parent $scriptDir) -Force } 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 WriteLine([System.IO.MemoryStream] $body, [String] $str) { $encoded = [System.Text.Encoding]::ASCII.GetBytes($str + [Environment]::NewLine) } <# Install logeto-terminal product #> function Uninstall-LogetoTerminal { Write-LogetoDebug "Uninstalling terminal" $package = Get-AppxPackage -Name $TerminalPackageName if ($package) { Stop-Process -Name $TerminalProcessName -ErrorAction SilentlyContinue Remove-AppxPackage $package } $keyname = "LogetoTerminal" $regname = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $fullpath = $regname + "\" + $keyname if (Test-Path $fullpath) { Remove-Item -Path $fullpath -Recurse } $value = Join-Path $AppFolderPath $TerminalProductName Remove-Item -Path $value -Recurse -ErrorAction SilentlyContinue # Unregister task $N = [Environment]::UserName $name = "Logeto Terminal Appx Update ($N)"
    $taskExists = (Get-ScheduledTask | Where-Object {$_.TaskName -eq $name })
    if ($taskExists)
    {
        Write-LogetoDebug "
Logeto Terminal Appx Update task revert" -Debug Write-LogetoProgress "Removing old appx task" "ScriptUnRegisterAppxUpdateTaskRemovingTask" UnRegister-ScheduledTask -TaskName $name -Confirm:$false } else { Write-LogetoDebug "Cannot uninstal Logeto Terminal Appx Update task" -Debug } } <# 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 Set-LogetoTerminalEnvironment { Param( [parameter(Mandatory=$true)] [ValidateSet('Sideloading', 'SystemartCertificate', 'Uninstall', 'LoopbackExemption')] $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 'Uninstall') { if (!(Get-IsElevated)) { throw Get-LogetoCustomException "Adding support for uninstalling can be run only as an admin!" "" $ResultExceptionThrown 0 } 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" -Force $value = "$AppFolderPath\$TerminalProductName\Uninstall\" + $ExeFileName + " -uninstallAsCurrentUser" New-ItemProperty -Path $fullpath -Name "UninstallString" -Value $value -Force New-ItemProperty -Path $fullpath -Name "Publisher" -Value "Systemart s.r.o." -Force $value = "$AppFolderPath\$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 = "$AppFolderPath\$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 -Name "$TerminalPackageName").PackageFamilyName CheckNetIsolation LoopbackExempt -a -n="$packageFamilyName" } }