Global.ps1

$Global:UpdateInfoURL = "http://update-service.logeto.com/"
$Global:DefaultVersion = "1.0.0"

$Global:LogetoFolder = $env:ProgramData + "\Logeto\"
$Global:ScriptsFolderPath = $LogetoFolder +"Scripts\"
$Global:DownloadFolderPath = $LogetoFolder + "Download\"
$Global:LogsFolderPath = $LogetoFolder + "Logs\"

$Global:RegistryFolder = "HKCU:\Software\Systemart s.r.o."
$Global:RegistryFolderFallback = "HKLM:\Software\Systemart s.r.o."
$Global:RegistryName = 'UpdateScope'

$Global:HockeyAppPackageName = "Powershell.Installers"
$Global:HockeyAppAppId = "219bc502d1824dd695bbc00e796e3a92"

<#
    Return the version of an appx package
#>

Function Get-LogetoAppxVersion([String] $packageName)
{
    $packages = Get-AppxPackage | where Name -EQ $packageName

    if ($packages -ne $null)
    {
        return $packages.Version
    }

    return $DefaultVersion;
}

<#
    Return the version of exe file
#>

Function Get-LogetoExeVersion([String] $pathToExe)
{
    if ([String]::IsNullOrEmpty($pathToExe) -or !(Test-Path $pathToExe))
    {
        return $DefaultVersion
    }

    return (Get-Command $pathToExe).FileVersionInfo.FileVersion
}

<#
    Return path to the file of service
#>

Function Get-LogetoServicePath([String] $serviceName)
{
    $service = (Get-WmiObject win32_service | ?{$_.Name -eq $serviceName})
    if ($service)
    {
        return $service.PathName.Replace("`"","")
    }

    return $null
}

<#
    Create and return custom Logeto exception
#>

Function Get-LogetoCustomException($exceptionText, $i18n, $errorcode, $repeatable)
{
    $MyException = New-Object System.Exception -ArgumentList ($exceptionText);
    $MyException.Data.Add("i18n", $i18n)
    $MyException.Data.Add("errorcode", $errorcode)
    $MyException.Data.Add("repeatable", $repeatable)
    return $MyException
}

<#
    Return Logeto scope value from system registry
#>

function Get-LogetoScope
{
    if (Test-LogetoRegistryValue $RegistryFolder $RegistryName)
    {
        $scope = (Get-ItemProperty -Path $RegistryFolder -Name $RegistryName)."$RegistryName"
    }
    elseif (Test-LogetoRegistryValue $RegistryFolderFallback $RegistryName)
    {
        $scope = (Get-ItemProperty -Path $RegistryFolderFallback -Name $RegistryName)."$RegistryName"
    }

    return $scope
}

<#
    Test if registry key/name combination exists.
#>

Function Test-LogetoRegistryValue($regkey, $name)
{
    Get-ItemProperty $regkey $name -ErrorAction SilentlyContinue | Out-Null
    $?
}

<#
    Install any Logeto product
#>

function Get-LogetoProduct
{
        Param(
        [parameter(Mandatory=$true)]
        $UpdateInfo,

        [parameter(Mandatory=$true)]
        [ValidateSet('logeto-terminal', 'logeto-terminal-service')]
        $ProductName
    )

    $folder = $DownloadFolderPath + $ProductName

    try
    {       
        [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

        $packageUrl =  $UpdateInfo | Select -ExpandProperty PackageUrl

        $zipFile = [System.IO.Path]::GetTempFileName();       
        try
        {
            (New-Object System.Net.WebClient).DownloadFile($packageUrl, $zipFile)
            
            Write-LogetoDebug "Downloaded ZipFile $zipFile (Get-LogetoProduct)" 

            Invoke-LogetoExtract $zipFile $folder
        }
        finally
        {
            if (Test-Path $zipFile)
            {
                Remove-Item $zipFile -Force
            }
        }
    
        Write-LogetoDebug "Downloading finished." 
    }
    catch
    {
        throw CreateCustomException "Downloading the newest version failed with reason: $_.Exception.Message" "ScriptSystemartInstallerDownloadFailed" $resultExceptionThrown 1
    }
}

<#
    Extended Write-Host for installer purposes
#>

Function Write-LogetoProgress([String] $text, [String] $code)
{
    if (Get-Command -CommandType Function -Name "Write-InstallerProgress" -ErrorAction SilentlyContinue)
    {
       Write-InstallerProgress $text $code
    } 
    else
    {
       Write-Host $text
    }
}

<#
    Extended Write-Debug for installer purposes
#>

Function Write-LogetoDebug([String] $text)
{
    if (Get-Command -CommandType Function -Name "Write-InstallerDebug" -ErrorAction SilentlyContinue)
    {
       Write-InstallerDebug $text
    } 
    else
    {
       Write-Host $text
    }
}

<#
    Send error report to HockeyApp
#>

Function Send-LogetoReportToHockeyApp([String] $message, [System.Management.Automation.ErrorRecord] $errorRecord, [String] $description)
{
    Write-LogetoDebug $message
    Write-LogetoDebug $errorRecord
    
    $body = New-Object System.IO.MemoryStream

    $bodyWriter = New-Object System.IO.StreamWriter $body

    $boundary = [Guid]::NewGuid().ToString().Replace('-','')

    if (!([String]::IsNullOrEmpty($description)))
    {
        $bodyWriter.WriteLine("--$boundary")
        
        $bodyWriter.WriteLine('Content-Disposition: form-data; name="description"; filename="description.txt"')
        $bodyWriter.WriteLine('Content-Type:application/octet-stream')
        $bodyWriter.WriteLine('')

        $bodyWriter.WriteLine($description)
    }

    $bodyWriter.WriteLine("--$boundary")
    
    $bodyWriter.WriteLine('Content-Disposition: form-data; name="log"; filename="log.txt"' )
    $bodyWriter.WriteLine('Content-Type:application/octet-stream')
    $bodyWriter.WriteLine('')

    $bodyWriter.WriteLine("Package: $HockeyAppPackageName")
    $bodyWriter.WriteLine('Version: 1.0.0.0')
    $bodyWriter.WriteLine('OS: ' + (Get-WmiObject Win32_OperatingSystem).Version)
    $bodyWriter.WriteLine('Manufacturer: ' + (Get-WmiObject -Class Win32_ComputerSystem).Manufacturer)
    $bodyWriter.WriteLine('Model: '  + (Get-WmiObject -Class Win32_ComputerSystem).Model)
    $bodyWriter.WriteLine('Date: ' + (Get-Date -format o))
    $bodyWriter.WriteLine('CrashReporter Key: ' + (Get-WmiObject Win32_ComputerSystemProduct).UUID)
    $bodyWriter.WriteLine('')

    $bodyWriter.WriteLine($message)
    $bodyWriter.WriteLine('')


    if ($errorRecord)
    {
        $bodyWriter.WriteLine('Exception Stack:')
        
        if ($errorRecord.Exception)
        {
            $bodyWriter.WriteLine($ErrorRecord.Exception.ToString())
            # Make it show up as the first row on the HockeyApp page
            $bodyWriter.WriteLine("at $($ErrorRecord.Exception.ToString())()")
        }

        if ((Get-Member -InputObject $errorRecord -Name ScriptStackTrace) -ne $null)
        {
            $bodyWriter.WriteLine("`nScript Stack Trace:")
            $bodyWriter.WriteLine($errorRecord.ScriptStackTrace.ToString())
        }

        if ((Get-Member -InputObject $errorRecord -Name InvocationInfo) -ne $null)
        {
            if ((Get-Member -InputObject $errorRecord.InvocationInfo -Name PositionMessage) -ne $null)
            {
                $bodyWriter.WriteLine("`nInvocation Info Position Message:")
                $bodyWriter.WriteLine($errorRecord.InvocationInfo.PositionMessage.ToString())
            }
        }
    }
    $bodyWriter.WriteLine("--$boundary--")

    Write-LogetoDebug 'Sending report' 
    try
    {
        $uri = "https://rink.hockeyapp.net/api/2/apps/$HockeyAppAppId/crashes/upload"
        Invoke-RestMethod -ContentType "multipart/form-data; boundary=$boundary" -Uri $uri -TimeoutSec 120 -Method POST -Body $body.ToArray()
        Write-LogetoDebug 'Report sent' 
    }
    catch
    {
        Write-LogetoDebug 'Report not sent'
    }
}