This is the third and final part of the PowerShell and Intune trilogy. This time, I’ll show you how to use PowerShell scripts for your Win32 app deployment. This is a continuation of part 2, with more details specific to application deployment.
Win32 applications
This type of application, which you can deploy using Microsoft Intune, is essentially a compressed file containing everything needed to install and uninstall an application on your Windows client. As mentioned in the first part of this trilogy, you have three options for using PowerShell scripts to be more flexible when installing applications in Intune: checking installation requirements, detecting whether the application is already installed, and running install and uninstall commands.
In this blog, we will focus on the install and uninstall PowerShell scripts and how you can use them without adding all the installation files to an Intunewin package.
Installation from an internet location
If you want more flexibility and do not want to update the Win32 app in your Intune environment whenever a new version is released (which essentially requires repackaging your Win32 app with the new installation files), you could try this approach.
You can create an installation script and a matching uninstallation script for software with installation files on the vendor’s website or at an internet location accessible to your clients.
In the example below, there are three scripts: an install script to deploy 7-Zip to your clients, a detection script that checks the specified version of 7-Zip, and a generic uninstall script that uninstalls any version from the client. You can add these scripts to your Win32 app. For install and uninstall commands, you can select PowerShell from the dropdown menu instead of the default command-line option.
The installation command for this example would be:
.\Install.ps1 -URL 'https://github.com/ip7z/7zip/releases/download/26.02/7z2602-x64.exe' -Outputfile '7-zip.exe' -InstallParameters "/S"
Note: To use this, you must have an empty dummy Intunewin package so you can start adding the Win32 app to Intune. For example, you could create a package from c:\temp\IntuneWin\readme.txt that contains no data, keeping things as small as possible.
Install.ps1
This installation script downloads the latest version from 7-Zip’s website and starts the installation on your client. It saves the file to the temp location, runs it, and cleans up afterward.
param (
[string]$URL,
[string]$Outputfilename,
[string]$InstallParameters
)
#Download the file from the specified https location and save it as the specified Outputfilename
if ($null -ne $URL -and $Null -ne $OutputFilename) {
try {
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile "$($env:TEMP)\$($Outputfile)" -ErrorAction Stop
Write-Output ("Downloaded file from {0} and saved it to {1}" -f $URL, "$($env:TEMP)\$($Outputfilename))")
}
catch {
Write-Output ("Could not download file from {0} or save it to {1}" -f $URL, "$($env:TEMP)\$($Outputfilename))")
exit 1
}
}
else {
Write-Output ("URL and/or Outputfile were not specified")
exit 1
}
#Start installation using the Outputfilename and $InstallParameters values
if ($null -ne $InstallParameters) {
try {
Start-Process -FilePath "$($env:TEMP)\$($Outputfilename)" -ArgumentList $InstallParameters -Wait -NoNewWindow -ErrorAction Stop
Write-Output ("Installation succeeded using {0} with {1}" -f $OutputFilename, $InstallParameters)
Remove-Item -Path "$($env:TEMP)\$($Outputfilename))" -Force:$true -Confirm:$false
exit 0
}
catch {
Write-Output ("Installation succeeded using {0} with {1}" -f $OutputFilename, $InstallParameters)
exit 1
}
}
Uninstall.ps1
This uninstall script removes 7-Zip from your client, if needed. It uses the default Uninstall.exe from 7-Zip to remove it from your system.
#Uninstall 7-Zip
try {
Start-Process -FilePath "$($env:ProgramFiles)\7-Zip\Uninstall.exe" -ArgumentList "/S" -Wait -NoNewWindow -ErrorAction Stop
Write-Output ("Successfully uninstalled 7-Zip")
exit 0
}
catch {
Write-Output ("Error uninstalling 7-Zip")
exit 1
}
Detection.ps1
This script checks whether 7-Zip is installed on the system and verifies a specific version. If 7-Zip is not found on the system, or the version is older than the specified version, it will start the installation command specified in the Win32 app in Intune.
#Check if the installed 7-Zip version matches or is more recent than the specified $Version value
$Version = '26.02'
if (Get-ChildItem $env:ProgramFiles\7-Zip\7zfm.exe) {
if ((Get-Item -Path $env:ProgramFiles\7-Zip\7zfm.exe).versioninfo.ProductVersion -ge $Version ) {
Write-Output ("Expected 7-Zip version {0}, found {1}" -f $Version, ((Get-Item -Path $env:ProgramFiles\7-Zip\7zfm.exe).versioninfo.ProductVersion))
exit 0
}
else {
Write-Output ("Expected 7-Zip version {0}, found {1}" -f $Version, $((Get-Item -Path $env:ProgramFiles\7-Zip\7zfm.exe).versioninfo.ProductVersion))
exit 1
}
}
#If 7-Zip was not found, exit and start installation
else {
Write-Output ("7-Zip was not found, installing now...")
exit 1
} Installation of Windows optional features
Another example of how you can use PowerShell scripts in a Win32 app is adding Windows optional features to a client, such as Hyper-V. In the example below, there are three PowerShell scripts: one to detect whether the Windows optional feature, Hyper-V in this example, is present; an install script that adds it to Windows if it is not present; and an uninstall script that removes it if needed. The installation script is a generic script that allows you to enter a specific Windows optional feature as a parameter for installation and uninstallation. The detection script, however, cannot be executed with parameters from within Intune and needs a hardcoded value. You need to change that value for every Windows optional feature Win32 app.
Note: To use this, you must have an empty dummy Intunewin package so you can start adding the Win32 app to Intune. For example, you could create a package from c:\temp\IntuneWin\readme.txt that contains no data, keeping things as small as possible.
Install.ps1
This script installs the Windows optional feature and all its requirements without rebooting the client computer. The installation command for this example would be:
.\Install.ps1 -WindowsOptionalFeature Microsoft-Hyper-V-All
param (
[string]$WindowsOptionalFeature
)
#Install the Windows component together with all the requirements. Use
#Get-WindowsOptionalFeature -Online | Select-Object FeatureName | Sort-Object FeatureName
#to show all available options.
try {
Enable-WindowsOptionalFeature -Online -FeatureName $WindowsOptionalFeature -All:$true -NoRestart:$true -ErrorAction Stop
Write-Output ("Installed Windows optional feature {0}" -f $WindowsOptionalFeature)
}
catch {
Write-Output ("Could not install Windows optional feature {0}" -f $WindowsOptionalFeature)
exit 1
}
Uninstall.ps1
This script removes the Windows optional feature from the client without rebooting the computer. The uninstall command for this example would be:
.\Uninstall.ps1 -WindowsOptionalFeature Microsoft-Hyper-V-All
param (
[string]$WindowsOptionalFeature
)
#Uninstall the Windows component together with all the requirements. Use
#Get-WindowsOptionalFeature -Online | Select-Object FeatureName | Sort-Object FeatureName
#to show all available options.
try {
Disable-WindowsOptionalFeature -Online -FeatureName $WindowsOptionalFeature -NoRestart:$true -ErrorAction Stop
Write-Output ("Removed Windows optional feature {0}" -f $WindowsOptionalFeature)
}
catch {
Write-Output ("Could not remove Windows optional feature {0}" -f $WindowsOptionalFeature)
exit 1
}
Detection.ps1
This script checks whether the Windows optional feature is present. If it is not present, it will start the installation script. Change the $WindowsOptionalFeature value to the Windows optional feature you want to add.
#Specify the Windows optional feature you want to check for
#Use Get-WindowsOptionalFeature -Online | Select-Object FeatureName | Sort-Object FeatureName to show all available options
$WindowsOptionalFeature = 'Microsoft-Hyper-V-All'
if ((Get-WindowsOptionalFeature -Online -FeatureName $WindowsOptionalFeature).State -eq 'Enabled') {
Write-Output ("Windows optional feature {0} was found" -f $WindowsOptionalFeature)
exit 0
}
else {
Write-Output ("Windows optional feature {0} was not found, installing now" -f $WindowsOptionalFeature)
exit 1
}
Wrapping up
And that’s how you can use only PowerShell scripts to deploy a Win32 app to your Intune clients: just scripts, no repackaging Intunewin files.