Monthly Archives: August 2015

See what I did there? 😉

I’ve talked about creating your own script repository in the past. I like having some sort of structure. GitHub goes further. It also helps with version control and so much more!. My idea of version control is adding -v# after any script, don’t judge me…

These days everything seems to be in GitHub! The PowerShell DSC Resource Modules are there. Azure PowerShell Module & Templates are there. You can even deploy Azure Resources from GitHub! You can also use Git for continuous deployment for website content/apps.

Visual Studio supports GitHub as well for continuous delivery

I just discovered Gist! Doug Finke created a GUI to help create a template to extract Data from text files. I noticed that the code was straight out of GitHub. So I did a little bit of googling and sure enough, I found out how! Gist lets you share snippets of code with others. All you need to do is copy & paste the url and you’re good to go!


<#
Author: I. Strachan
Version: 1.0
Version History:
Purpose: Extract The AppxManifest.xml file from the .appv file.
Get the Version,PackageID and VersionID from AppxManifest.xml
#>
function Get-AppxManifest {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateScript({ Test-Path -Path $_ -PathType Container })]
[string]$Source
)
begin{
#Load Assembly for Zip
Add-Type -assembly 'system.io.compression.filesystem'
#get AppV Files from parent Folder
$appVFiles = Get-ChildItem -Path $Source -Recurse -Filter ('*.appv')
$manifestFolder = "$($PSScriptRoot)\Manifest"
if(!(Test-Path -Path $manifestFolder)) {
Write-Verbose 'Manifest folder does not exist. Creating folder'
New-item -Path $manifestFolder -Type Directory | Out-Null
}
}
process{
#get AppxManifest.xml content
$appVFiles |
ForEach-Object {
$FileName = $_.BaseName
$FilePath = $_.FullName
#Create handle in orde to dispose File later on
$hndZipFile = [System.IO.Compression.ZipFile]::OpenRead($_.FullName)
$hndZipFile.Entries |
Where-Object { $_.FullName -like 'AppxManifest.xml' } |
ForEach-Object {
$File = Join-Path $manifestFolder "$($FileName)_$($_.FullName)"
[IO.Compression.ZipFileExtensions]::ExtractToFile($_, $File, $true)
#Typecast to Get XML
[XML]$xml = Get-Content $File
[PSCustomObject]@{
Version = $xml.Package.Identity.Version
PackageId = $xml.Package.Identity.PackageId
VersionId = $xml.Package.Identity.VersionId
DisplayName = $xml.Package.Properties.DisplayName
AppVPath = $FilePath
}
}
#Close handle on File
$hndZipFile.Dispose()
}
}
end{}
}

Best part of Gist is having you code “As-Is”. Using WordPress plugins sometimes gets the “<#” , “#>” or “&” wrong, replacing it with HTML equivalent. This way you’ll never have to worry about your code being mutilated anymore! Sweet!!!

Here’s an article to help you on your way getting started with GitHub.

wpid-wp-1440101002843.jpg

GitHub is (going to be) one of those things that you need to master…

Hope it’s worth something to you…

Ttyl,

Urv

‘Sup PSHomies

So APP-V has this file, AppxManifest.xml, where the Version,VersionID,PackageID is stored amongst other things. My last interaction with software virtualization was when APP-V still went by the name SoftGrid… Yeah… So I was kinda reluctant, that was until I heard that the APP-V client is all about PowerShell! This pleases me… 😉 I guess that’s why my colleague thought of me in the first place… I do love me some PowerShell… Hehe…

So he explained that the .appv file is just a zip file… Wait what?  So I can extract the content just like a zip file? Good to know!!! I remember seeing this tactic once used by Bartek Bielawski in his excel module. It would seem that a .xlsx file is also just a zip file.

I’ve been using PowerShell version 5 for quite some time. There are two cmdlets available for zipping and unzipping respectively,Compress- and Expand-Archive. This will get you all the files. My first attempt was to extract all the files and then select the AppxManifest.xml file, but that seemed like quite a lot of unnecessary work for just one file… Hmmm… Guess it’s  .NET then…

Before the archive cmdlets the only way to deal with zip file was with you needed to use .NET to extract files from zip. Just load the assembly

Add-Type -assembly 'system.io.compression.filesystem'

Rule of thumb is to use a cmdlet if available, but in this case I only wanted that one file… I checked if expand supported extract a single file, it doesn’t, so using .NET is justified (for the moment)

My first attempt was to copy the appv file and rename it to zip. But then I would need to clean up files/folders afterwards… Why not just read the file eh? Just one thing, you need a handle on the file you opened in order to dispose of the process later down… The function will extract the AppxManifest file and prepend the appv filename to the AppxManifest.xml file, using underscore as a separator, in the subfolder manifest… Whew! Still follow me?

Ok… enough chit-chat here’s the code…


<#
   Author: I. Strachan
   Version: 1.0
   Version History:

   Purpose: Extract The AppxManifest.xml file from the .appv file.
            Get the Version,PackageID and VersionID from AppxManifest.xml
#>
function Get-AppxManifest {
   [CmdletBinding()]
   param (
      [Parameter(Mandatory = $true)]
      [ValidateScript({ Test-Path -Path $_ -PathType Container })]
      [string]$Source
   )

   begin{
      #Load Assembly for Zip
      Add-Type -assembly 'system.io.compression.filesystem'

      #get AppV Files from parent Folder
      $appVFiles = Get-ChildItem -Path $Source -Recurse -Filter ('*.appv')
      $manifestFolder = "$($PSScriptRoot)\Manifest"
  
      if(!(Test-Path -Path $manifestFolder)) {
         Write-Verbose 'Manifest folder does not exist. Creating folder'
         New-item -Path $manifestFolder -Type Directory | Out-Null
      }
   }

   process{
      
      #get AppxManifest.xml content
      $appVFiles | 
      ForEach-Object {
         $FileName = $_.BaseName
         $FilePath = $_.FullName

         #Create handle in orde to dispose File later on
         $hndZipFile = [System.IO.Compression.ZipFile]::OpenRead($_.FullName)

         $hndZipFile.Entries | 
         Where-Object { $_.FullName -like 'AppxManifest.xml' } |
         ForEach-Object {
            $File = Join-Path $manifestFolder "$($FileName)_$($_.FullName)"
            [IO.Compression.ZipFileExtensions]::ExtractToFile($_, $File, $true)

            #Typecast to Get XML 
            [XML]$xml = Get-Content $File

            [PSCustomObject]@{
               Version = $xml.Package.Identity.Version
               PackageId = $xml.Package.Identity.PackageId
               VersionId = $xml.Package.Identity.VersionId
               DisplayName = $xml.Package.Properties.DisplayName
               AppVPath = $FilePath
            }
         }

         #Close handle on File
         $hndZipFile.Dispose()
      }
   }

   end{}
}

Just point the function to the folder hosting the appv files and you’ll get an overview of the Version,VersionID,PackageID,DisplayName and AppVPath

Get-AppxManifest

The fun part for me was using .NET to extract that single file. I forgot that you needed to keep a handle on things yourself when using .NET

Hope it’s worth something to you…

Ttyl,

Urv