Skip to main content
Win32 apps and the New PowerShell Script Installer in Intune
  1. Posts/

Win32 apps and the New PowerShell Script Installer in Intune

Michael Escamilla
Author
Michael Escamilla
Table of Contents

Now that it’s actually widely available, I figured it’s time to take a look at the new PowerShell Script Installer option for Win32 Apps in Intune and learn how it works.

There are some posts already out there that cover the feature and I encourage you to go check them out:

What is the PowerShell Script Installer for Win32 Apps?
#

This new feature allows you to utilize a PowerShell script as the installer or uninstaller for your Win32 app, instead of a normal ‘command line’.

PowerShell Script Installer option in Intune
Example Install Script

This is great for a few reasons:

  • All the installation logic is now handled by this PowerShell script. Make it as simple as my example above, or as complex as your installation requires (think PSADT style stuff).
  • As Rudy points out in his blog post, the PowerShell Script does not need to be part of the Win32 app package itself, it is part of the metadata of the app now.

Why use the PowerShell Script Installer option?
#

New Win32 Apps
#

If you are creating a new Win32 app in Intune, you no longer need to include your installation script inside the package. Store and manage the install and uninstall script separate from the Install Files of the package.

Note

As of this post, I am unable to create a New Win32 App with the PowerShell Script Installer option. I first need to create the Win32 app with the Command Line option, then edit the app to change the Installer type to PowerShell Script.

This is a note in the Docs about this limitation if you are using Multi-Admin Approval (MAA): Step 2: Program | Microsoft Learn

But I’m not using MAA and still have this limitation, so not sure what’s up with that.

Command Line option
#

With the command line option, if you want to use a PowerShell script to install, you need to:

  • Include the script file in the package
Win32 app with PowerShell scripts inside package
PowerShell scripts inside package
  • Then use the below command line to call powershell.exe and point to the scripts inside the package
%SystemRoot%\System32\WindowsPowerShell\v1.0\PowerShell.exe -ExecutionPolicy Bypass -NoProfile -File Install.ps1
Command Line for PowerShell script
Command Line for PowerShell script

Downsides to this approach is if you need to update the install or uninstall script, you need to repackage the entire Win32 app again and upload that to Intune.

This is inefficient and if you are working with a large application package like something from Autodesk, could take a long time to upload again.

PowerShell Script Installer option
#

Now with the PowerShell Script Installer option:

  • Only the installation files are required to be in the package:
Win32 app with only install files in package
Only install files inside package
  • And the Install and Uninstall scripts are uploaded into the app within the Intune portal:
PowerShell Script Installer option in Intune
Example Install and Uninstall Script

Existing Win32 Apps
#

For any existing Win32 apps that you have already created in Intune, if you need to make any changes to the install or uninstall script, you can now switch the Installer type to PowerShell script and upload a new PowerShell script directly in Intune without needing to repackage and reupload the entire Win32 app package.

  1. Switch the Installer type to PowerShell script in the dropdown box
Change Installer type to PowerShell script
Change Installer type to PowerShell script
  1. Upload your new PowerShell install and uninstall scripts
Upload new PowerShell scripts
Upload new PowerShell scripts

How is this working on the client side?
#

What is actually happening on the client side when using this new PowerShell Script Installer option is used?

Let’s start an install…

Get policies
#

The policy for the Win32 app is delivered to the client just like any other Win32 app.

If you didn’t know, you can see the app policies being received by the client in the AppWorkload.log by search for a line that starts with ‘Get policies’:

AppWorkload.log showing Win32 app policies
AppWorkload.log showing Win32 app policies

If you take a look at the policy payload, you’ll see a couple of things:

  • The InstallCommandLine and UninstallCommandLine are still set. In this example, I originally created the app with test as a placeholder until I could edit the Installer type.
  • There is a Scripts property that contains install and uninstall script IDs in a JSON format.
[
    {
        "Id": "c77e67fa-a460-490d-a0d8-5c7db4ead143",
        "Name": "Notepad++ 8.9.1 (EXE-x64) - Script Installer",
        "Version": 1,
        "Intent": 1,
        "TargetType": 1,
        "AppApplicabilityStateDueToAssginmentFilters": null,
        "AssignmentFilterIds": null,
        "DetectionRule": "[{\"DetectionType\":2,\"DetectionText\":\"{\\\"Path\\\":\\\"C:\\\\\\\\Program Files\\\\\\\\Notepad++\\\",\\\"FileOrFolderName\\\":\\\"notepad++.exe\\\",\\\"Check32BitOn64System\\\":false,\\\"DetectionType\\\":4,\\\"Operator\\\":5,\\\"DetectionValue\\\":\\\"8.9.1.0\\\"}\"}]",
        "InstallCommandLine": "test",
        "UninstallCommandLine": "test",
        "RequirementRules": "{\"RequiredOSArchitecture\":32,\"MinimumFreeDiskSpaceInMB\":null,\"MinimumWindows10BuildNumer\":\"10.0.14393\",\"MinimumMemoryInMB\":null,\"MinimumNumberOfProcessors\":null,\"MinimumCpuSpeed\":null,\"RunAs32Bit\":false}",
        "ExtendedRequirementRules": "[]",
        "InstallEx": "{\"RunAs\":1,\"RequiresLogon\":true,\"InstallProgramVisibility\":3,\"MaxRetries\":3,\"RetryIntervalInMinutes\":5,\"MaxRunTimeInMinutes\":60,\"DeviceRestartBehavior\":0}",
        "ReturnCodes": "[{\"ReturnCode\":0,\"Type\":1},{\"ReturnCode\":1707,\"Type\":1},{\"ReturnCode\":3010,\"Type\":2},{\"ReturnCode\":1641,\"Type\":3},{\"ReturnCode\":1618,\"Type\":4}]",
        "AvailableAppEnforcement": 0,
        "SetUpFilePath": "npp.8.9.1.Installer.x64.exe",
        "ToastState": 0,
        "Targeted": 1,
        "FlatDependencies": null,
        "MetadataVersion": 4,
        "RelationVersion": 0,
        "RebootEx": {
            "GracePeriod": 0,
            "Countdown": 0,
            "Snooze": 0
        },
        "InstallBehavior": 0,
        "StartDeadlineEx": {
            "TimeFormat": "",
            "StartTime": "/Date(-62135596800000)/",
            "Deadline": "/Date(-62135596800000)/"
        },
        "RemoveUserData": false,
        "DOPriority": 1,
        "newFlatDependencies": true,
        "AssignmentFilterIdToEvalStateMap": null,
        "ContentCacheDuration": null,
        "ESPConfiguration": null,
        "ReevaluationInterval": 480,
        "SupportState": null,
        "InstallContext": 1,
        "InstallerData": null,
        "AvailableAppRequestType": 0,
        "ContentMode": 1,
        "Scripts": "[{\"Id\":\"8a208b6a-fe19-4b0b-a209-d37b7c6c200a\",\"Type\":2,\"Data\":null,\"EnforceSignatureCheck\":false},{\"Id\":\"7faafc19-9fa4-413f-9e29-f9a5ab4100b5\",\"Type\":1,\"Data\":null,\"EnforceSignatureCheck\":false}]"
    }
]

The Scripts property contains two records, one for the install script and one for the uninstall script.

  • Type
    • 1 = Install Script
    • 2 = Uninstall Script
[
    {
        "Id": "8a208b6a-fe19-4b0b-a209-d37b7c6c200a",
        "Type": 2,
        "Data": null,
        "EnforceSignatureCheck": false
    },
    {
        "Id": "7faafc19-9fa4-413f-9e29-f9a5ab4100b5",
        "Type": 1,
        "Data": null,
        "EnforceSignatureCheck": false
    }
]

Download content
#

The Win32 app content is downloaded the same way, except an added step to download either the install or uninstall script is added.

You’ll see some ‘content info’ requests that include the script IDs:

AppWorkload.log content info requests including script IDs
ContentID matches the ‘Install’ script ID from policy

You see the lines where the app and also the ‘script’ is downloaded:

AppWorkload.log Downloading the install script
Downloading the install script

And the compressed script file is extracted to the IMECache folder inside the app content folder:

AppWorkload.log script extracted in IMECache folder
Extracted uninstall script in IMECache folder

If you navigate to the IMECache folder, you’ll see the extracted PowerShell script file inside the app content folder:

File Explorer shows Extracted install script in IMECache folder
Extracted install script in IMECache app content folder

Install
#

After the script is extracted, the installation is started by calling the PowerShell script from the IMECache app content folder.:

AppWorkload.log starting install
Starting install

Conclusion
#

I think this is a welcome addition to the Win32 app capabilities in Intune. It gives admins more flexibility as well as some wanted efficiency for testing and managing Win32 apps in Intune.