Home > App-V, PowerShell Scripting > Automating Microsoft App-V Lightweight Streaming Services with Powershell.

Automating Microsoft App-V Lightweight Streaming Services with Powershell.

App-V Lightweight streaming services (LWS) is awesome. In particular, its a great utility for enterprises who wish to use App-V but don’t need the user management overhead that comes along with the full product.

For example, when using something brilliant like RES Workspace Manager, you can provision App-V applications, manage licensing requirements and restrict access to applications to pretty much any collection you wish. With utilities like this managing your workspaces the App-V database and management servers are just unnecessary add-ons.

With Lightweight streaming services, you get all the benefit of isolation, streaming and version control but without the additional infrastructure and management overhead. Simply host a network based application depot and point the lightweight streaming servers / clients to the share, Done.

But even with all these great benefits, the key difficulty with Lightweight streaming services is pre-caching the applications before a user needs them and keeping the application content up to date as new updates are added.

Having scripted mechanisms in Batch to perform this function and lost some hair in the process, I’m delighted to say PowerShell handles this job really well. Below find the powershell functions I’ve written to handle the four core tasks and the script I use to tie them all together. I run this script as a startup script after our XenApp servers scheduled restarts, this script will:

  • delete local packages that no longer exist on the content share.
  • Add new packages on the content share.
  • Perform a version check, deleting a local older copy if found.

Note: These scripts assume best practices of the applications being stored in \\servername\contentshare\appname\app files.
Add an appv package to the local machine:
Useage:  add-appvpackage -path “\\server\contentshare” -packagename “packagename”

function add-appvpackage{
    param(
        [string]$path,
        [string]$packagename)
       if (test-path $path\$packagename\$packagename`_manifest.xml){
            pushd $path
            start-process -wait sftmime.exe -argumentlist "add package:$packagename /manifest .\$packagename\$packagename`_manifest.xml /global"
            start-process -wait sftmime.exe  -argumentlist "load package:$packagename"
            popd
          }#end path if
       Else{
       write-warning "problem with path $path\$packagename\$packagename`_manifest.xml"}
}#end function

Remove an appv package to the local machine:
Useage: remove-appvpackage -packagename “packagename”


function remove-appvpackage{
    param(
        [string]$packagename)
    start-process -wait sftmime.exe -argumentlist "delete package:$packagename /global"
}

Retrieve a list of appv packages on the local machine:
Useage: get-appvlocalpackages

function get-appvlocalPackages{
    $localpackageswmi = get-wmiobject -class Package -namespace root\microsoft\appvirt\client
    foreach ($package in $localpackageswmi) {
        $packagedetails = New-Object PSObject -Property @{
                Name=$package.Name
                Version=$package.version
                VersionGuid="`{$($package.versionguid)`}"
            }#end object
        $packages+=@($packagedetails)
    }#end for
    return $packages
}#end function

Retrieve a list of appv packages on the content share:
Useage: get-appvremotepackages

function get-appvremotepackages{
    param(
        [string]$remotedir="\\computername\contentshare")

    foreach ($package in get-childitem $remotedir){
        [xml]$manifest = get-content $remotedir\$package\${package}_manifest.xml
        $packagedetails = New-Object PSObject -Property @{
            Name=$manifest.package.Name
            Version=$manifest.package.version
            VersionGuid=$manifest.package.versionguid
        }#end object
        $packages+=@($packagedetails)
    }#end for
    Return $packages
}#End Function

Gluing it all together into a maintenance script:

#getting package arrays
$locallist=get-appvlocalpackages | sort name
$remotelist=get-appvremotepackages | sort name

#sort the differences to highlight deletes first.
foreach ($difference in COMPARE-OBJECT -referenceobject $locallist -differenceobject $remotelist -property name,version | sort sideindicator){
    if ($difference.sideindicator -eq "<="){
        if ($difference.name -ne $null){
            write-host "removing $($difference.name)"
            remove-appvpackage -packagename $difference.name}
    }#end if
    Else {
        if ($difference.name -ne $null){
            "adding $($difference.name)"
             add-appvpackage -path $remotedir -packagename $difference.name}   
        }#end else
}#end for

To grab a copy of the whole script, follow the jump below:

###############################################################################
##     Performing App-V Maintenance.
###############################################################################

$remotedir = "\\servername\ContentShare"

function add-appvpackage{
    param(
        [string]$path,
        [string]$packagename)
       if (test-path $path\$packagename\$packagename`_manifest.xml){
            pushd $path
            start-process -wait sftmime.exe -argumentlist "add package:$packagename /manifest .\$packagename\$packagename`_manifest.xml /global"
            start-process -wait sftmime.exe  -argumentlist "load package:$packagename"
            popd
          }#end path if
       Else{
       write-warning "problem with path $path\$packagename\$packagename`_manifest.xml"}
}#end function

function get-appvlocalPackages{
    $localpackageswmi = get-wmiobject -class Package -namespace root\microsoft\appvirt\client
    foreach ($package in $localpackageswmi) {
        $packagedetails = New-Object PSObject -Property @{
                Name=$package.Name
                Version=$package.version
                VersionGuid="`{$($package.versionguid)`}"
            }#end object
        $packages+=@($packagedetails)
    }#end for
    return $packages
}#end function

function get-appvremotepackages{
    param(
        [string]$remotedir="\\Servername\contentshare")

    foreach ($package in get-childitem $remotedir){
        [xml]$manifest = get-content $remotedir\$package\${package}_manifest.xml
        $packagedetails = New-Object PSObject -Property @{
            Name=$manifest.package.Name
            Version=$manifest.package.version
            VersionGuid=$manifest.package.versionguid
        }#end object
        $packages+=@($packagedetails)
    }#end for
    Return $packages
}#End Function

function remove-appvpackage{
    param(
        [string]$packagename)
    start-process -wait sftmime.exe -argumentlist "delete package:$packagename /global"
}

#getting  package arrays
$locallist=get-appvlocalpackages | sort name
$remotelist=get-appvremotepackages | sort name

#sort the differences to highlight deletes first.
foreach ($difference in COMPARE-OBJECT -referenceobject $locallist -differenceobject $remotelist -property name,version | sort sideindicator){
    if ($difference.sideindicator -eq "<="){
        if ($difference.name -ne $null){
            "removing $($difference.name)"
            remove-appvpackage -packagename $difference.name}
    }#end if
    Else {
        if ($difference.name -ne $null){
            "adding $($difference.name)"
             add-appvpackage -path $remotedir -packagename $difference.name}   
        }#end else
}#end for
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: