App-V Auto Sequencing Part 4 - Automate the sequencing process further

Now we are able to use the sequencer using PowerShell cmdlets, we can take this a step further and automate more of the process

I was visiting a company a while ago, and the person responsible for creating and maintaining the App-V packages had automated updating their Google chrome and Mozilla Firefox App-V packages. I've added the Auto Sequencer to the mix, and that leads to the following example.

 

For this example, I am going to use Visual Studio Code.

Visual Studio Code updates on a very frequent basis, so being able to automate this process will bring your end-users the latest version with in a fully automated matter, illustrated below

I've started off with creating a folder for this little project. In the folder that I created in an earlier post, see <link>, I've created a folder called Visual Studio Code,

and I've copied the example xml file discussed in the same post into it.

 

To make keeping track of versioning, I've created a txt file named CurrentVersion.txt to write the latest version to.

To make the PowerShell script that we're going to create work, add the current version of the package that you are upgrading to the file.

Next to this, I've created an empty PowerShell ps1 file called AutoSEQ-VSC.ps1

So when we look at the new folder created, we should see

The next step will be modifying the upgrade xml.

The PowerShell script will dynamically populate some fields. The content of the xml after modifying is shown below

 <?xml version="1.0"?>
<Applications>
    <!-- For sequencing a package -->
        <Application>
            <AppName>[AppName]</AppName>
            <InstallerFolder>[InstallerFolder]</InstallerFolder>
        <Installer>VisualStudioCode.exe</Installer>
           <InstallerOptions>/VERYSILENT /MERGETASKS=!runcode</InstallerOptions>
            <Package>[Package]</Package>
            <Cmdlet>true</Cmdlet>
            <Enabled>true</Enabled>
        </Application>
</Applications>

Next, we need to modify the PowerShell script. See the example below.

 <#
.SYNOPSIS
    This Script will automatically download, prepare and sequence VisualStudioCode App-V packages. This Script requires:
        - Hyper-V role installed
        - Windows 10 SDK installed
        - App-V Autosequencer installed
        - administrative account
        - prepared SequencingVM

.DESCRIPTION

.EXAMPLE
    C:\PS> SequenceVSCode.ps1

.NOTES
    Author: Ingmar Oosterhoff & Johannes Freundorfer, Microsoft PFE
    .DISCLAIMER
    The sample scripts are not supported under any Microsoft standard support program or service.
    The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims
    all implied warranties including, without limitation, any implied warranties of merchantability
    or of fitness for a particular purpose. The entire risk arising out of the use or performance of
    the sample scripts and documentation remains with you. In no event shall Microsoft, its authors,
    or anyone else involved in the creation, production, or delivery of the scripts be liable for any
    damages whatsoever (including, without limitation, damages for loss of business profits, business
    interruption, loss of business information, or other pecuniary loss) arising out of the use of or
    inability to use the sample scripts or documentation, even if Microsoft has been advised of the
    possibility of such damages.
#>

begin {
    function Get-ScriptDirectory() {
        New-Variable -Name Invocation -Value $(Get-Variable MyInvocation -Scope 1 -ErrorAction SilentlyContinue).Value -Scope Script -Force
        if (Test-path $Invocation.PSScriptRoot -ErrorAction SilentlyContinue) {
            return $Invocation.PSScriptRoot
        }
        Elseif (Test-path $Invocation.MyCommand.Path -ErrorAction SilentlyContinue) {
            return Split-Path $Invocation.MyCommand.Path
        }
        else {
            return get-location
        }
        Remove-Variable -Name Invocation -Force
    }
    Set-StrictMode -Version 2  
    New-Variable -Name VisualStudioCodeVersion -Value $null -Description "Variable containing the Version of Visual Studio to be packaged"
    New-Variable -Name Scriptfolder -Value $(Get-ScriptDirectory) -Description "Variable containing the Script"
    New-Variable -Name Product -Value $(Split-Path $Scriptfolder -Leaf) -Description "Variable containing the Product-Name"
    New-Variable -Name DownloadLink  -Value "https://code.visualstudio.com/updates" -Description "Specify the location to get the update from"
    New-Variable -Name InstallersFolder -Value "C:\Repository\Projects\Auto-Sequencing\10-Installers" -Description "Specify the location where all installers are kept"
    New-Variable -Name href -Description "Variable that holds the Download-Website."
    New-Variable -Name PackageDir -Description "Variable containing the Target folder for the package"
    New-Variable -Name OutputPath -value "C:\Repository\Projects\Auto-Sequencing\20-Packaged" -Description "Destination directory for the resulting App-V Package"
    New-Variable -Name CurrentVer -Description "Contains the current Version of Visual Studio Code"
    New-Variable -Name latestPkg -Description "Contains the latest Version of the App-V Package"
    New-Variable -Name upgradeXml -Value [string]"" -Description "Contains the XML-Data to sucessfully create a package update"

    # Get the current version available online
    new-Variable -name htmlContent -Value $(Invoke-webRequest -uri $DownloadLink ) -Description "Downloading the current VSCode-Website" -Force
    $href = ($htmlContent.Links | Where-Object {$_.innerhtml -like "*Windows*"} | Select-Object href | Format-Table -HideTableHeaders | Out-String).Trim()

    New-Variable VisualStudioCodeVersion -value $($href.Split("\")[3]) -Description "Holds the current VSCode Version" -Force
    $PackageDir = "$InstallersFolder\$Product\$VisualStudioCodeVersion"

    # Verify if we haven't done this one earlier

    if (!(test-path -path "$PackageDir")) {
        Write-Information -MessageData "New version available: $VisualStudioCodeVersion. Starting package creation..."
    }
    else {
        Write-Warning -Message "Package was created earlier. Exiting with exit code: 1"
        exit 1
    }
}
# we're still here, so it must be a newer version
process {
    Write-Information -MessageData "Preparing the Target directory and downloading the sources"
    New-Item -Path $PackageDir -ItemType Directory | Out-Null
    try {
        Invoke-WebRequest -Uri $href -OutFile $(Join-Path $PackageDir -ChildPath "VisualStudioCode.exe") | Unblock-File
    }
    Catch {
        Write-Error -Message "Downloading sources failed. Exiting with exit code: 2"
        exit 2
    }
    Write-Information -MessageData "Preparing App-V Update metadata"
    $CurrentVer = Get-Content -path "$Scriptfolder\currentversion.txt"
    $latestPkg = "$OutputPath\$product $CurrentVer\$product $CurrentVer.appv"
    $upgradeXml = Get-Content -path $Scriptfolder\template\upgrade.xml | Out-String
    $upgradeXml = $upgradeXml.Replace("[InstallerFolder]", "$PackageDir")
    $upgradeXml = $upgradeXml.Replace("[AppName]", "$Product $VisualStudioCodeVersion")
    $upgradeXml = $upgradeXml.Replace("[Package]", "$latestPkg")
    $upgradeXml | out-File $Scriptfolder\upgrade.xml -Encoding Ascii -Force
    try {
        New-BatchAppVSequencerPackages -ConfigFile "$Scriptfolder\upgrade.xml" -VMName autoSEQ -OutputPath "$OutputPath"
        $VisualStudioCodeVersion | out-file "$Scriptfolder\currentversion.txt"
    }
    catch {
        Write-Error -Message "Package creation failed. Exiting with exit code: 3"
    }
}

end {
    Remove-Variable -Name VisualStudioCodeVersion -Force
    Remove-Variable -Name Scriptfolder -Force
    Remove-Variable -Name Product -Force
    Remove-Variable -Name DownloadLink -Force
    Remove-Variable -Name InstallersFolder -Force
    Remove-Variable -Name href -Force
    Remove-Variable -Name PackageDir -Force
    Remove-Variable -Name OutputPath -Force
    Remove-Variable -Name CurrentVer -Force
    Remove-Variable -Name latestPkg -Force
    Remove-Variable -Name upgradeXml -Force
    exit 0
}

Save the PowerShell file, and there's just one more thing we have to make sure of.

This script is for upgrading a package, so it expects an appv package in the correct location.

As I've specified 1.24.1 in the CurrentVer.txt,  I've got a package called "Visual Studio Code 1.24.1.appv" in "c:\AutoSequencer\Packages\Visual Studio Code 1.24.1"

We're good to go!

We can now execute the script manually, or even nicer, create a scheduled talk!

Ingmar Oosterhoff and Johannes Freundorfer