App-V 5 Configuration Editor (ACE) v1.4 Released!

ACE-256px_thumb.pngVirtual Engine are pleased to announce the version 1.4 release of the App-V 5 Configuration Editor (ACE). This (free) utility provides a simple user interface for editing App-V 5 dynamic configuration and manifest files, without manually hacking the underlying XML files.

This release requires Microsoft .NET Framework 4.5 or above and contains several reported bug fixes along with:

  • Support for App-V 5.1 (See excellent blog post by @ThamimKarim for a run down of what’s new in App-V 5.1);
  • Ability to modify AppxManifest files to support the App-V 5.1 sequencer Export/Import feature;
  • New Applications tab has been added, where you can Enable or Disable applications when published;
  • Improved Error checking for missing data;
  • New setting added to the User and Machine scripts that enables scripts to Run Asynchronously;
  • Tool tips added to explain what various settings or options will do;
  • New options added to the Shortcuts Context Menu that make it even easier to add new shortcuts;
  • Ability to pop-out the Generated XML and Source XML into a separate viewable window;
  • Comments have been added in the Generated XML file to make it easier to read each section;
  • Drag and Drop support has been added to open the dynamic configuration files;
  • Ability to save the Generated XML for use in App-V Scheduler.

App-V 5 Sequencer Template – Full VFS Write Mode

With the recent release of Hotfix 4 for App-V 5.0, Microsoft has now provided the ability to “Allow virtual applications full write permissions to the virtual file system”. This setting can be found in the sequencer under the “Advanced” tab as demonstrated in the screen shot below:

 Sequncer Full VFS

Should you wish to enable this setting as a default whenever you create a new package, then simply go ahead and add <FullVFSWriteMode>true<FullVFSWriteMode> into your sequencer template (.appvt), as you can see below. This setting is only valid where you have the App-V 5.0 SP2 Hotfix 4 sequencer installed.

<?xml version="1.0" encoding="utf-8"?>
<SequencerTemplate xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <AllowMU>false</AllowMU>
  <AppendPackageVersionToFilename>false</AppendPackageVersionToFilename>
  <AllowLocalInteractionToCom>false</AllowLocalInteractionToCom>
  <AllowLocalInteractionToObject>false</AllowLocalInteractionToObject>
  <FullVFSWriteMode>true</FullVFSWriteMode>
  <ExcludePreExistingSxSAndVC>false</ExcludePreExistingSxSAndVC>
  <FileExclusions>
    <string>[{CryptoKeys}]</string>
    <string>[{Common AppData}]\Microsoft\Crypto</string>
    <string>[{Common AppData}]\Microsoft\Search\Data</string>
    <string>[{Cookies}]</string>
    <string>[{History}]</string>
    <string>[{Cache}]</string>
    <string>[{Local AppData}]</string>
    <string>[{Personal}]</string>
    <string>[{Profile}]\Local Settings</string>
    <string>[{Profile}]\NTUSER.DAT.LOG1</string>
    <string>[{Profile}]\NTUSER.DAT.LOG2</string>
    <string>[{Recent}]</string>
    <string>[{Windows}]\Debug</string>
    <string>[{Windows}]\Logs\CBS</string>
    <string>[{Windows}]\Temp</string>
    <string>[{Windows}]\WinSxS\ManifestCache</string>
    <string>[{Windows}]\WindowsUpdate.log</string>
    <string>[{AppVPackageDrive}]\$Recycle.Bin</string>
    <string>[{AppVPackageDrive}]\System Volume Information</string>
    <string>[{AppData}]\Microsoft\AppV</string>
    <string>[{Local AppData}]\Temp</string>
    <string>[{ProgramFilesX64}]\Microsoft Application Virtualization\Sequencer</string>
  </FileExclusions>
  <RegExclusions>
    <string>REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Microsoft\Cryptography</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Explorer\StreamMRU</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\StreamMRU</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\Streams</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Microsoft\AppV</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft\AppV</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\AppV</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\AppV</string>
  </RegExclusions>
  <TargetOSes />
</SequencerTemplate>

And if you’re not currently using a template then I’d highly recommend you do. You’ll find a great article over at Rory Monaghan’s blog that explains the use of the sequencer template in more detail.

Nathan

App-V 5 Configuration Editor User Guide

ACEWe’ve been working hard getting the App-V 5 Configuration Editor (ACE) ready for official release; take a look at the ACE page for a bit more information about why it was developed.

The purpose of this short blog to guide you through the ACE interface. There is an assumption here you have an understanding of the App-V 5 Dynamic Configuration files and how they are used, if not you might want to take a look at this Technet article.

USER INTERFACE

Main Toolbar:

You will notice there are three main buttons in the tool bar as shown below:

Main Toolbar

image Opens an App-V XML file, i.e. a UserConfig.xml or DeploymentConfig.xml file. Once the file has been opened the contents will be parsed and displayed under the various tabs within the GUI.

image Saves the current App-V XML file, including any changes that have been made. You can give it a new name and Save As a different file, keeping your original one as is if necessary.

image Previews the changes that will be made to the App-V XML file before saving. This gives you the ability to check out the structure of the generated XML. It’s probably a good idea to point out here that you don’t need to preview the changes prior to performing a save.

Package Details:

This sections displays the Package Display Name, Package ID and Type of XML file opened, i.e. DeploymentConfig or UserConfig. Here is an example DeploymentConfig.xml opened below:

Package Details

MAIN CONFIGURATION TABS

Once an App-V 5 configuration XML file has been opened you can then begin to make changes as required using the tabs set out below.

User Configuration

Under the User Configuration tab you can change and view various options and configurations:

User Configuration

Options

Various global options change be changed here if you so desire, e.g. altering the COM integration mode.

Shortcuts

This tab allows you to View, Add, Edit or Delete any Shortcuts within the package.

If you want to delete an existing shortcut, simply select the row that contains the shortcut and press delete. Should you wish to add a new shortcut, I’d suggest you copy and paste an existing row and then edit the fields accordingly; we’ve added a context menu to make that task easy, should you not fancy using Ctrl+C and Ctrl+V  Smile.

Shortcuts

Scripts (User Context)

This is really where ACE starts to make life simple Smile. You can easily define which scripts you’d like to add and to which script actions, e.g. PublishPackage, UnpublishPackage, StartVirtualEnvironment, TerminateVirtualEnvironment, StartProcess and ExitProcess. There is no need to worry about getting the syntax in the XML file right. There are some excellent blogs out there talking about using scripts in App-V 5.0, so I suggest you take a look here at one from Tim Mangan and Microsoft’s own Steve Thompson if you need some further background information.

NOTE: You might have noticed that not all the script actions are available under this tab, that’s simply because those excluded aren’t permitted to run under the User Configuration section of the XML file.

I think most of the options are self explanatory but, it’s good to point out that leaving the Timeout value at 0 means no timeout period will be set, i.e. it will wait indefinitely for it to finish so use with caution.

Scripts (User Context)

Machine Configuration

Under the Machine Configuration tab you can alter global options, configure scripts and control the termination of processes.

NOTE: this tab will only be available when you open a DeploymentConfig.xml file. This is because machine configuration items cannot be set in the UserConfig.xml file.

Machine Configuration

Options

Here you’ll find any options that can be changed if you so desire.

Terminate Child Processes

You can define the path to an executable, that when closed, will terminate any child process running within the virtual environment.

Terminate Child Processes

Scripts (System Context)

Very much like the Scripts tab under User Configuration you can define which scripts you’d like to add to which machine script actions, e.g. AddPackage, RemovePackage, PublishPackage and UnpublishPackage.

NOTE: You might have noticed that not all the script actions are available under this tab, that’s simply because those excluded aren’t permitted to run under the Machine Configuration section of the XML file.

Scripts (System Context)

XML

You can view both the source (original) XML and/or preview the generated XML under this tab.

Source XML

Source XML

This is simply where you can view your source App-V XML file as it was when you opened it.

Generated XML

Once you click the Preview button image this pane will display any changes that will be made to the App-V XML file, giving you the ability to check out the structure of the XML before saving if you wish. NOTE: You don’t have to preview the changes prior to performing a save.

The example below (highlighted in yellow) shows the changes made by ACE in the generated XML format. NOTE: ACE will not highlight the changes in the XML, we’ve done it here for clarity purposes only.

Generated XML

With any luck this brief guide has given you a good overview of how to use ACE and hopefully you’ll agree its pretty intuitive to use and should make editing the App-V 5 Dynamic Configuration files a lot, lot easier (well we think so anyway!)? 🙂

DISCLAIMER: THE APP-V CONFIGURATION EDITOR IS FREE TO USE AT YOUR OWN RISK, WE CANNOT BE HELD RESPONSIBLE FOR ANY DAMAGE IT MIGHT CAUSE.

Querying .APPV Package Properties Part 2

powershell_appv_logoFollowing on from Part 1, we can also query the properties of an App-V 5.0 .APPV package with another cmdlet included in the Virtual Engine App-V 5.0 .APPV PowerShell CmdLets; Get-AppV5FilePackage.  The main difference with this cmdlet (when compared to Get-AppV5FileXml and Get-AppV5FileXmlPackage) is that it returns a custom PSObject with a simpler property namespace and additional package information.

To populate our object we can run this:

[code]C:\PS> $AppVPackage = Get-AppV5FilePackage –AppV C:\Mozilla_Firefox_v17.0.appv[/code]

Going back to our example in Part 1, we can then query this object for both the VersionId and PVAD like so:

[code]C:\PS> $AppVPackage | Select-Object VersionId,FileSystemRoot | Format-List

VersionId      : fd215f39-f317-447d-aa79-7fe6c35e73f6
FileSystemRoot : C:\Program Files\Mozilla Firefox[/code]

Our custom PSObject also includes details of all the files in package and the uncompressed size. If you want to know how much space a package will take when loaded into the App-V 5 client cache, then this is the command for you!

To return the uncompressed package size we could run:

[code]$AppVPackage.UncompressedSize
43738570[/code]

If you want this in MB, easy:

[code]C:\PS> ($AppVPackage.UncompressedSize/1MB).ToString(“N2”)
41.71[/code]

Want the total number of files in the package?

[code]C:\PS> $AppVPackage.Files.Count
85[/code]

Need a list of all the files in the .APPV package?

[code]C:\PS> $AppVPackage.Files | Select-Object FullName

FullName
——–
Registry.dat
Root/components/binary.manifest
Root/components/browsercomps.dll
Root/defaults/pref/channel-prefs.js
Root/defaults/pref/local-settings.js
Root/dictionaries/en-US.aff
Root/dictionaries/en-US.dic
Root/extensions/%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D/icon.png
Root/extensions/%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D/install.rdf
Root/modules/services-aitc/.mkdir.done
Root/modules/services-common/.mkdir.done
Root/modules/services-crypto/.mkdir.done
Root/modules/services-notifications/.mkdir.done
Root/modules/services-sync/.mkdir.done
Root/modules/services-sync/engines/.mkdir.done
Root/modules/sessionstore/.mkdir.done
Root/searchplugins/amazondotcom.xml
Root/searchplugins/bing.xml
Root/searchplugins/eBay.xml
Root/searchplugins/google.xml
Root/searchplugins/twitter.xml
Root/searchplugins/wikipedia.xml
Root/searchplugins/yahoo.xml
Root/webapprt/omni.ja
Root/webapprt/webapprt.ini
Root/override.ini
Root/mozilla.cfg
Root/install.log
Root/AccessibleMarshal.dll
Root/application.ini
Root/blocklist.xml
Root/breakpadinjector.dll
Root/chrome.manifest
Root/crashreporter-override.ini
Root/crashreporter.exe
Root/crashreporter.ini
Root/D3DCompiler_43.dll
Root/d3dx9_43.dll
Root/dependentlibs.list
Root/firefox.exe
Root/freebl3.chk
Root/freebl3.dll
Root/gkmedias.dll
Root/libEGL.dll
Root/libGLESv2.dll
Root/maintenanceservice.exe
Root/maintenanceservice_installer.exe
Root/mozalloc.dll
Root/mozglue.dll
Root/mozjs.dll
Root/mozsqlite3.dll
Root/msvcp100.dll
Root/msvcr100.dll
Root/nspr4.dll
Root/nss3.dll
Root/nssckbi.dll
Root/nssdbm3.chk
Root/nssdbm3.dll
Root/nssutil3.dll
Root/omni.ja
Root/platform.ini
Root/plc4.dll
Root/plds4.dll
Root/plugin-container.exe
Root/precomplete
Root/removed-files
Root/smime3.dll
Root/softokn3.chk
Root/softokn3.dll
Root/ssl3.dll
Root/update-settings.ini
Root/updater.exe
Root/updater.ini
Root/webapp-uninstaller.exe
Root/webapprt-stub.exe
Root/xpcom.dll
Root/xul.dll
Root/firefox.exe.0.ico
Root/firefox.exe.1.ico
FilesystemMetadata.xml
StreamMap.xml
PackageHistory.xml
AppxManifest.xml
AppxBlockMap.xml
[Content_Types].xml[/code]

Hopefully, these cmdlets will be useful? As an example, we’ve used the Get-AppV5FilePackage cmdlet to create HTML .APPV package reports. Happy PoShing Open-mouthed smile

Querying .APPV Package Properties Part 1

powershell_appv_logoSo you have an App-V 5.0 package (in this example I’ll use Mozilla Firefox) and you’d like to know various properties about the package without loading it into the App-V 5 client. The sequencer creates numerous files by default that expose some extremely pertinent information, i.e. the PackageId. The PackageId is specified in both the template <PackageName>_DeploymentConfig.xml and <PackageName>_UserConfig.xml files.

Unfortunately for us, other useful details such as the VersionId and Primary Virtual Asset Directory (PVAD) are stored within the <PackageName>.appv file. This is a compressed archive and can simply be opened with Windows Explorer by renaming the file with a .ZIP extension. Within this file are some more files (generated by the Sequencer):

image

If we want to find out information such as the VersionId or Primary Virtual Asset Directory (PVAD directory) without loading the package into the App-V 5.0 client, we have to manually rename the file, open the archive and inspect the various files (AppxManifest.xml for the VersionId and FileSystemMetadata.xml for the PVAD). Whilst this is fine, it is manual and if we forget to rename the file back to a .APPV file we leave the package unusable!

Using PowerShell

This is what the Virtual Engine App-V 5.0 Package PowerShell CmdLets are for! Included are three CmdLets that can help us here: Get-AppV5FileXmlGet-AppV5FileXmlPackage and/or Get-AppV5FilePackage. This post covers the first two and Part 2 of this post covers the Get-AppV5FilePackage command.

Get-AppV5FileXml

This cmdlet will extract the contents of a single XML file within an .APPV package. The results are returned as a System.Xml.XmlDocument that we can then interrogate. No more manually renaming the archive, extracting and then loading the file.

Going back to our example, if we wanted the VersionId of an .APPV package we need to interrogate the AppxManifest.xml file. To accomplish this we can run this command (all on a single line!):

[code]C:\PS> (Get-AppV5FileXml –AppV C:\Mozilla_Firefox_v17.0.appv –XML AppxManifest).Package.Identity.VersionId

fd215f39-f317-447d-aa79-7fe6c35e73f6

C:\PS>[/code]

If we want the PVAD directory, this is stored in the FileSystemMetadata.xml file. Easy (again, all on a single line!):

[code](Get-AppV5FileXml –AppV C:\Mozilla_Firefox_v17.0.appv –XML FilesystemMetadata).Metadata.FileSystem.Root

C:\Program Files\Mozilla Firefox

C:\PS>[/code]

This method loads each file into it’s own XmlDocument. Is there a way to load all the XML properties at once? You betcha!

Get-AppV5FileXmlPackage

This command bundles all the default sequencer generated XML files into a single XmlDocument object. This includes the contents of the AppxManifest.xml, StreamMap.xml, AppxBloackMap.xml, PackageHistory.xml and FileSystemMetadata.xml files. Each XML file is loaded under the <AppV5> element within the XML document and therefore, the paths are extended slightly.

Taking our example, if want to get the VersionId and PVAD we can do this instead:

[code]C:\PS> $Mozilla = Get-AppV5FileXmlPackage –AppV C:\Mozilla_Firefox_v17.0.appv

C:\PS> $Mozilla.AppV5.Package.Identity.VersionId
fd215f39-f317-447d-aa79-7fe6c35e73f6

C:\PS> $Mozilla.AppV5.Metadata.FileSystem.Root
C:\Program Files\Mozilla Firefox

C:\PS>[/code]

In Part 2, we can use yet another method: Get-AppV5FilePackage. Happy PowerShelling Open-mouthed smile

Documenting App-V 5.0 Packages

Continuing our series of posts on the Virtual Engine App-V 5.0 .APPV PowerShell CmdLets, this one will show you how to quickly document your .APPV packages’ contents. The Save-AppV5FileReport cmdlet generates a HTML report of information contained within the .APPV package contents. Here’s an example summary report (detailed reports are also available):

Generating Single Reports

Generating summary reports (such as the one above) simply requires running the following command:

[code]C:\PS> Save-AppV5FileReport –AppV C:\Mozilla_Firefox_v17.0\Mozilla_Firefox_v17.0.appv[/code]

This will generate a Mozilla_Firefox_V17.0_Report.html file in the source C:\Mozilla_Firefox_v17.0\ directory. If we wanted a detailed report instead we could run:

[code]C:\PS> Save-AppV5FileReport –AppV C:\Mozilla_Firefox_v17.0\Mozilla_Firefox_v17.0.appv –Detailed[/code]

Documenting Multiple Packages

Creating a report for a single package is fine, but what if we wanted to document all packages on a share or in a folder? Fortunately this is simple. If you wanted each package report in the source package directory, we can do so like this:

[code]C:\PS> Get-ChildItem C:\Packages\ -Include *.appv -Recurse | % { Save-AppV5FileReport -AppV $_.FullName }

Directory: C:\Packages\GoogleChrome_v23.0.1271.91

Mode                LastWriteTime     Length Name
—-                ————-     —— —-
-a—        02/05/2013     12:36       8884 GoogleChrome_v23.0.1271.91_Report.html

Directory: C:\Packages\Mozilla_Firefox_v17.0

Mode                LastWriteTime     Length Name
—-                ————-     —— —-
-a—        02/05/2013     12:36       8802 Mozilla_Firefox_v17.0_Report.html

Directory: C:\Packages\Paint.Net_v3.5.10

Mode                LastWriteTime     Length Name
—-                ————-     —— —-
-a—        02/05/2013     12:36       8770 Paint.NET_v3.5.10_Report.html[/code]

What about if we wanted all the reports in a single location? Again, pretty straight forward. The Save-AppV5FileReport cmdlet has a –FilePath parameter that we can specify the output location. Note: this folder is not automatically created so make sure it exists! Our command to achieve this is:

[code]C:\PS> Get-ChildItem C:\Packages\ -Include *.appv -Recurse | % { Save-AppV5FileReport -AppV $_.FullName -FilePath C:\Packages\Reports\ }

Directory: C:\Packages\Reports

Mode                LastWriteTime     Length Name
—-                ————-     —— —-
-a—        02/05/2013     12:40       8884 GoogleChrome_v23.0.1271.91_Report.html
-a—        02/05/2013     12:40       8802 Mozilla_Firefox_v17.0_Report.html
-a—        02/05/2013     12:40       8770 Paint.NET_v3.5.10_Report.html[/code]

Hopefully you’ll find these HTML reports useful. We are planning to add sequencer reports into this module in the near future too, so stay tuned! Happy PoShing 😀

Installing the new App-V 5 PowerShell Modules

Following on from the release of the Virtual Engine App-V 5.0 PowerShell CmdLets, I thought I best give you a quick run through on setting them up! Installing the PowerShell modules is easy, regardless of whether you’re installing them just for your user account or on a per machine basis. Note: we will package these up into a .MSI once we’ve had some initial feedback and fixed any “features!”

Per User Installation

To install the new modules on a per-user basis, extract the files into your ‘Documents\WindowsPowerShell\Modules\’ directory:

image

Per Computer Installation

To install the new modules on a per-computer basis, extract the files into the ‘C:\Windows\System32\WindowsPowerShell\v1.0\Modules\’ (or %PSModulePath% for short!) directory:

image

Importing

To import and use the modules, simply run the following PowerShell command (they are digitally signed):

[code]Import-Module VirtualEngine-AppV5[/code]

You may be prompted to confirm that you trust the publisher  (!?). The modules are digitally signed. If you want to use them, then you better ensure that you select the ‘Always Run’ (or at lease ‘Run Once’) option!

PowerShell_Trusted_Publisher

Once they’re loaded you can check by running the following PowerShell command. If you see something similar to this then you should be all set:

[code]PS C:\Windows\system32> Get-Command -Module VirtualEngine*

CommandType     Name                                      ModuleName
———–     —-                                      ———-
Function        Get-AppV5File                             VirtualEngine-AppV5
Function        Get-AppV5FilePackage                      VirtualEngine-AppV5
Function        Get-AppV5FileReport                       VirtualEngine-AppV5
Function        Get-AppV5FileXml                          VirtualEngine-AppV5
Function        Get-AppV5FileXmlPackage                   VirtualEngine-AppV5
Function        Get-VEAppV5Version                        VirtualEngine-AppV5
Function        Save-AppV5File                            VirtualEngine-AppV5
Function        Save-AppV5FileReport                      VirtualEngine-AppV5
Function        Save-AppV5FileXml                         VirtualEngine-AppV5
Function        Save-AppV5FileXmlPackage                  VirtualEngine-AppV5

PS C:\Windows\system32> [/code]

Note: The modules require PowerShell 3.0 and the Microsoft .Net Framework 4.5. These are installed by default on Windows 8 and Windows Server 2012. If you’re running Windows 7 without these requirements, then you’ll receive errors. Make sure you meet these requirements.

Extracting files from an .APPV file with PowerShell

Whilst doing a lot of work with App-V 5.0 we have come across the requirement to look inside the .appv file with PowerShell. In our particular instance we’re after the package VersionId which is contained in the AppxManifest.xml file. As previously championed, we love automating and this should be easy!

The .appv file extension is a compressed archive and therefore, should be simple to crack open. After scouring the interweb, there is very little information on how to achieve this in code. We could use the built-in Shell32.dll functionality but this requires us to rename the file to .zip first. Ideally we want to avoid copying or renaming the source files. I did find one reference over on the Login Consultants forum which pointed me in the right direction.

Disclaimer: the following code requires the .Net Framework 4.5. The System.IO.Compression.FileSystem object is not available in previous releases. You can check in the C:\Windows\Microsoft.NET\assembly\GAC_MSIL\ folder and if you have the System.IO.Compression.FileSystem folder you should be good to go Smile with tongue out.

To get this new .Net functionality to work within PowerShell we will be calling the .Net assemblies directly and therefore need to create a couple of references. In our example we’ll be using both the System.IO.Compression and System.IO.Compression.FileSystem assemblies (two different DLLs hence the two references):

[code]### The System.IO.Compression.FileSystem requires at least .Net Framework 4.5
[System.Reflection.Assembly]::LoadWithPartialName(“System.IO.Compression”) | Out-Null;
[System.Reflection.Assembly]::LoadWithPartialName(“System.IO.Compression.FileSystem”) | Out-Null;[/code]

Next we can create our FileStream object (with read only access) required by the ZipArchive object class.

[code]### Open the ZipArchive with read access
$FileStream = New-Object System.IO.FileStream($SourceAppV5Archive, [System.IO.FileMode]::Open);
$AppV5Archive = New-Object System.IO.Compression.ZipArchive($FileStream);[/code]

In fact we can shorten this down to a single line:

[code]### Open the ZipArchive with read access
$AppV5Archive = New-Object System.IO.Compression.ZipArchive(New-Object System.IO.FileStream($SourceAppV, [System.IO.FileMode]::Open));[/code]

Once we have opened our .ZIP (.appv) file we can retrieve the AppXManifest.xml file entry:

[code]### Locate the AppxManifest.xml file
$AppxManifestEntry = $AppV5Archive.GetEntry(“AppxManifest.xml”);[/code]

Having the ZipArchiveEntry object we can extract it with the ExtractToFile method:

[code]### Extract the $ZipArchiveEntry
$ZipArchiveEntry.ExtractToFile($SaveAs);[/code]

Unfortunately this does work and reports the following error:

[code]Method invocation failed because [System.IO.Compression.ZipArchiveEntry] doesn’t contain a method named ‘ExtractToFile’.[/code]

Eh!? WT… Looking on the ZipArchiveEntry reference page on MSDN, the ExtractToFile is an Extension Method. Therefore, we need to utilise the underlying object method, the ZipFileExtensions.ExtractToFile method. For more information on Extension Methods in PowerShell see here and here. Now our code should look like this:

[code]### Extract the ZipArchiveEntry (ZipArchiveEntry.ExtractToFile is an extension method)
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($AppxManifestEntry, $SaveAs, $Overwrite);[/code]

Finally we need to ensure that we correctly dispose of the ZipArchive object otherwise we’ll leave it open:

[code]### Ensure we close the file handle otherwise the file will be left open
$AppV5Archive.Dispose();[/code]

That’s it! It you want a simpler way of doing this, just download the Virtual Engine App-V 5.0 Package PowerShell CmdLets. You can achieve all this in just a single command:

[code]Save-AppV5FileXml -AppV c:\package.appv -XML AppxManifest[/code]

Full PowerShell Code Snippet

Here is the full code listing:

[code]### The System.IO.Compression.FileSystem requires at least .Net Framework 4.5
[System.Reflection.Assembly]::LoadWithPartialName(“System.IO.Compression”) | Out-Null;
[System.Reflection.Assembly]::LoadWithPartialName(“System.IO.Compression.FileSystem”) | Out-Null;

### Open the ZipArchive with read access
$AppV5Archive = New-Object System.IO.Compression.ZipArchive(New-Object System.IO.FileStream($SourceAppV5Archive, [System.IO.FileMode]::Open));

### Locate the AppxManifest.xml file
$AppxManifestEntry = $AppV5Archive.GetEntry(“AppxManifest.xml”);
### ZipArchiveEntry.ExtractToFile is an extension method
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($AppxManifestEntry, $SaveAs, $true);

### Ensure we close the file handle otherwise the file will be left open
$AppV5Archive.Dispose();[/code]