PSADT.WIMFile Extension

PSADT.WIMFile Extension

Extension for PowerShell App Deployment Toolkit to create and handle .WIM files.

Features

  • Creates WIM files from your Files directory by default.
  • Maximum compression by default.
  • Does not requires administrative rights to mount (extracts if can’t mount).
  • Does not requires administrative rights to create (requires wimlib).
  • Can extract to UNC Path.
  • Creates remediation scheduled tasks if mount/dismount fails
  • Multilanguage support.
  • ContinueOnError and ExitScriptOnError support.

External Links

PSADT.WIMFile Extension download

2 Likes

For more information related to the usage or installation, follow the external link.

2023/02/08 - Updated to v1.0.1 :grinning:

For more information related to the usage or installation, follow the external link.

2023/02/22 - Updated to v1.0.2 :grinning:

  • Re-Check Zero-Config Installation after mount/extract WIM File.
  • Added a progress dialog/notification indicating the WIM File is being created.
  • Added ability to continue the script when ‘New-WIMFile’ function is present.
  • Added internal function ‘Expand-WIMFile’ if the ‘Mount-WIMFile’ can’t mount the image.
  • Adequated variables according powershell cmdlets.
  • Fixed a bug when discovering the image file when no fully qualified file is given.
  • Removed PassThru parameter from all functions.
  • Fixed a bug when capture and save path don’t validate existance of folder path if any of them are UNC path.
  • Added maximum compresion level for wimlib.
1 Like

For more information related to the usage or installation, follow the external link.

2023/04/14 - Updated to v1.0.3 :grinning:

  • Fixed a bug in a parameter when calling New-RemediationDismountTask function.

For more information related to the usage or installation, follow the external link.

2023/11/22 - Updated to v1.0.4 :grinning:

  • wimlib updated to v1.14.3
  • Added some missing CurrentCultureIgnoreCase thanks to chrisshearing
1 Like

Hi,
I’m sorry but I’m gonna ask basic questions because I don’t understand how to use your extension.
I’ve put those files:

  • libwim-15.dll
  • WIMFileConfig.xml
  • WIMFileExtension.ps1
  • wimlib-imagex.exe

in the AppDeployToolkit\PSADT.WIMFile directory

I’ve added those lines on top of the AppDeployToolkitExtensions.ps1 file:

##*===============================================
##* FUNCTION LISTINGS
##*===============================================

# <Your custom functions go here>
## Variables: Extensions to load
$ExtensionToLoad = @()

$ExtensionToLoad += [PSCustomObject]@{
	Path   = "PSADT.WIMFile"
	Script = "WIMFileExtension.ps1"
}

## Loading extensions
foreach ($Extension in $ExtensionToLoad) {
	$ExtensionPath = $null
	if ($Extension.Path) {
		[IO.FileInfo]$ExtensionPath = Join-Path -Path $scriptRoot -ChildPath $Extension.Path | Join-Path -ChildPath $Extension.Script
	}
	else {
		[IO.FileInfo]$ExtensionPath = Join-Path -Path $scriptRoot -ChildPath $Extension.Script
	}
	if ($ExtensionPath.Exists) {
		try {
			. $ExtensionPath
		}
		catch {
			Write-Log -Message "An error occurred while trying to load the extension file [$($ExtensionPath)].`r`n$(Resolve-Error)" -Severity 3 -Source $appDeployToolkitExtName
		}
	}
	else {
		Write-Log -Message "Unable to locate the extension file [$($ExtensionPath)]." -Severity 2 -Source $appDeployToolkitExtName
	}
}

Now my questions:

  • I’d like the WIM file to be created in the SupportFiles directory. Is it possible?
  • I’d like the WIM file to use the name of the application
  • I’d like to understand where to put the
$MountedObject = Mount-WIMFile
$MountedObject | Dismount-WIMFile

If my install fails, should the dismount be in this section?

    ##*===============================================
    ##* END SCRIPT BODY
    ##*===============================================

    ## Call the Exit-Script function to perform final cleanup operations
    Exit-Script -ExitCode $mainExitCode
}
Catch {
    [Int32]$mainExitCode = 60001
    [String]$mainErrorMessage = "$(Resolve-Error)"
    Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName
    Show-DialogBox -Text $mainErrorMessage -Icon 'Stop'
    Exit-Script -ExitCode $mainExitCode
}

Or somewhere else?
Thanks for your help.

Hi there, no problem at all :smiley:

First of all, you have to download and extract in the Toolkit folder, so you get:

Nevermind the files, you shouldn’t extract them individually.

After you do this, you can use the AppDeployToolkitHelp.ps1 and get more information on the usage of the extension functions:

The function should be in your Deploy-Application.ps1 file, where you put the installation logic and other stuffs.

When you use the Mount-WIMFile a dismount task is automatically generated, you don’t need to worry about the dismount at all, but if you want it to be dismounted anyway you can uso the Dismoun-WIMFile with the objetct returned by the first function.

To create a WIM file use the New-WIMFile function (it uses $installName by default), like this:

New-WIMFile -Name $installName -SavetoPath (Join-Path -Path $dirSupportFiles -ChildPath "my_application_file.wim")

The WIM file is created (by default) with the content of the Files folder, after that you can move the file anywhere, just include the path in the function:

$MountedObject = Mount-WIMFile -ImagePath (Join-Path -Path $dirSupportFiles -ChildPath "my_application_file.wim")

I usually put the $MountedObject | Dismount-WIMFile in the post installation or uninstallation phases.

1 Like

I´m feeling really dumb as i don´t understand how to use the plugin. I have done everything in “AppDeployToolkitExtensions.ps1”

Should i after that put “New-WIMFile -Name $installName -SavetoPath (Join-Path -Path $dirSupportFiles -ChildPath “my_application_file.wim”)” in the Deploy-Application.ps1 file and where in that file in that case? And how should i run this from Deploy-Application.ps1?

It can be a bit hard the first time, the extension use should be (at least I planned this way) this:

  1. Run Deploy-Application.ps1 with New-WIMFile function to create the compressed .wim file with the content of the Files folder (by default).
  2. If everything went fine you should see the file in your Toolkit directory (by default).
  3. The Files folder is not needed anymore (compressed in .wim file), can be deleted.
  4. Comment or remove the New-WIMFile function in the script, we don’t want to compress again.
  5. Add the Mount-WIMFile, will look for any .wim file and mount its content, by default mounted in the Files folder (can change this).
  6. Add the Dismount-WIMFile at the end of the phase execution or in the catch if any unexpected error.

There is no correct way to use it, just keep in mind that to generate the .wim file you first need to have your “installation files” in a folder (Files by default) and run the package at least once to generate the .wim file.

Then the New-WIMFile function is not used (you’ve just created the .wim file), you have to mount and dismount the created file.

You will see a warning message if you forgot to remove the New-WIMFile function in the .ps1 file.

Check the documentation for the error exit codes, and the log for the mounting process.

This is an awesome extension.

In my opinion, maybe adding a “zero-config”-like condition to not have to comment out the wim file cmdlets each and every time. That way, you can just keep them in there with your template. I modified my Deploy-Application.ps1 script to reflect the following:

   # Mount any WIM file found in script directory (last modified one if multiple)  
# Zero-Config WIM Mounting
    $global:WIMFileExists = $false
    if ((Get-Item *.wim).count -ge 1) { $WIMFileExists = $true }
    if ($WIMFileExists) { $MountedObject = Mount-WIMFile }

Then I just add if ($WIMFileExists) { in front of all the other WIM commands. That way, if you are dealing with small installations, you don’t have to remember to comment it out, and you can keep the template as just that, a template.

Doesn’t mean you need to add it, but just one less step you have to do.

Not a bad idea at all… The main problem is that you still have to execute at least one time the PS1 to create the .WIM file before publishing the APP in SCCM/Intune/MDM, so it can’t be fully zero-config… But, once the .WIM is created I can implement a way to avoid commenting the cmdlets… Thanks for the idea

Understood. That’s the tricky part. For me, I just import the module and run the command, or simply do a New-WindowsImage and then toss it in the folder.

I also made a mistake in my previous post. It seems even if there is a WIM, it would never mount. The relative path is always the main script, not the Deploy-Application.ps1 script. So you would need to edit line 4 to the following if ((Get-Item -Path $(Split-Path $invokingScript) -Filter *.wim).count -ge 1) {