On July 1, 2026, Microsoft updated the Add Win32 apps to Microsoft Intune documentation to clarify the interaction between the PowerShell Script Installer for Win32 Apps and Multi-Admin Approval (MAA). The clarification is narrow: script upload during the app-creation workflow is blocked when MAA is enabled on the tenant, and two additional script properties — enforceSignatureCheck and runAs32Bit — will fall under approval gating in a subsequent update. Nothing in the update changes what the Script Installer is. It changes only what its operational envelope looks like on a tenant with elevated governance controls.
The reason the July 1 clarification lands as news rather than as a routine documentation revision is that the Script Installer itself is no longer new. The feature went generally available in January 2026 and has been in production use for approximately six months at the point of writing. The initial wave of coverage — Peter van der Woude's getting-started walkthrough, the Patch My PC overview, and Michael the Admin's PSADT combination pattern — appeared in the first weeks after GA. What is available now, six months into production use, is empirical evidence of how the feature settles into an established packaging pipeline that already relies on the PowerShell App Deployment Toolkit. This article documents that intersection: what the Script Installer structurally changes for PSADT wrappers, three concrete deployment layouts, and the governance implication for tenants that have MAA in effect.
Six Months of PowerShell Script Installer — What Practice Looks Like Now
The PowerShell Script Installer for Win32 Apps was announced in preview during the second half of 2025 and reached general availability in January 2026. The feature extends the Win32 App type in Intune with a first-class script surface. An install script and an uninstall script are uploaded as independent assets on the app object, alongside — not inside — the .intunewin content package. Requirement scripts, which were already a Win32 App capability, sit on the same asset surface. Detection remains untouched by the Script Installer: MSI product-code, file-existence, registry-value, and custom-script detection continue to be selected independently of how the installer half of the app is realised.
The vendor framing at launch was pragmatic. The Script Installer removes the requirement that a Win32 App wrap every installer decision inside a single .intunewin payload. For estates that already run a mature packaging pipeline — a PSADT wrapper for every non-trivial install, a signing convention, a change-controlled release into ConfigMgr — the Script Installer offered a second path onto the Intune Win32 surface without demanding that the entire packaging discipline be refactored. For estates that had adopted native Intune Win32 first and had accumulated a body of bespoke PowerShell around simple installers, it offered a way to lift those scripts into a supported asset type rather than continuing to embed them inside opaque .intunewin files.
Six months of practice have surfaced three observations that were not obvious from the launch documentation alone.
The first observation is that the Script Installer is a structural feature, not an ergonomic one. The command line that runs on the endpoint is functionally equivalent to what a Win32 App with a Install.ps1 inside the .intunewin and an install command of powershell.exe -ExecutionPolicy Bypass -File .\Install.ps1 would produce. What changes is the separation of the script asset from the content asset, and the operational consequences that separation carries — where signatures apply, where versioning applies, and which lifecycle events touch which asset.
The second observation is that the 50 KB script-size limit documented against each script asset is a real operational boundary, not a theoretical one. A minimal script that shells out to a bundled installer stays comfortably under the limit. A script that inlines PSADT-style logic — dialogs, deferral, close-processes handling, exit-code translation — exceeds the limit rapidly. The consequence is that the Script Installer does not compete with PSADT for the wrapping role. It composes with PSADT, or it replaces PSADT only for installers where no wrapping logic is required.
The third observation is that Multi-Admin Approval, which was rolled out in phases across 2024 and 2025 to gate sensitive operations behind an approval workflow, treats the Script Installer's script upload as a sensitive operation. This is defensible: the script executes on managed endpoints under the local system context, and any tenant that has adopted MAA has adopted it precisely to interpose an approval step in front of that class of operation. The Microsoft Learn update on July 1 confirmed and clarified this behaviour, and the interaction is the subject of the fourth section below.
The Mechanics — Scripts as First-Class Assets, Not Payloads
The structural change that the Script Installer introduces is best understood at the level of the app object that Intune stores. A Win32 App without the Script Installer has one primary content reference — the .intunewin — and its install and uninstall command lines are strings that Intune passes to the endpoint at deployment time. The endpoint expands the .intunewin into a per-deployment working directory, resolves the install command against that directory, and executes it.
A Win32 App with the Script Installer has, in addition to the .intunewin, discrete script assets attached to the app object. The install script and the uninstall script are stored as separate properties on the app rather than as files inside the content package. Requirement scripts sit on the same surface. At deployment time, the endpoint receives the script asset, writes it to a working directory alongside the expanded .intunewin content, and executes the script. The script's working directory contains both the script itself and the expanded content package. The install command is no longer a hand-crafted string that names a file inside the content package — it is the script asset.
The consequence for detection is nil. Detection methods are separately configured on the Win32 App object and are evaluated on the endpoint independently of the installer flow. An MSI ProductCode detection continues to work whether the install path is a classical .intunewin invocation or a Script Installer. A file-existence detection is likewise agnostic. A custom detection script, which is itself a script asset on the app object, was already first-class before the Script Installer arrived and is unaffected by its introduction.
The size limit that the documentation records against each script asset is 50 KB. The number is not a random ceiling — it is the operational threshold that separates "a script that composes existing content" from "a script that inlines its own logic". A twelve-line PowerShell wrapper that calls msiexec.exe /i .\vendor.msi /qn /norestart and translates the exit code is a few hundred bytes. A PSADT wrapper script (Invoke-AppDeployToolkit.ps1 in the v4 layout) is several tens of kilobytes even before per-package customisation. The Script Installer does not attempt to accept the latter as a script asset. The intended composition is that the PSADT wrapper stays inside the .intunewin and the Script Installer's script becomes the entry point that invokes it.
An illustrative Graph payload for a Win32 App with the Script Installer looks approximately as follows. The exact schema is documented under Microsoft Graph Intune app resource types and is the authoritative reference for a production implementation; the sketch below is included only to make the asset separation concrete:
{
"@odata.type": "#microsoft.graph.win32LobApp",
"displayName": "7-Zip 24.09 x64",
"publisher": "Igor Pavlov",
"installCommandLine": null,
"uninstallCommandLine": null,
"installExperience": {
"runAsAccount": "system",
"deviceRestartBehavior": "suppress"
},
"detectionRules": [
{
"@odata.type": "#microsoft.graph.win32LobAppProductCodeDetection",
"productCode": "{23170F69-40C1-2702-2409-000001000000}"
}
],
"installScript": { "scriptContent": "<base64-encoded PowerShell>" },
"uninstallScript": { "scriptContent": "<base64-encoded PowerShell>" }
}
The two absent properties are as informative as the present ones. installCommandLine and uninstallCommandLine are null because the install and uninstall paths are the script assets, not command strings. The endpoint agent reads the script from the app object, materialises it into the deployment working directory, and invokes it with the standard PowerShell host arguments.
Two script properties named in the July 1 documentation update sit on this same object: enforceSignatureCheck and runAs32Bit. The first, when set to true, instructs the endpoint agent to verify an Authenticode signature on the script before executing it. The second forces the script to be hosted in the 32-bit PowerShell process on 64-bit endpoints, which is the pattern required for interacting with the 32-bit registry view or with 32-bit-only COM objects. Both properties are already available; what the update announced is that both will fall under MAA gating in an upcoming release.
PSADT Under Script Installer — Three Layouts
The intersection between the Script Installer and a PSADT-based packaging pipeline admits three deployment layouts. The layouts are not officially documented as such — Microsoft's guidance describes the Script Installer surface; the PSADT documentation describes the wrapper; the composition is left to the packaging team to choose. What follows is the author's classification of the three patterns observed in practice, with the tradeoffs that separate them.
Layout A — Classical, Unchanged
The .intunewin package contains the complete PSADT folder — Files\, SupportFiles\, PSAppDeployToolkit\, Invoke-AppDeployToolkit.ps1, and Invoke-AppDeployToolkit.exe. The install command line on the Win32 App points at the entry-point executable:
Invoke-AppDeployToolkit.exe -DeploymentType Install -DeployMode Silent
The uninstall command line points at the same executable with -DeploymentType Uninstall. Detection is configured against the MSI product code or the installer's registry marker. No Script Installer asset is present on the app object. The Win32 App looks structurally identical to how a PSADT-wrapped Win32 App looked before January 2026.
The advantage of Layout A is that it is the defensive path. The signature applied to Invoke-AppDeployToolkit.exe covers the entry point; the .intunewin package is a single content asset that flows through the estate's existing distribution mechanisms; the PSADT wrapper is unchanged. Existing packages migrate to Layout A by not migrating at all — they were already there.
The disadvantage is iteration cost. A change to the PSADT wrapper — a new close-processes entry, an adjusted post-install cleanup — requires the .intunewin to be rebuilt, re-signed if applicable, and re-uploaded to the app object. Each iteration touches the full content pipeline.
Layout B — Script Installer with PSADT Payload in .intunewin
The .intunewin package contains the PSADT folder as before, but the install command line is delegated to the Script Installer's script asset. The install script is a minimal PowerShell shim that invokes the PSADT wrapper:
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$exe = Join-Path $here 'Invoke-AppDeployToolkit.exe'
$args = @('-DeploymentType', 'Install', '-DeployMode', 'Silent')
$proc = Start-Process -FilePath $exe -ArgumentList $args -PassThru -Wait
exit $proc.ExitCode
The uninstall script is the same shape with -DeploymentType Uninstall. Detection remains configured against the MSI product code independently of the script assets.
The advantage of Layout B is that script iteration is decoupled from content iteration. A change to how the PSADT wrapper is invoked — for instance, switching from -DeployMode Silent to -DeployMode NonInteractive, or adding an environment-variable set before the process is launched — updates the script asset on the app object without touching the .intunewin. On a mature package where the PSADT wrapper is stable but the invocation policy is still being refined, the reduction in re-upload cost is measurable.
The disadvantage is that Layout B breaks the signature-chain continuity that Layout A preserves. In Layout A, the signed Invoke-AppDeployToolkit.exe inside the signed .intunewin produces a single verification surface. In Layout B, the script asset is a separate artifact with its own signature status. If the estate's Intune tenant has enforceSignatureCheck set to true on the script asset — which it should, in any organisation that treats script execution as a governance concern — the script asset must be signed independently. The signing pipeline now covers two artifacts rather than one, and the two must be kept in sync.
Layout C — Flat, Script-Driven, Without PSADT
The .intunewin package contains only the vendor installer. The install script is a direct PowerShell invocation of msiexec.exe or the vendor's silent installer, with no PSADT wrapper involved:
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$msi = Join-Path $here '7z2409-x64.msi'
$log = Join-Path $env:TEMP '7zip-install.log'
$args = @('/i', "`"$msi`"", '/qn', '/norestart', "ALLUSERS=1", "/l*v", "`"$log`"")
$proc = Start-Process -FilePath 'msiexec.exe' -ArgumentList $args -PassThru -Wait
exit $proc.ExitCode
The uninstall script is analogous, using the MSI product code with msiexec.exe /x. Detection remains configured against the MSI product code.
The advantage of Layout C is minimalism. There is no PSADT toolkit inside the .intunewin, no entry-point executable, no wrapper module. The Win32 App is a thin sandwich around a single installer, with the script asset as its install and uninstall entry points. For a well-behaved MSI that requires no user interaction, no pre-install checks beyond what the MSI itself performs, no post-install cleanup, and no close-processes handling, Layout C is the honest expression of what the install actually needs.
The disadvantage is that everything PSADT provides — the dialogs, the deferral logic, the disk-space check, the close-processes handling, the log-file convention, the exit-code translation for 3010 and 1641 — is absent. Layout C is not a shortcut for a complex application; it is the correct layout for a simple one. An application that would require a PSADT wrapper to install cleanly does not become simpler by being wrapped in a raw msiexec.exe call in a Script Installer asset. It becomes harder to reason about, because the pre-install checks that would surface in the PSADT log now surface as anonymous non-zero exit codes with no context.
Comparison
The table below summarises the three layouts against the four operational dimensions that most often decide between them.
| Layout | Use case | Signature surface | Iteration speed |
|---|---|---|---|
| A — Classical | Established PSADT wrappers in stable production; migrated ConfigMgr packages | Single: signed .intunewin covers the signed entry-point executable | Slow: any change requires .intunewin rebuild and re-upload |
| B — Script + PSADT payload | Active development phase; invocation policy still being refined | Split: .intunewin and script asset are signed separately | Fast for script changes; slow for wrapper changes |
| C — Flat, script-only | Simple MSIs with no wrapper logic required; short-lived deployments | Single: .intunewin is minimal, script asset is the primary signed surface | Fast: single-script iteration, single-installer content |
The three layouts are not mutually exclusive across an estate. A packaging team can — and in practice usually does — mix them: Layout A for the ninety per cent of packages that were built pre-January 2026 and continue to run without incident, Layout C for the trivial single-MSI apps where PSADT wrapping is overkill, and Layout B reserved for packages that are actively being refined and benefit from the decoupled iteration.
The Multi-Admin Approval Wall — What Blocks and What Doesn't
Multi-Admin Approval in Intune is a governance mechanism that interposes an approval workflow between an administrator's action and its effect. An access policy is defined against a category of sensitive operations — the current supported categories include app management, script execution, and device wipe among others — and any administrator action that falls within the category requires approval from a designated second administrator before it takes effect. The mechanism was rolled out in phases across 2024 and 2025 and is now generally available across the Intune surface.
The rationale for including PowerShell script upload in the app-management category is the same rationale that motivated MAA in the first place: a script that runs under the local system context on managed endpoints is an arbitrary-code-execution surface, and any tenant that has taken the operational trouble to enable MAA has done so precisely to interpose an approval step in front of that class of operation. What the July 1 documentation update clarifies is the concrete interaction between the Script Installer's app-creation workflow and the MAA gate.
What the July 1 update documents
The specific behaviour recorded in the update is that the PowerShell script cannot be uploaded during the initial Win32 App creation workflow when MAA is enabled on the tenant. The app creation wizard proceeds up to the point at which the script asset is expected; the upload is blocked; the workflow cannot complete in a single sitting.
The workaround pattern that the documentation describes is a two-step flow. In the first step, the Win32 App is created without the script asset — a skeleton app object with metadata, .intunewin content reference, detection rules, and requirement rules, but no install or uninstall script. This step is not blocked by MAA. In the second step, the script assets are added to the existing app object through a separate operation. The second step is what MAA gates: an approval request is generated, the designated approver reviews the script content, and on approval the script is attached to the app.
The two additional properties named in the update — enforceSignatureCheck and runAs32Bit — are announced as falling under MAA gating in a subsequent release rather than in the July update itself. The direction of travel is clear: script content is gated today, script execution parameters are gated next. What further properties may fall under gating in future releases is not documented, and speculation would be out of scope. The two properties named are the two properties within the operational scope of this article.
What is not affected
The Script Installer's endpoint execution flow is not affected by MAA. Once an app has been created and its script assets have been approved and attached, deployment to devices, execution on endpoints, log collection, and detection all proceed exactly as they would on a non-MAA tenant. MAA is a pre-deployment governance gate, not an in-flight enforcement layer. Devices that have already received the deployed app continue to run it without any MAA involvement.
Detection rules are not gated. Requirement rules that are file, registry, or built-in checks are not gated. Custom detection scripts and custom requirement scripts sit on the same first-class script surface as install and uninstall scripts and are treated equivalently by MAA — script content upload during app creation is blocked; the two-step create-then-add-script flow is the sanctioned workaround. The two-step flow is not a bug being routed around. It is the intended interaction between the two features: the app skeleton is created without the sensitive asset, the sensitive asset is then submitted through the approval workflow, and the approver has an opportunity to review the script before it becomes part of the app.
Governance Recommendation for MAA-Enabled Tenants
The choice among the three PSADT layouts, and the operational impact of MAA on the app-creation flow, produce a small set of governance recommendations for a packaging team that operates against an Intune tenant.
For tenants without MAA enabled, the Script Installer is a structural choice among the three layouts. Layout A is the default for existing packages that already run through PSADT. Layout B is the marginal-improvement option for packages under active development. Layout C is the honest layout for simple MSIs that were never going to benefit from PSADT wrapping. There is no procedural blocker: a package can move between layouts as its lifecycle requires, and the packaging team's choice is dictated by iteration cost and signature-surface preference rather than by governance.
For tenants with MAA enabled, the two-step create-then-add-script flow becomes the standard operating procedure for any Win32 App that carries a script asset. The release runbook needs to reflect this. A ticket to add a new packaged application to Intune now includes two distinct operations: the app-skeleton creation, which the packaging team performs without an approver in the loop, and the script asset attachment, which triggers an approval request that a second administrator processes. The end-to-end lead time for a new package increases by the approver's response time. Estates that release infrequently can absorb this cost; estates that release frequently need to size the pool of MAA-authorised approvers such that a script attachment does not sit in the queue for longer than the package cadence tolerates.
For business-critical production rollouts, Layout A remains the defensive choice. The advantage is not a technical one — the endpoint execution flow is equivalent across the layouts. The advantage is that Layout A minimises the MAA touchpoints. A Layout A package has one asset that flows through the approval flow, and that asset is the .intunewin content upload. A Layout B or Layout C package has both the content asset and the script asset, and both must clear the approval gate. On a package that is on the critical path for a business deadline, fewer gates translate into fewer opportunities for the release to slip.
For development and test tenants, Layout B is the pragmatic default. Development tenants typically do not have MAA enabled — the operational overhead of a two-approver flow on every packaging iteration is incompatible with the cadence of active development — and Layout B's decoupled iteration is where its advantage lies. A package that reaches production readiness in a development tenant under Layout B is migrated to Layout A for the production deployment, on the reasoning above. The two layouts are not incompatible; the transition is a repack of the same source material into a different envelope.
On the two named properties, enforceSignatureCheck should be set to true on any script asset that is expected to reach a production tenant. The property is already available; the pending MAA gating does not affect what the property does, only the workflow through which it is changed. Setting the property early — during development, before MAA gating applies — establishes the signing discipline as part of the package's release definition rather than as a scramble at production cut-over. runAs32Bit is used sparingly and only where the script's actual work requires the 32-bit context; the property is not a defensive default and should not be set as one.
The Script Installer, six months into general availability, has settled into the shape that the initial coverage anticipated. It is a structural surface, not an ergonomic one; it composes with PSADT rather than competing with it; and its interaction with Multi-Admin Approval is the operational detail that determines how much of the release runbook needs to change on a governed tenant. The July 1 documentation update is a small revision to the reference documentation, but it is the revision that names, in one place, the current state of that interaction and the direction in which it is developing.
Sources: Microsoft Learn — Add Win32 apps to Microsoft Intune (documentation updated 2026-07-01), Michael the Admin — Using PowerShell Script Installer with PSADT, Patch My PC — PowerShell Script Installer for Intune Win32 Apps, Peter van der Woude — Getting started with PowerShell Script Installers in Microsoft Intune, Microsoft Graph — Intune app resource types, PSAppDeployToolkit repository. Feature GA date (January 2026), Microsoft Learn update date (2026-07-01), Multi-Admin Approval interaction with Script Installer upload, the 50 KB script asset size limit, and the two named properties (enforceSignatureCheck and runAs32Bit) falling under MAA gating verified against the linked Microsoft primary sources. The three PSADT deployment layouts described above are the author's classification of patterns observed in six months of practice, not an officially documented Microsoft taxonomy. Last verified: 2026-07-19.