Wednesday, November 20, 2013

PS Scripts to change File Association on your Windows 8 / 8.1 Image

Hello there,

A colleague of mine asked me if we could automate modifying file association when building images.

Here is the solution we came up with:

After a bit of google-fu-ing, it seems that there are two ways to accomplish this either through some HKCU   registry keys but some key permissions need to be changed or using DISM.

Here we are going to look at the DISM way.

Note that when using DISM the changes are not available for the currently logged in user but it works for new users. Therefore, this is a valid method when creating a custom Windows 8 / 8.1 image.

First we Need to export the current File association with DISM. To do this we will create a script called
Get-AppAssociation.ps1 with the following content:


param(

[parameter(Mandatory = $True )][string]$AssocXMLExportPath
)
DISM /online /Export-DefaultAppAssociations:$AssocXMLExportPath


Next we will create a second script called Set-AppAssociation.ps1 to check if the file extension to modify exists and if so modify it else add it to the xml file. This script also creates a backup of the original xml file.


param(
[parameter(Mandatory = $True )][string]$AssocXMLPath,
    [parameter(Mandatory = $True )][string]$Extention,
    [parameter(Mandatory = $True )][string]$ProgID,
    [parameter(Mandatory = $True )][string]$AppName
)

If(! (Test-Path -Path $AssocXMLPath".bak")){
    Copy-Item $AssocXMLPath $AssocXMLPath".bak"
}

[xml]$AssocXML = Get-Content $AssocXMLPath -Encoding UTF8
$Associations = @($AssocXML.DefaultAssociations.Association)
$Found = $False

foreach ($Association in $Associations){
    #Checks if the file association already exists and if it does update it. 
   If($Association.Identifier -eq  $Extention){
        $Association.ProgId = $ProgID
        $Association.ApplicationName = $AppName
        $Found = $True
   }
}

#If not existing association are found a new one is created and added to the xml
 if(!($found)){
        #Create a new XML element       
        $NewAssociationNode = $AssocXML.CreateElement("Association")
       
        #Set the attributes for the new element
        $NewAssociationNode.SetAttribute("Identifier",$Extention)
        $NewAssociationNode.SetAttribute("ProgId",$ProgID)
        $NewAssociationNode.SetAttribute("ApplicationName",$AppName)

        #Inject the new child to existing
        $AssocXML.LastChild.AppendChild($NewAssociationNode) > $null
}
$AssocXML.Save($AssocXMLPath)

Finally, we will use a third script to import those modified settings back to the image, using the script Restore-AppAssociation.ps1. Here is the content of the script.
param(
[parameter(Mandatory = $True )][string]$AssocXMLImportPath
)
DISM /online /Import-DefaultAppAssociations:$AssocXMLImportPath

And to bring it all together and demonstrate how to properly use those scripts here is a batch file that calls the 3 scripts above with parameters to modify the file extensions (pre-sysprep & capture).

cd /d "%~dp0"
::powershell set-executionpolicy remotesigned

:: Export the file association XML to the file system with DISM
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Get-AppAssociation.ps1 -AssocXMLExportPath "C:\OSD\AppAssoc.xml""

::modify the association XML content
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".bmp"  -ProgID "PhotoViewer.FileAssoc.Bitmap" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".dib"  -ProgID "PhotoViewer.FileAssoc.Bitmap" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".jfif"  -ProgID "PhotoViewer.FileAssoc.JFIF" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".jpe"  -ProgID "PhotoViewer.FileAssoc.Jpeg" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".jpeg"  -ProgID "PhotoViewer.FileAssoc.Jpeg" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".jpg"  -ProgID "PhotoViewer.FileAssoc.Jpeg" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".jxr"  -ProgID "PhotoViewer.FileAssoc.Wdp" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".png"  -ProgID "PhotoViewer.FileAssoc.Png" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".tif"  -ProgID "PhotoViewer.FileAssoc.Tiff" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".tiff"  -ProgID "PhotoViewer.FileAssoc.Tiff" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".wdp"  -ProgID "PhotoViewer.FileAssoc.Wdp" -AppName 'Windows Photo Viewer'"
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Set-AppAssociation.ps1 -AssocXMLPath "C:\OSD\AppAssoc.xml" -Extention ".pdf"  -ProgID "AcroExch.Document.11" -AppName 'Adobe Reader'"

:: Import the file association XML to the file system with DISM
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& .\Restore-AppAssociation.ps1 -AssocXMLImportPath "C:\OSD\AppAssoc.xml""

Well that is it for today, I hope you enjoy this post !!

No comments:

Post a Comment