psadt-deploy-skill 0.27.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -546
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -425,549 +425,42 @@ pre-flight fails on non-ASCII without a BOM), and anything that lands in a packa
|
|
|
425
425
|
|
|
426
426
|
## Changelog
|
|
427
427
|
|
|
428
|
-
|
|
429
|
-
from
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
- **
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
- **
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
- **
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
- **
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
- **Changed (behaviour): Phase 11 no longer re-runs Phase 6.** Phase 6 answers *does the package work* (the
|
|
468
|
-
gate, in a throwaway Sandbox); Phase 11 answers *does the delivery work* (Intune test group, real device,
|
|
469
|
-
`AppWorkload.log`). A package that passes 6 and fails 11 now tells you something.
|
|
470
|
-
- **Changed: `"update skill"` is gone from the description** — un-namespaced, it made this skill answer for
|
|
471
|
-
every other updatable skill on the machine. `"psadt update"` stays.
|
|
472
|
-
- **Added `SECURITY.md`** — the risk surface next to the control that covers each part of it, each naming the
|
|
473
|
-
file and the test that implement it.
|
|
474
|
-
- **Added: researched content is data, never instructions** (`references/research-trust.md`) — Phase 2
|
|
475
|
-
researches on the open web and the result runs as SYSTEM. The install4j case generalised.
|
|
476
|
-
- **Added three guards and CI**: rule anchors proving no binding rule was lost in the move, a two-directional
|
|
477
|
-
doc cross-reference check that also reads `scripts/`, a context-budget test, and the suite on a clean
|
|
478
|
-
Windows runner for every push. Suite 441 → 474.
|
|
479
|
-
- **Added `evals/`** — 20 trigger and behaviour cases. Not yet run: `claude plugin eval` is in early access.
|
|
480
|
-
### 0.26.7 - 08.09.2026
|
|
481
|
-
- **Fixed: the control plane did not know MSIX exists.** L.8/L.9 landed in 0.26.5, but Gate 1's package-type list
|
|
482
|
-
never mentioned MSIX — so a `.msix` fell through to "native installer (default)", the one route that is wrong for
|
|
483
|
-
it, and nothing pointed at the new appendix. Gate 1 now carries **MSIX/AppX** with the decision attached: Intune
|
|
484
|
-
takes it **natively as a line-of-business app**, so the default is to use that and *not* build a PSADT package;
|
|
485
|
-
the wrapper is the exception, and L.8 is read first when it is used.
|
|
486
|
-
- **Added `tests/SKILL.Tests.ps1`**, a coherence guard: every appendix SKILL.md points at must exist, and the Gate 1
|
|
487
|
-
decision must actually route MSIX. Research that the router cannot reach is dead weight — now a test failure.
|
|
488
|
-
### 0.26.6 - 08.09.2026
|
|
489
|
-
- **Fixed: the sandbox host timeout force-killed the viewer, then told you to close the window.** A timed-out run
|
|
490
|
-
was torn down like a finished one. That **orphans `vmmemWindowsSandbox`** — the Hyper-V compute service owns it,
|
|
491
|
-
so the host cannot kill it, and it keeps the work folder locked until the next run throws on it — and it removes
|
|
492
|
-
the only window through which the guest could still be shut down cleanly. The script's own comments name this
|
|
493
|
-
mechanism as the reason the *guest* must shut itself down; the timeout path did it anyway. A timeout now touches
|
|
494
|
-
nothing and explains what to close and which knob to raise.
|
|
495
|
-
- **Fixed: the warning claimed 60 seconds while the code waited 180** — a literal duplicating a parameter default.
|
|
496
|
-
One declared value now feeds both.
|
|
497
|
-
- **Appendix G finding 6 corrected**: "no recovery path" is now scoped to a run killed from *outside* the script.
|
|
498
|
-
### 0.26.5 - 08.09.2026
|
|
499
|
-
- **L.8, new: MSIX/AppX**, verified against Microsoft Learn and against the live cmdlets. MSIX is a two-step
|
|
500
|
-
model — machine-wide **staging**, then **per-user registration at logon** — and three traps follow from it:
|
|
501
|
-
**`Add-AppxPackage` as SYSTEM registers the app for the SYSTEM account and reports success** (nobody can launch
|
|
502
|
-
it), **`Get-AppxPackage` is the wrong detection cmdlet** (finds nothing right after provisioning, so Intune
|
|
503
|
-
reinstalls forever), and **de-provisioning does not remove the app from existing users** — a complete uninstall
|
|
504
|
-
needs `Remove-AppxProvisionedPackage` *and* `Remove-AppxPackage -AllUsers`. Plus signing: the certificate
|
|
505
|
-
Subject must equal the manifest Publisher (so a vendor MSIX cannot just be re-signed), self-signed certs belong
|
|
506
|
-
in `LocalMachine\TrustedPeople`, and missing timestamping is what makes an expired certificate break installs.
|
|
507
|
-
And the decision that comes first: **usually don't wrap MSIX in PSADT** — Intune takes it natively.
|
|
508
|
-
- **L.9, new: App-V is not end of life.** The client and sequencer are **no longer deprecated** (fixed extended
|
|
509
|
-
support, no end date, no extra cost); only the **server components** end in **April 2026**. Also: `-Global` is
|
|
510
|
-
the device-context switch, and a package in use goes *pending* — a global task applies only after a restart.
|
|
511
|
-
- **The MSIX row in L.2 was misleading and is rewritten**; L.2 gains an App-V row.
|
|
512
|
-
### 0.26.4 - 08.09.2026
|
|
513
|
-
- **L.7, new: Inno Setup and NSIS**, verified against vendor documentation. `/VERYSILENT` **reboots the
|
|
514
|
-
machine by itself** when a restart is needed — so `/NORESTART` is mandatory, and `/RESTARTEXITCODE=3010`
|
|
515
|
-
turns the fact into the code Intune already understands. And `Uninstall.exe /S` in NSIS **returns before
|
|
516
|
-
the uninstall has finished** (it copies itself to temp and detaches), so any verification afterwards races
|
|
517
|
-
it — `_?=<installdir>` makes it synchronous, must be last, must not be quoted.
|
|
518
|
-
- **Advanced Installer wired into L.1 and L.2**, not just the new L.6 — with a measured fingerprint
|
|
519
|
-
(`AI_*` custom actions, `aicustact.dll`, `OLDPRODUCTS;AI_NEWERPRODUCTFOUND`).
|
|
520
|
-
### 0.26.3 - 08.09.2026
|
|
521
|
-
- **Appendix L gains three sections**, researched against vendor documentation instead of written from
|
|
522
|
-
memory: **MSP patches** (the full `/p` matrix, why `/i` and `/p` never combine, and that exit 1642 means
|
|
523
|
-
*either* "not installed" *or* "wrong patch revision" — so it must not be treated as a blanket success),
|
|
524
|
-
**WiX Burn bundles** (BundleProviderKey rather than a ProductCode for detection; `/layout` is a Burn
|
|
525
|
-
action but the bootstrapper decides whether it can be narrowed — the ADK refuses, so an offline layout is
|
|
526
|
-
always the whole kit), and **Advanced Installer projects** (the `.aip` CLI, a fresh ProductCode per build
|
|
527
|
-
changing the package identity every time, and the undocumented behaviour that relative paths resolve
|
|
528
|
-
against the .aip's own location — moving a project between drives breaks it silently).
|
|
529
|
-
### 0.26.2 - 08.09.2026
|
|
530
|
-
- **Fixed: a WHQL driver pack turned the pre-flight red.** `Get-DriverSignatureInfo.ps1` did not strip the
|
|
531
|
-
inline comment that WHQL packs write after `CatalogFile=` (`; for WHQL certified`), so the catalog never
|
|
532
|
-
resolved and validly signed drivers classified as `Unsigned` — 6 of 70 INF in a Dell WinPE set, all of
|
|
533
|
-
whose catalogs were Authenticode-valid and Microsoft-signed. An unquoted `;` now ends the value.
|
|
534
|
-
- **Fixed: `New-MsiPackage.ps1` was the sixth script with the `-File` binder trap.** `-ProcessesToClose
|
|
535
|
-
'a','b'` arrived as one element, so the scaffold closed no processes at all — silently, while reporting
|
|
536
|
-
success. 0.25.1 had fixed the other five and missed the generator.
|
|
537
|
-
- **Documented: seven findings from a three-package dependency chain** (Appendix G) and four new
|
|
538
|
-
anti-patterns (Appendix B), including `msiexec /a` against bundled payload, the `-Include` trap, 8.3
|
|
539
|
-
short names in path comparisons, and what a service's `%TEMP%` really is on Windows 11.
|
|
540
|
-
### 0.26.1 - 06.09.2026
|
|
541
|
-
- **Fixed: a syntax error in the template silently killed the whole dossier script.** A `
|
|
542
|
-
` inside a JS
|
|
543
|
-
string literal became a real newline; JavaScript then discards the entire `<script>` block, so the
|
|
544
|
-
language toggle, all copy buttons and the condensing sticky header died at once — while all 419 tests
|
|
545
|
-
stayed green, because they only assert on rendered HTML. `tests/Report-Template.Tests.ps1` now runs
|
|
546
|
-
`node --check` on the script block plus a node-free quote-balance check, both proven against the
|
|
547
|
-
reintroduced bug.
|
|
548
|
-
- **Changed: every table copies by clicking the row**, replacing the hover icon. Key/value tables give the
|
|
549
|
-
value, return codes the code, assignments the group name, the SYSTEM-test table the whole row. Clicks on
|
|
550
|
-
a row's own controls (the foldable detection script) and text selections are left alone. The Markdown
|
|
551
|
-
description keeps its own copy button.
|
|
552
|
-
|
|
553
|
-
### 0.26.0 - 06.09.2026
|
|
554
|
-
- **Fixed: the dossier could name a return-code type Intune does not have.** Graph accepts exactly
|
|
555
|
-
`success`, `softReboot`, `hardReboot`, `retry`, `failed` — there is no `ignored`, yet "Ignored" reached a
|
|
556
|
-
real dossier because the report rendered a caller-supplied table without validating anything (`Label` was
|
|
557
|
-
free text, `Cls` was interpolated raw into a `class` attribute). `Label` and `Cls` are now derived from
|
|
558
|
-
`Type` through a closed switch and cannot be supplied at all; an invalid type throws.
|
|
559
|
-
- **Return codes are sorted and copyable.** Sorted by type in Appendix F.4 order, then numerically — the
|
|
560
|
-
order the table is verified against and typed into the portal. Each code cell has a copy icon and the
|
|
561
|
-
section a "copy table" button.
|
|
562
|
-
- **New `Get-PsadtReturnCodes.ps1`: one source of truth for the dossier AND the upload.** Previously two
|
|
563
|
-
independent literals that agreed by coincidence. `Invoke-IntuneWin32Upload.ps1` gained `-ReturnCodes`, so
|
|
564
|
-
installer-specific codes finally reach the app instead of only the document, and a new manifest key
|
|
565
|
-
`research.returnCodes` records them once for both.
|
|
566
|
-
- 419 tests; six new regression guards, each verified to fail on its reintroduced bug.
|
|
567
|
-
|
|
568
|
-
### 0.25.2 - 06.09.2026
|
|
569
|
-
- **Fixed: a sandbox run left an error dialog on the desktop.** The guest shuts itself down at the end, the
|
|
570
|
-
RDP-style client loses its session and shows a connection-lost box. The host now disposes of the viewer as
|
|
571
|
-
soon as the run reports in. The tempting fix — let the host kill the VM instead of shutting the guest down
|
|
572
|
-
— was measured and is wrong: it orphans the `vmmemWindowsSandbox` worker, which then holds the work folder
|
|
573
|
-
open for minutes and cannot be killed. Guest shuts down, host closes the window, and the wait is on the VM
|
|
574
|
-
worker rather than on the client processes.
|
|
575
|
-
|
|
576
|
-
### 0.25.1 - 06.09.2026
|
|
577
|
-
- **Fixed: array parameters broke under the `-File` binder.** `pwsh script.ps1 -Intents a,b` passes the
|
|
578
|
-
whole string as ONE element, so `Invoke-IntuneAppAssignment.ps1` rejected a perfectly valid comma-separated
|
|
579
|
-
intent list with a ValidateSet error naming a value nobody typed. It now splits the list itself and still
|
|
580
|
-
rejects a real typo by name. `Invoke-PsadtSandboxTest.ps1 -Paths*` had the same trap with a worse outcome —
|
|
581
|
-
only the first path was asserted and the run still reported GREEN. Six regression tests; suite at 382.
|
|
582
|
-
|
|
583
|
-
### 0.25.0 - 05.09.2026
|
|
584
|
-
- **New: `Get-PsadtMsiFacts.ps1` reads an MSI in one pass** — identity, signature, SHA256, features with
|
|
585
|
-
component counts, *decoded* upgrade flags, shortcuts, directories, file versions, registry rows and the
|
|
586
|
-
Icon table. For an MSI this probe **is** the research: it is what reveals an auto-updater sitting in its
|
|
587
|
-
own feature (so `ADDLOCAL` replaces post-install cleanup), a `DesktopFeature` you must not install, and
|
|
588
|
-
`MigrateFeatures` on the upgrade row — the flag that means `ADDLOCAL` alone is not enough. Five
|
|
589
|
-
regression guards, each verified to fail on its reintroduced bug.
|
|
590
|
-
- **Fixed: the sandbox test left litter and put the evidence in the wrong place.** It kept one work folder
|
|
591
|
-
per app under the config home forever, and `result.json` plus the PSADT logs lived there with the
|
|
592
|
-
manifest pointing into a profile directory. Evidence now lands in
|
|
593
|
-
`<outputRoot>\<Stem>\SandboxTest\` beside the dossier — not in the package folder, which is what
|
|
594
|
-
IntuneWinAppUtil packs — the logs are recorded in `artifacts.logs[]`, and the scratch is removed.
|
|
595
|
-
`-KeepWorkFolder` keeps it, and a failed run keeps it automatically.
|
|
596
|
-
- **Fixed: the test suite wrote into the real config home.** It now redirects `PSADT_DEPLOY_HOME` to a temp
|
|
597
|
-
directory, with a test that asserts it.
|
|
598
|
-
- **Measured:** PuTTY 0.85 packaged with these lessons applied took **13 min 45 s end to end** — versus 75
|
|
599
|
-
minutes for the Notepad++ run that produced them. The largest single factor: the sandbox test costs zero
|
|
600
|
-
wall-clock time when started as soon as pre-flight goes GREEN, because packaging and the dossier do not
|
|
601
|
-
depend on its verdict.
|
|
602
|
-
|
|
603
|
-
### 0.24.0 - 05.09.2026
|
|
604
|
-
- **New: `Invoke-PsadtSandboxTest.ps1` runs the whole Phase 6 loop in a throwaway Windows Sandbox** —
|
|
605
|
-
Install, detection, Uninstall, detection, Reinstall, Repair, final Uninstall, every action as
|
|
606
|
-
`NT AUTHORITY\SYSTEM` via a scheduled task. **No elevation on the host, and the host is never touched**,
|
|
607
|
-
so the SYSTEM test stops being the step that gets deferred to "a DEV VM later". Every action starts from
|
|
608
|
-
a machine that has never seen the app, so a pass cannot be an artefact of the previous run. The verdict
|
|
609
|
-
is keyed on the detection script; package-specific facts go in via `-PathsPresentAfterInstall` /
|
|
610
|
-
`-PathsAbsentAfterInstall` / `-PathsAbsentAfterUninstall`. Verified end to end on Notepad++ 8.9.8 x64:
|
|
611
|
-
GREEN, all seven steps, 5 min 58 s.
|
|
612
|
-
- **Why it is a script and not a snippet:** a hand-rolled version hit three bugs that each destroyed a full
|
|
613
|
-
VM run and each present as a timeout or a null-reference minutes after launch — `echo %ERRORLEVEL%>file`
|
|
614
|
-
silently becoming the `0>` stdin redirection (empty file, never a number), file existence read as
|
|
615
|
-
completion, and `[string]$null` still being `$null` in Windows PowerShell 5.1 (an empty detection output
|
|
616
|
-
is the *normal* result, so the harness crashed because the package was clean). All three now have
|
|
617
|
-
regression guards that were each verified to fail on the reintroduced bug.
|
|
618
|
-
- Phase 6 in SKILL.md and the guide now lead with the sandbox route; the per-action route stays for apps a
|
|
619
|
-
VM cannot host. New anti-patterns cover hand-rolled harnesses, debugging through a long job instead of a
|
|
620
|
-
two-second local check, and "speeding up" the test by disabling Defender or dropping Uninstall/Repair.
|
|
621
|
-
|
|
622
|
-
### 0.23.1 - 04.09.2026
|
|
623
|
-
- **Fixed: two generators were broken since 0.21.0.** `New-BrowserExtensionPackage.ps1` and
|
|
624
|
-
`New-WindowsFeaturePackage.ps1` died at run time — the per-run `LogName` change had wedged a statement
|
|
625
|
-
into the template `Replace(...)` chain, which PowerShell parses as a property assignment with an empty
|
|
626
|
-
name. Valid syntax, so neither the parse check nor the source-inspecting tests could see it; it surfaced
|
|
627
|
-
the first time the whole chain ran against a real package. A guard in all four generator test suites now
|
|
628
|
-
fails on a broken chain, and the guard itself was verified against a broken and a good sample.
|
|
629
|
-
|
|
630
|
-
### 0.23.0 - 04.09.2026
|
|
631
|
-
- **`npx psadt-deploy-skill`.** One line installs or updates the skill into `~/.claude/skills/psadt-deploy`
|
|
632
|
-
and runs the setup doctor. Flags `--dir`, `--project`, `--ref`, `--no-setup`. Cloning to exactly the right
|
|
633
|
-
path by hand was the first thing a new user could get wrong.
|
|
634
|
-
- **Zero dependencies** (Node 18's `fetch` + the `tar.exe` Windows ships). Three acquisition routes:
|
|
635
|
-
update an existing clone, else `git clone --depth 1`, else the branch tarball — because plenty of managed
|
|
636
|
-
machines have no git. The npm package ships only `bin/`; the skill comes from GitHub at install time, so
|
|
637
|
-
a new skill version needs no republish.
|
|
638
|
-
- **The installer never writes the config itself** — it spawns `Set-PsadtConfig.ps1` and
|
|
639
|
-
`Initialize-PsadtSkill.ps1 -Fix`, because a second config-home implementation in JavaScript would drift
|
|
640
|
-
from `Get-PsadtConfig`. `Update-PsadtSkill.ps1` now tracks `package.json` and `bin/` so the archive
|
|
641
|
-
update route stops dropping them. Suite 307 → 326 tests.
|
|
642
|
-
|
|
643
|
-
### 0.22.0 - 04.09.2026
|
|
644
|
-
- **Third-party drivers.** New `scripts/Get-DriverSignatureInfo.ps1` classifies a driver folder before
|
|
645
|
-
anything is built — Microsoft-signed / vendor-signed / unsigned — by checking the **catalog** signature
|
|
646
|
-
rather than the `.sys` (a dual-signed `.sys` reports only its primary signature). New
|
|
647
|
-
`scripts/New-DriverPackage.ps1` builds the package: pnputil staging per INF, uninstall that resolves
|
|
648
|
-
`oemNN.inf` by original name instead of a remembered index, `Get-WindowsDriver` detection.
|
|
649
|
-
- **The rule that saves the most time:** a vendor-signed *kernel* driver is RED, not a warning. With Secure
|
|
650
|
-
Boot on, only Microsoft Dev-Portal-signed kernel drivers load — importing the signer certificate removes
|
|
651
|
-
the "install device software?" prompt but does nothing for Code Integrity, so the driver installs and
|
|
652
|
-
then never loads. Unsigned drivers are refused outright, with three honest options and no testsigning.
|
|
653
|
-
- Pre-flight gained a `DriverTrust` check that fires for **any** package shipping an `.inf` (a vendor
|
|
654
|
-
installer staging a driver is the case nobody declares), the dossier has a driver-trust row, and
|
|
655
|
-
`New-IntuneTrustedCertPolicy.ps1` is now fully self-contained like the firewall script.
|
|
656
|
-
- New guide **Appendix Q** with the decision tree, pnputil exit codes and the installer-bundled-driver
|
|
657
|
-
case. Suite 251 → 307 tests.
|
|
658
|
-
|
|
659
|
-
### 0.21.0 - 04.09.2026
|
|
660
|
-
- **Every package gets a manifest** (`psadt-package.json`): identity, gate decisions, research findings,
|
|
661
|
-
every phase result and the produced artifacts, in one file per app. The generators write it, every phase
|
|
662
|
-
script reads and updates it — so an app's version, name and test evidence stop living in someone's head.
|
|
663
|
-
- **The `.intunewin` is named after the app.** New: `<outputRoot>\<Vendor>_<App>_<Version>_<Arch>\<same
|
|
664
|
-
stem>.intunewin`, produced by the new `scripts/Invoke-PsadtPackage.ps1`. Until now every package came out
|
|
665
|
-
as `Invoke-AppDeployToolkit.intunewin` — that name reached Intune, and concurrent uploads collided in one
|
|
666
|
-
shared temp folder. The new script also verifies the archive before calling it a deliverable and refuses
|
|
667
|
-
an output folder inside the package (which made the tool pack its own previous output).
|
|
668
|
-
- **One PSADT log per run** instead of one ever-growing file:
|
|
669
|
-
`<Vendor>_<App>_<Version>_<Arch>_<Install|Uninstall|Repair>_<timestamp>.log`. PSADT appends to a fixed
|
|
670
|
-
name by default, so by the third attempt a failed install was unreadable.
|
|
671
|
-
- **Pre-flight gained two checks:** a missing or incomplete manifest is RED, a pre-0.21 launcher without a
|
|
672
|
-
per-run log name is a WARN. Report and upload both take their identity from the manifest.
|
|
673
|
-
- Guide: the missing `Phase 6 / 9 / 10` sections now exist, and Appendix E is numbered by phase.
|
|
674
|
-
Suite 173 → 251 tests.
|
|
675
|
-
|
|
676
|
-
### 0.20.0 - 04.09.2026
|
|
677
|
-
- **Intune access is state, not a 403.** New `scripts/Test-PsadtIntuneAccess.ps1` answers *before* Phase 9
|
|
678
|
-
whether the configured app can actually upload, assign groups or create policies — and for how long the
|
|
679
|
-
credential lives. `TokenOk` and every capability are three-valued: verified / refused / **unknown**,
|
|
680
|
-
because Graph tokens are opaque by contract and "we could not tell" is not "not permitted". An offline run
|
|
681
|
-
never overwrites what was verified earlier.
|
|
682
|
-
- **The scripts assert the role they need before their first write** instead of discovering it from a 403
|
|
683
|
-
mid-upload. Group assignment requires *both* group roles and names the missing half.
|
|
684
|
-
- **`New-PsadtEntraApp.ps1` is re-runnable.** It finds the app by the recorded `clientId`, **merges**
|
|
685
|
-
requested permissions instead of replacing them (a run without `-IncludeConfigurationManagement` used to
|
|
686
|
-
silently revoke that role), never prompts, persists what it learned, and only sets `uploadEnabled` once
|
|
687
|
-
consent is really in place. Older client secrets are counted, never deleted.
|
|
688
|
-
- **Auth failures say what to do:** expired/invalid client secret, unknown app or tenant, Conditional Access
|
|
689
|
-
block — and an undecryptable DPAPI secret now explains that DPAPI is bound to the Windows user profile.
|
|
690
|
-
- `references/app-registration.md` is now the single permission matrix (app roles → capabilities → how to
|
|
691
|
-
grant), referenced from the guide instead of duplicated. Suite 128 → 173 tests.
|
|
692
|
-
|
|
693
|
-
### 0.19.0 - 04.09.2026
|
|
694
|
-
- **Setup doctor: `scripts/Initialize-PsadtSkill.ps1`.** One idempotent script replaces the Phase 0 prose
|
|
695
|
-
wizard and reports GREEN/YELLOW/RED over 13 prerequisite checks, each with a concrete fix hint. `-Fix`
|
|
696
|
-
installs the modules, downloads the content-prep tool, fills the EN/DE + tool-path defaults and migrates an
|
|
697
|
-
old setup; `-Set @{...}` persists your values first; `-Json` / `-JsonPath` for other tooling. `.Missing`
|
|
698
|
-
lists only the four values a human has to supply (`paths.packageRoot`, `paths.outputRoot`, `author.person`,
|
|
699
|
-
`author.company`) — never a key the doctor could fill itself.
|
|
700
|
-
- **Config, secret and tools moved to a per-user config home** (`%LOCALAPPDATA%\psadt-deploy\`, override
|
|
701
|
-
`$env:PSADT_DEPLOY_HOME`) instead of the skill folder, so a `git pull`, re-clone or re-install no longer
|
|
702
|
-
takes the whole setup with it — and scripts started from an output folder still find their config.
|
|
703
|
-
`Get-PsadtConfig.ps1` is the single resolver and now returns `.Home` / `.DefaultHome` / `.LegacyInUse`. An
|
|
704
|
-
old config beside `scripts/` keeps working read-only until `-Fix` migrates it (originals renamed
|
|
705
|
-
`*.migrated`, nothing deleted).
|
|
706
|
-
- **`Set-PsadtConfig.ps1 -Remove`** deletes dotted keys, so switching credential type can clean up the
|
|
707
|
-
stale one. **Fixed:** `New-PsadtEntraApp.ps1` reported `<skill>\config.json` even when the config lived
|
|
708
|
-
elsewhere. Suite 120 → 128 tests.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
<details>
|
|
712
|
-
<summary><strong>Earlier releases (0.18.1 and older)</strong></summary>
|
|
713
|
-
|
|
714
|
-
### 0.18.1 - 03.09.2026
|
|
715
|
-
- **Upload: `-MaxRunTimeMinutes`.** `Invoke-IntuneWin32Upload.ps1` can now set
|
|
716
|
-
`installExperience.maxRunTimeInMinutes` (1–1440); `0` (default) omits the field and keeps the service default
|
|
717
|
-
of 60 min. Raise it for long-running installs (OS in-place upgrades, large suites) so the IME does not kill them.
|
|
718
|
-
|
|
719
|
-
### 0.18.0 - 01.07.2026
|
|
720
|
-
- **HanseMerkur corporate design + editorial report redesign.** The dossier/report template is re-themed to the
|
|
721
|
-
HanseMerkur CD (green brand family on a light mint canvas; Metric font stack with Segoe fallback and no
|
|
722
|
-
web-font fetch → no CORS console errors on a local `file://` open) and relaid out as an "editorial
|
|
723
|
-
data-report": flat hairline sections, auto-numbered headings (`01…13`), an at-a-glance KPI band under the hero
|
|
724
|
-
(version · pre-flight · min OS · arch), and a wider 1600px layout. The detection script is folded behind a
|
|
725
|
-
collapsed `<details>` (the rule summary stays visible). German report text now uses real umlauts. Fixed the
|
|
726
|
-
sticky-header flicker (Chrome/Edge scroll-anchoring vs. the condensing hero → `overflow-anchor: none`,
|
|
727
|
-
Playwright-verified) and removed the redundant hero status pill.
|
|
728
|
-
|
|
729
|
-
### 0.17.0 - 01.07.2026
|
|
730
|
-
- **install4j fingerprint + behavioral silent-switch verification.** Appendix L.1 now recognises install4j
|
|
731
|
-
(Java) installers (`com/install4j/runtime`, `exe4j`, `i4jparams.conf`, bundled `jre\`) and records that `/S`
|
|
732
|
-
is NOT its switch (it hangs on the language dialog) — the unattended switch is `-q`, run elevated. New BINDING
|
|
733
|
-
rule: a single string match is a hint, not proof; confirm the engine by its definitive fingerprint AND run the
|
|
734
|
-
silent switch once (timeout+kill, expect exit 0, no dialog) before packaging. Appendix L.3 adds the
|
|
735
|
-
trademark-sign gotcha (`Name(R)` breaks `-match 'Name'` → tolerant regex); Appendix B adds anti-patterns 13–15.
|
|
736
|
-
(Driven by an Aperio install4j installer misidentified as NSIS, where `/S` hung on the language dialog.)
|
|
737
|
-
|
|
738
|
-
### 0.16.0 - 29.06.2026
|
|
739
|
-
- **Dossier auto-sync convention (BINDING)** + report header layout fix. Any change to the package scripts
|
|
740
|
-
(launcher, Extensions, detection, version/changelog, return codes, re-packaging) now requires regenerating
|
|
741
|
-
`Intune-Dossier.html` in the same pass; a stale dossier is a defect. The `.pill-lg` status badge caps at 230px
|
|
742
|
-
and wraps so a long status no longer overlaps the hero title.
|
|
743
|
-
|
|
744
|
-
### 0.15.2 - 15.06.2026
|
|
745
|
-
- **Follow-up doc fix.** A contradiction sweep after 0.15.1 caught one more stale "Phase 7.5" in
|
|
746
|
-
`New-PsadtReport.ps1` help (upload is Phase 9); corrected. No other live stale references remain.
|
|
747
|
-
|
|
748
|
-
### 0.15.1 - 15.06.2026
|
|
749
|
-
- **Generator hardening from a self-review (correctness + security).** All three generators now single-quote-escape
|
|
750
|
-
values embedded in `$adtSession` literals, so an apostrophe in the App name/vendor/author (e.g. "Bob's App",
|
|
751
|
-
"L'Oreal") no longer produces an unparseable package; the MSI `-AdditionalArgumentList` / `ProcessesToClose`
|
|
752
|
-
literals are escaped too (also closing a SYSTEM code-injection path). Detection exit-code drift fixed:
|
|
753
|
-
`New-MsiPackage.ps1` + the WinGet example now `exit 0` for "not installed" (a non-zero exit reads as a detection
|
|
754
|
-
error), and a new **pre-flight Detection check** WARNs on a non-zero exit in `Detect*.ps1`. The WSUS bypass in
|
|
755
|
-
`New-WindowsFeaturePackage.ps1` now saves all prior state before writing and runs inside the `try/finally`, so a
|
|
756
|
-
partial failure can't leave `UseWUServer=0` permanently. Added input guards (`$Name` path-traversal, `__TOKEN__`
|
|
757
|
-
leak), MSI `-Author` config fallback + `-InstallerPath` validation. Stale refs fixed (SKILL.md "A-M"->"A-P",
|
|
758
|
-
`New-PsadtEntraApp.ps1` "Phase 7.5"->"Phase 9").
|
|
759
|
-
|
|
760
|
-
### 0.15.0 - 15.06.2026
|
|
761
|
-
- **Windows-feature packages (optional features + capabilities / FoD).** New `scripts/New-WindowsFeaturePackage.ps1`
|
|
762
|
-
— one-call generator that enables Windows **Optional Features** (`Enable-WindowsOptionalFeature`: NetFx3,
|
|
763
|
-
Hyper-V, WSL, TelnetClient, …) and **Capabilities / Features on Demand** (`Add-WindowsCapability`: RSAT.*,
|
|
764
|
-
OpenSSH, …) from one typed list, multiple per package. Uninstall reverts (disable/remove); Repair re-enables
|
|
765
|
-
(idempotent). Reboot surfaces **3010** via `$adtSession.SetExitCode(3010)` (`-NoRestart`); detection treats
|
|
766
|
-
`EnablePending` as not-yet-done. Content comes from a bundled `-Source` (offline SxS) else Windows Update
|
|
767
|
-
behind a **temporary** WSUS bypass (`RepairContentServerSource=2`, `UseWUServer=0`) whose exact prior state is
|
|
768
|
-
restored. Guide **Appendix P**, SKILL.md Gate-1/anti-patterns/ref-lookup. Pre-flight GREEN; helper logic
|
|
769
|
-
verified against an in-memory registry sim; ASCII-clean.
|
|
770
|
-
|
|
771
|
-
### 0.14.0 - 15.06.2026
|
|
772
|
-
- **Browser-extension force-install packages (Edge / Chrome / Firefox).** New
|
|
773
|
-
`scripts/New-BrowserExtensionPackage.ps1` — one-call generator for force-installing browser extensions via
|
|
774
|
-
enterprise **policy registry keys** (policy-only, no installer, ESP-safe). Multiple extensions per package.
|
|
775
|
-
Chromium helper computes the **next free `ExtensionInstallForcelist` index** (never hard-codes `1`), dedupes by
|
|
776
|
-
ID and removes only its own entry (coexistence); Firefox merges into the single `ExtensionSettings` JSON written
|
|
777
|
-
as **`REG_MULTI_SZ`** (single-line `REG_SZ` is silently ignored — Mozilla bug 1750233). Guide **Appendix O**,
|
|
778
|
-
SKILL.md Gate-1/anti-patterns/ref-lookup. Pre-flight GREEN; helpers validated against a scratch registry hive;
|
|
779
|
-
ASCII-clean.
|
|
780
|
-
|
|
781
|
-
### 0.13.1 - 15.06.2026
|
|
782
|
-
- **Firewall policy body fixed against the live template (verified 201).** `New-IntuneFirewallPolicy.ps1`
|
|
783
|
-
produced a body Graph rejected (400). Corrected via the **msgraph skill** (not guessed): the group id needs
|
|
784
|
-
the `{firewallrulename}` token, the program path is the direct child `..._app_filepath`, action values are
|
|
785
|
-
`_action_type_1`/`_0`, and a template-based policy requires `settingInstanceTemplateReference` per instance +
|
|
786
|
-
`settingValueTemplateReference` per simple/choice value (profiles collection: instance ref only — a per-value
|
|
787
|
-
ref is a duplicate). Confirmed by a live **201 Create**; tests assert the references. Mirrored into the
|
|
788
|
-
MxManagementCenter Output deliverable.
|
|
789
|
-
|
|
790
|
-
### 0.13.0 - 15.06.2026
|
|
791
|
-
- **Self-contained firewall deliverable (copy-to-client safe).** `scripts/New-IntuneFirewallPolicy.ps1` is now
|
|
792
|
-
fully self-contained — no dot-sourcing of `_GraphCommon`/`_GraphInteractive`, no skill path; WAM sign-in +
|
|
793
|
-
policy body builder + console helpers are embedded. It runs on a test client that does **not** have the skill
|
|
794
|
-
installed (`-Interactive` WAM, or `-GraphToken`). Fixes the "Skill script not found … -SkillRoot" failure when
|
|
795
|
-
the deliverable was copied to another machine. New **binding SKILL.md convention "Self-contained deliverables"**
|
|
796
|
-
+ a Pester test that enforces it (no dot-source / no skill path / embeds WAM). Test-first per writing-skills.
|
|
797
|
-
|
|
798
|
-
### 0.12.0 - 15.06.2026
|
|
799
|
-
- **Interactive WAM sign-in for the Intune policy scripts.** `New-IntuneFirewallPolicy.ps1` and
|
|
800
|
-
`New-IntuneTrustedCertPolicy.ps1` gain `-Interactive` (+ `-TenantId`): delegated sign-in via **WAM**
|
|
801
|
-
(Windows Web Account Manager) when there is no app registration — **no device code**. The WAM machinery
|
|
802
|
-
(`Initialize-MsalBroker` / `Get-WamToken` / new `Get-InteractiveGraphToken`) was extracted from
|
|
803
|
-
`New-PsadtEntraApp.ps1` into a shared `scripts/_GraphInteractive.ps1` (one implementation, no copy-paste
|
|
804
|
-
drift); the bootstrap now consumes it. The MxManagementCenter firewall deliverable became a thin wrapper
|
|
805
|
-
over the generic script.
|
|
806
|
-
|
|
807
|
-
### 0.11.0 - 15.06.2026
|
|
808
|
-
- **Intune firewall-rules policy + app config-management permission.** New `scripts/New-IntuneFirewallPolicy.ps1`
|
|
809
|
-
(Endpoint Security "Windows Firewall Rules" policy, one program-scoped rule; dry-run / `-Execute` / manual
|
|
810
|
-
portal fallback) + Pester test. Suppresses the first-run Windows Firewall prompt for apps that listen inbound.
|
|
811
|
-
New `New-PsadtEntraApp.ps1 -IncludeConfigurationManagement` consents `DeviceManagementConfiguration.ReadWrite.All`
|
|
812
|
-
(needed by the firewall and trusted-cert policies for `-Execute`).
|
|
813
|
-
|
|
814
|
-
### 0.10.0 - 15.06.2026
|
|
815
|
-
- **Certificate store deployment (driver-trust / TrustedPublisher).** New `scripts/New-IntuneTrustedCertPolicy.ps1` —
|
|
816
|
-
a Custom OMA-URI profile that places a certificate into a Windows machine store via the
|
|
817
|
-
`RootCATrustedCertificates` CSP (the policy-based way to suppress the Windows "install device software?"
|
|
818
|
-
driver-trust prompt). Guide Appendix N, dossier "Treiber-Zertifikat" row, SKILL.md convention + Pester test.
|
|
819
|
-
|
|
820
|
-
### 0.9.2 - 12.06.2026
|
|
821
|
-
- **Reconciled a diverged install copy back into the repo.** Fixed `Invoke-PsadtSystemTest.ps1` crashing at
|
|
822
|
-
param binding under the WinPS 5.1 re-exec (`$SkillRoot` default is now fail-safe, so the SYSTEM Install/
|
|
823
|
-
Uninstall gate works on a pwsh-7 host). Added per-field copy buttons + a `file://`-safe clipboard to the
|
|
824
|
-
HTML dossier (`Report-Template.html`, token set unchanged). Added `scripts/New-MsiPackage.ps1` (reusable
|
|
825
|
-
MSI package generator, `$PSScriptRoot`-relative, ASCII-only) + its Pester test.
|
|
826
|
-
|
|
827
|
-
### 0.9.1 - 12.06.2026
|
|
828
|
-
- **Applicability/portability drift cleanup** (docs + instructions; no script logic changed). Removed the
|
|
829
|
-
phantom `test.maxIterations` / `test.endState` config keys from SKILL.md Phase 6 (the cap is a hard count of
|
|
830
|
-
5 the orchestrator owns); fixed stale "Phase 7.5" -> **Phase 9** in SKILL.md + `app-registration.md`; fixed
|
|
831
|
-
the README project tree (report **Phase 8**, added the 3 missing scripts `Invoke-PsadtPreflight`,
|
|
832
|
-
`Invoke-IntuneAppAssignment`, `_GraphCommon`).
|
|
833
|
-
- **`superpowers` downgraded from hard `REQUIRED` to optional/preferred.** The Researcher/Reviewer roles now
|
|
834
|
-
prefer `superpowers:*` if installed and otherwise fall back to the native Agent tool / `/code-review`; the
|
|
835
|
-
Requirements list documents it as an optional (recommended) enhancement. The workflow no longer depends on it.
|
|
836
|
-
|
|
837
|
-
### 0.9.0 - 11.06.2026
|
|
838
|
-
- **Audit cleanup** (quality / content / applicability+compatibility / tests). Highlights: shared
|
|
839
|
-
`scripts/_GraphCommon.ps1` (de-duplicates the 3 Graph scripts) + **28 new Pester tests** for the previously
|
|
840
|
-
untested upload/assignment/Entra-app/token scripts (suite now 74); fixed an `Invoke-WithRetry` precedence
|
|
841
|
-
bug (retried every error 6x) and PS7-fragile throttling reads; the HTML report no longer shows synthetic
|
|
842
|
-
"passed" rows when no pre-flight/SYSTEM-test results are supplied (neutral "not run") and derives the PSADT
|
|
843
|
-
version from the installed module; GUID `ValidatePattern` on the MSI codes.
|
|
844
|
-
- **Phase numbering unified** across SKILL.md + guide into one integer scheme **0-12**; every Phase/Appendix
|
|
845
|
-
cross-reference re-verified. Anti-pattern list trimmed; SYSTEM-test prerequisites, `/beta` drift caveat,
|
|
846
|
-
rollback step, logging convention, and config help added. Guide `$adtSession` template `1.0.0`->`0.1` +
|
|
847
|
-
author-from-config; intro appendix index -> A-M.
|
|
848
|
-
|
|
849
|
-
### 0.8.1 - 11.06.2026
|
|
850
|
-
- **Docs consistency.** Fixed a stale cross-reference in SKILL.md (the guide range said **Appendix A-J** but
|
|
851
|
-
the guide now runs through **M** — K/L were added in 0.7.0 and M in 0.8.0 without updating it). Restored the
|
|
852
|
-
**0.5.3** entry that was missing from this README changelog mirror (it was present in `CHANGELOG.md`).
|
|
853
|
-
|
|
854
|
-
### 0.8.0 - 11.06.2026
|
|
855
|
-
- **Opt-in Entra group assignment, wired end-to-end.** New Phase 10 + `Invoke-IntuneAppAssignment.ps1`:
|
|
856
|
-
create/reuse Entra security groups by a configured naming scheme (`intune.groups`) and assign the uploaded
|
|
857
|
-
app (Required / Available / Uninstall). Read-only dry-run → confirm → execute; idempotent; never deletes a
|
|
858
|
-
group or another app's assignment; ambiguous/duplicate names skipped. Least-privilege roles
|
|
859
|
-
(`Group.Create` + `GroupMember.Read.All`) via `New-PsadtEntraApp.ps1 -IncludeGroupManagement`. Full
|
|
860
|
-
reference in **guide Appendix M** (config schema, naming tokens, version-independent default vs `%version%`
|
|
861
|
-
opt-in, permission model).
|
|
862
|
-
- **Upload min-OS fix.** `-MinWindowsRelease` is now a `ValidateSet` of backend-accepted release IDs
|
|
863
|
-
(`1607..2004`) — `21H2`/`22H2` are server-rejected and used to kill the upload mid-flight with a Graph
|
|
864
|
-
`BadRequest`. Fails fast at param binding instead; set a higher minimum in the portal. Guide **H.11**.
|
|
865
|
-
|
|
866
|
-
### 0.7.5 - 10.06.2026
|
|
867
|
-
- **Honest exit codes + detection (correctness fix).** Removed the dangerous "always `exit 0`" guidance from
|
|
868
|
-
guide Appendix K — a blanket `exit 0` (or a detection tag written in a `finally`) reports GREEN on failure.
|
|
869
|
-
New **K.7**: the exit code reflects whether the fix could RUN (couldn't-run -> non-zero; the 64-bit relaunch
|
|
870
|
-
propagates the child's exit code), detection reflects the real END-STATE (tag only on success), with a
|
|
871
|
-
per-package decision table; "never block enrollment" is now an explicit ESP-assignment + return-code-mapping
|
|
872
|
-
choice, not a masked exit code. SKILL.md anti-pattern added.
|
|
873
|
-
|
|
874
|
-
### 0.7.0 - 10.06.2026
|
|
875
|
-
- **Value-adding extensions.** New `scripts/Invoke-PsadtPreflight.ps1` turns the Phase-5 Reviewer gate into one
|
|
876
|
-
deterministic `GREEN/RED` tool (encoding/parse/v3-scan/top-level/structure/GUID-to-`-FilePath`), with a Pester
|
|
877
|
-
suite. New guide **Appendix K** (script-only remediation / fix packages, ESP-safe — the debloat/Cisco pattern)
|
|
878
|
-
and **Appendix L** (installer technologies + silent switches, a lookup consulted before web research). Expanded
|
|
879
|
-
error-code catalogue (MSI 1603/1605/1619/1638/1639…, PSADT 60001/60008 + ranges) in guide Appendix A and the
|
|
880
|
-
SKILL.md troubleshooting table. SKILL.md rewired to point at the pre-flight script and the new appendices.
|
|
881
|
-
|
|
882
|
-
### 0.6.2 - 10.06.2026
|
|
883
|
-
- **Audit & harden.** Agent-based audit + source-level verification (discarded ~8 false positives). Fixes: the
|
|
884
|
-
guide's broken `New-ADTTemplate` "Extended scaffold" (passing app metadata params that v4.1.x rejects);
|
|
885
|
-
the Graph uploader leaving its extracted work dir (with the AES keys in `Detection.xml`) in `%TEMP%` (now
|
|
886
|
-
`try/finally` cleanup); the report `Notes` default `·` double-escape; the fallback initials-SVG logo
|
|
887
|
-
now XML-escapes + base64-encodes (no markup injection, with a regression test). Robustness: `Invoke-Graph`
|
|
888
|
-
429/5xx retry with `Retry-After`; malformed-`config.json` safety in four scripts; WinGet 2-byte header read;
|
|
889
|
-
symmetric temp cleanup in self-update. Graph request shapes left untouched.
|
|
890
|
-
|
|
891
|
-
### 0.6.1 - 10.06.2026
|
|
892
|
-
- **Report header flicker fixed** (`references/Report-Template.html`): at widths where the content height met
|
|
893
|
-
the viewport edge, the vertical scrollbar toggled on/off and the header's `vw`-based `clamp()` padding and
|
|
894
|
-
`h1` font-size reflowed on every toggle — a wild flicker loop. Reserving the scrollbar gutter
|
|
895
|
-
(`html { overflow-y: scroll; scrollbar-gutter: stable; }`) keeps the width constant and breaks the loop.
|
|
896
|
-
|
|
897
|
-
### 0.6.0 - 10.06.2026
|
|
898
|
-
- **SKILL.md slimmed to a control plane** (733 → 244 lines, ~67% fewer tokens) via progressive disclosure:
|
|
899
|
-
the long inline code moved into the reference guide (new **Appendix I** WinGet + **Appendix J** app-logo),
|
|
900
|
-
loaded on demand. Intake restructured into **4 decision gates** (researchable facts become stated
|
|
901
|
-
assumptions, not questions); explicit **sub-agent roles** (Researcher×3 / Builder / Reviewer) with GREEN
|
|
902
|
-
handoff gates; a single **blockade protocol** for errors. No binding rule or behaviour dropped.
|
|
903
|
-
|
|
904
|
-
### 0.5.3 - 09.06.2026
|
|
905
|
-
- **Guide code-fences are now English/ASCII.** Anglicized every German comment, string literal and placeholder
|
|
906
|
-
living **inside** PowerShell/text code fences in the guide (and the inline-code placeholders in the Appendix
|
|
907
|
-
F.1 table) — snippets get copied verbatim into deployment scripts, where the binding rule is English + 7-bit
|
|
908
|
-
ASCII. German explanatory **prose** and the **F.2 Company-Portal dossier template** deliberately stay German
|
|
909
|
-
(legitimate `language.dossier` end-user text). No script/tooling code changed.
|
|
910
|
-
|
|
911
|
-
### 0.5.2 - 08.06.2026
|
|
912
|
-
- **HTML package report is now always generated** (upload or not) by `scripts/New-PsadtReport.ps1` from the
|
|
913
|
-
fixed template `references/Report-Template.html`. One self-contained, **bilingual (DE/EN toggle)** document
|
|
914
|
-
combining the Intune dossier + a technical package report; Fluent-2 styled, sticky shrink header, logo
|
|
915
|
-
embedded as a data URI, description preview rendered from its Markdown source. New Pester test
|
|
916
|
-
`tests/New-PsadtReport.Tests.ps1`.
|
|
917
|
-
|
|
918
|
-
### 0.5.1 - 06.06.2026
|
|
919
|
-
- Self-update now decides by **commit** (git `HEAD` vs `origin/main`, or the GitHub commits-API sha vs a
|
|
920
|
-
recorded `tooling.skillCommit`) instead of the CHANGELOG version — no more CDN lag / circular version reads.
|
|
921
|
-
- README project-structure tree compacted so it renders without horizontal scroll.
|
|
922
|
-
|
|
923
|
-
### 0.5.0 - 06.06.2026
|
|
924
|
-
- **Skill self-update** — `scripts/Update-PsadtSkill.ps1` checks GitHub for a newer version, shows what's new,
|
|
925
|
-
and updates in place on confirmation (`git pull` for a clone, else branch-zip overwrite of tracked files
|
|
926
|
-
only; `config.json` / `secret.dpapi` / `tools/` preserved). Triggers: *"update skill"*, *"/update-skill"*,
|
|
927
|
-
*"psadt update"*.
|
|
928
|
-
|
|
929
|
-
### 0.4.0 - 06.06.2026
|
|
930
|
-
- **WinGet packaging support** (strictly opt-in, never the default) + **certificate-based auth** for the Phase 9
|
|
931
|
-
upload (no secret at rest) + MSI icon-table logo fallback + device-code first-poll fix. Contributed by
|
|
932
|
-
**@joakim-i** (PR #4), reviewed and hardened before merge. See [CHANGELOG.md](CHANGELOG.md).
|
|
933
|
-
|
|
934
|
-
### 0.3.2 - 06.06.2026
|
|
935
|
-
- **Test-before-upload is now a binding gate:** Install + Uninstall must pass the Phase 6 SYSTEM test before
|
|
936
|
-
any Phase 9 upload. If it can't be run (no elevation / VM), stop before upload and hand back the command.
|
|
937
|
-
|
|
938
|
-
### 0.3.1 - 06.06.2026
|
|
939
|
-
- `Invoke-IntuneWin32Upload.ps1` gains **`-DetectionScriptPath`** (PowerShell-script detection rule) for
|
|
940
|
-
EXE / non-MSI installers without a ProductCode (e.g. Vivaldi). Verified live by uploading Vivaldi 8.0.4033.44.
|
|
941
|
-
- Lesson: a *detection* script rule accepts only `ruleType,enforceSignatureCheck,runAs32Bit,scriptContent`
|
|
942
|
-
(guide Appendix H.2).
|
|
943
|
-
|
|
944
|
-
### 0.3.0 - 06.06.2026
|
|
945
|
-
- **Direct upload** (`scripts/Invoke-IntuneWin32Upload.ps1`, Phase 9): self-contained raw-Graph
|
|
946
|
-
`win32LobApp` upload (parse `.intunewin` → token → probe → idempotency → create/update → content → SAS
|
|
947
|
-
block-blob upload via HttpClient → commit → activate → categories → supersedence). Read-only dry-run by
|
|
948
|
-
default; `-Execute` to write.
|
|
949
|
-
- **WAM Entra-app bootstrap** (`scripts/New-PsadtEntraApp.ps1`): interactive Windows-broker sign-in (device
|
|
950
|
-
code fallback), creates the app + admin consent + secret, DPAPI-stored.
|
|
951
|
-
- **App-only token helper** (`scripts/Get-GraphToken.ps1`).
|
|
952
|
-
- **Coexistence-safe versioning:** never deletes an older version; new versions coexist; optional
|
|
953
|
-
supersedence wiring. **Logo guard:** refuses the PSADT default `AppIcon.png`. Fills the full
|
|
954
|
-
App-information tab; never auto-assigns category/notes/groups.
|
|
955
|
-
- Fixed the Repair `-FilePath`→`-ProductCode` example; reference guide gains **Appendix H**.
|
|
956
|
-
|
|
957
|
-
### 0.2.0 - 05.06.2026
|
|
958
|
-
- **Automated SYSTEM test loop** (`scripts/Invoke-PsadtSystemTest.ps1`, Phase 6): install → uninstall →
|
|
959
|
-
reinstall the package as the SYSTEM account via `Invoke-CommandAs`, with agent-driven auto-fix until
|
|
960
|
-
green or a max-iteration cap. Opt-in; elevated session required.
|
|
961
|
-
- Phase 8 now prefers `Invoke-CommandAs -AsSystem` for SYSTEM-context testing (PsExec kept as a fallback).
|
|
962
|
-
|
|
963
|
-
### 0.1.0 - 04.06.2026
|
|
964
|
-
- Initial release: guided PSADT v4 → Intune Win32 lifecycle (intake, autonomous research, scaffolding, all
|
|
965
|
-
three deployment types, pre-flight checks, packaging, dossier + logo, guided testing, troubleshooting).
|
|
966
|
-
- First-run setup writing a machine-local `config.json` (paths, language, author).
|
|
967
|
-
- Self-healing prerequisites: PSAppDeployToolkit module (PSGallery) and `IntuneWinAppUtil.exe`
|
|
968
|
-
(auto-download + version check).
|
|
969
|
-
- HTML dossier document with a Markdown app-description block (the Intune description field is
|
|
970
|
-
Markdown-only).
|
|
971
|
-
- English skill + reference guide; MIT licensed.
|
|
972
|
-
|
|
973
|
-
</details>
|
|
428
|
+
The two most recent releases are below. **[CHANGELOG.md](CHANGELOG.md)** carries the complete history,
|
|
429
|
+
every release since 0.1.0, and nothing is ever removed from it - this section is a window onto it, not a
|
|
430
|
+
second copy to keep in sync.
|
|
431
|
+
|
|
432
|
+
### 0.28.0 - 2026-09-11
|
|
433
|
+
- **Fixed: a space in the `.wsb` path silently disabled every custom mapped folder.** `Start-Process
|
|
434
|
+
-ArgumentList` does not quote its elements, so Windows Sandbox booted with the built-in shares only -
|
|
435
|
+
no error, no warning. A username with a space in it is enough, and it reads exactly like an upstream
|
|
436
|
+
Sandbox bug.
|
|
437
|
+
- **Fixed: `<LogonCommand>` never ran** on the affected Sandbox app version
|
|
438
|
+
([#125](https://github.com/microsoft/Windows-Sandbox/issues/125)). The work folder is now mapped onto
|
|
439
|
+
the guest's Startup folder and a trigger `.cmd` starts the runner, which lives one level down because
|
|
440
|
+
Startup auto-executes only `.exe/.bat/.cmd/.lnk/.vbs`.
|
|
441
|
+
- **Fixed: a transient read reported a real result as empty** - a detection step captured `stdout: ""`
|
|
442
|
+
while the same file, re-read at the end of the run, held the right answer. The read now retries.
|
|
443
|
+
- **Changed: `schtasks` failures are checked** instead of surfacing as a 900-second timeout, and the
|
|
444
|
+
runner verifies it is elevated before the first action - a Startup item does not carry the full admin
|
|
445
|
+
token by construction the way `<LogonCommand>` did.
|
|
446
|
+
- **Added: NSIS MultiUser needs an explicit `/allusers` or `/currentuser`** (App. L.7). A bare `/S`
|
|
447
|
+
exits in under a second with no output and nothing installed. Now a Gate 2 decision.
|
|
448
|
+
- **Added: an unbundled runtime prerequisite is researched in Phase 2 and decided at Gate 1**, and a
|
|
449
|
+
manual interactive test is offered after a GREEN Phase 6 - the loop proves the package works, never
|
|
450
|
+
that the app does. Suite 484 -> 493.
|
|
451
|
+
### 0.27.1 - 2026-09-10
|
|
452
|
+
- **Fixed: the dossier invented facts about the package and printed them as statements.** Found while
|
|
453
|
+
packaging two real apps to test 0.27.0. Without `-Metadata`, the report claimed `_Beschreibung folgt._`
|
|
454
|
+
as the Company-Portal text — which is copied into Intune verbatim and reads like a finished field —
|
|
455
|
+
plus `Start-ADTMsiProcess` and "Nutzerdaten bleiben erhalten" as the hook contents, for whatever package
|
|
456
|
+
happened to be reported on. A WinMerge package that only ever calls `Start-ADTProcess` with Inno Setup
|
|
457
|
+
switches was described four times as using a cmdlet it never touches. Nothing marked any of it as a guess.
|
|
458
|
+
- **Hooks and the cmdlet list are now read out of the real launcher by AST**, per `*-ADTDeployment`
|
|
459
|
+
function. No launcher to read means `nicht ermittelbar / not derivable` instead of a plausible list. An
|
|
460
|
+
explicit `-Metadata` value still wins.
|
|
461
|
+
- **A missing description warns and is marked visibly — and is refused outright when
|
|
462
|
+
`decisions.upload = true`**, in the same shape as the existing SYSTEM-test gate.
|
|
463
|
+
`-AllowMissingDescription` is the deliberate, visible opt-out.
|
|
464
|
+
- **The header status is derived from the evidence** instead of defaulting to `Upload-bereit - getestet`.
|
|
465
|
+
- **SKILL.md Phase 8** now says the description is mandatory; before, it only said how to format it.
|
|
466
|
+
Suite 474 → 484.
|