Skip to content

Commit efc8f5a

Browse files
authored
Merge pull request #41 from fadwen/release/v0.33.0
release: 0.33.0
2 parents b0c1075 + ea71620 commit efc8f5a

6 files changed

Lines changed: 69 additions & 20 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,28 @@ release notes.
1111

1212
## [Unreleased]
1313

14+
## [0.33.0] - 2026-10-15
15+
16+
Fixes to the CI pieces, found by running the gate script, the workflow template, the suite template
17+
and the SARIF export against a repository laid out the way the templates describe. The gate leaves
18+
out the two kinds of file the suite template puts under the script folders, the Pester suite and a
19+
Win32 app's package content, so neither fails a build for findings that do not apply to it; the
20+
SARIF export describes the policy rules and no longer throws on a policy check; the templates work
21+
on Windows on ARM and use current action versions. No verdict changes.
22+
1423
### Fixed
1524

1625
- `Examples/Invoke-IntuneScriptGate.ps1` analyzed a Pester suite placed next to the scripts, where
1726
`Examples/IntuneScripts.Tests.ps1.template` puts it, and reported its `Import-Module
1827
IntuneScriptLab` as an `IslModuleDependency` warning, which failed a build at `-FailOn Warning`.
1928
Folders are searched by the gate now and `*.Tests.ps1` files are left out; a suite named directly
2029
on `-Path` is still analyzed.
30+
- The gate also analyzed the contents of a Win32 app's `Package` folder (`Win32\<app>\Package\`,
31+
what becomes the `.intunewin`), and an `install.ps1` there, which the agent runs through the
32+
install command as SYSTEM, was read as a user-context platform script: every machine-wide write
33+
became an `IslContextIssue` warning, and the build failed at `-FailOn Warning`. Files under a
34+
`Package` folder are left out of a folder search; a `Packages` folder, which holds Win32 apps,
35+
stays in, and a file named directly on `-Path` is still analyzed.
2136
- The gate's GitHub annotations percent-encode the `file=` and `title=` values as well as the
2237
message, so a script outside `-Root`, whose path stays absolute, no longer ends the property list
2338
at its drive letter.
@@ -659,7 +674,8 @@ Nothing any command does has changed.
659674

660675
- Static rules: `Test-IntuneScript`.
661676

662-
[Unreleased]: https://github.com/fadwen/IntuneScriptLab/compare/v0.32.0...HEAD
677+
[Unreleased]: https://github.com/fadwen/IntuneScriptLab/compare/v0.33.0...HEAD
678+
[0.33.0]: https://github.com/fadwen/IntuneScriptLab/compare/v0.32.0...v0.33.0
663679
[0.32.0]: https://github.com/fadwen/IntuneScriptLab/compare/v0.31.0...v0.32.0
664680
[0.31.0]: https://github.com/fadwen/IntuneScriptLab/compare/v0.30.0...v0.31.0
665681
[0.30.0]: https://github.com/fadwen/IntuneScriptLab/compare/v0.29.0...v0.30.0

‎Examples/Invoke-IntuneScriptGate.ps1‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
2424
.PARAMETER Path
2525
Folders or scripts to analyze; folders are searched for .ps1 files recursively, leaving out
26-
Pester suites (*.Tests.ps1), which the suite template places next to the scripts. A suite
27-
named directly is analyzed. Default: the current directory.
26+
Pester suites (*.Tests.ps1), which the suite template places next to the scripts, and the
27+
contents of a Win32 app's Package folder (Win32\<app>\Package\, what becomes the .intunewin),
28+
which the agent runs through the install command rather than as a script. A file named
29+
directly is analyzed. Default: the current directory.
2830
2931
.PARAMETER FailOn
3032
The lowest severity that fails the build: Error (default), Warning, Information, or None
@@ -155,14 +157,21 @@ function ConvertTo-AnnotationProperty {
155157
(ConvertTo-AnnotationText -Text $Text).Replace(':', '%3A').Replace(',', '%2C')
156158
}
157159

158-
# Folders are searched here rather than by Test-IntuneScript, so that a Pester suite next to the
159-
# scripts (IntuneScripts.Tests.ps1, where the suite template puts it) is not analyzed as an Intune
160-
# script; a suite named directly on -Path still is
160+
# Folders are searched here rather than by Test-IntuneScript, so that two kinds of file the suite
161+
# template puts under the script folders are not analyzed as Intune scripts: a Pester suite next to
162+
# the scripts (IntuneScripts.Tests.ps1) and the contents of a Win32 app's Package folder
163+
# (Win32\<app>\Package\), which become the .intunewin and run through the install command as
164+
# SYSTEM, where an install.ps1 would otherwise be read as a user-context platform script. A file
165+
# named directly on -Path is still analyzed. Only the singular segment 'Package' is left out: a
166+
# 'Packages' folder is one that holds Win32 apps, and their detection scripts stay in.
161167
$scriptFiles = @(foreach ($item in $Path) {
162168
foreach ($resolved in (Resolve-Path -Path $item)) {
163169
if (Test-Path -LiteralPath $resolved.ProviderPath -PathType Container) {
164170
Get-ChildItem -LiteralPath $resolved.ProviderPath -Recurse -Filter *.ps1 -File |
165-
Where-Object { $_.Name -notlike '*.Tests.ps1' } | ForEach-Object { $_.FullName }
171+
Where-Object {
172+
$_.Name -notlike '*.Tests.ps1' -and
173+
"$($_.DirectoryName)\" -notmatch '(?i)[\\/]Package[\\/]'
174+
} | ForEach-Object { $_.FullName }
166175
}
167176
else { $resolved.ProviderPath }
168177
}

‎Examples/intune-script-gate.yml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ env:
2727
# Folders holding the scripts: remediations, platform scripts, Win32 detection and requirement
2828
# scripts. Folder and file names tell the analysis what each script is (Remediations\<name>\
2929
# Detect.ps1, Win32\<app>\Detect.ps1, PlatformScripts\*.ps1); a directive comment overrides.
30-
# Pester suites under them (*.Tests.ps1) are left out of the analysis.
30+
# Pester suites under them (*.Tests.ps1) and the contents of a Win32 app's Package folder
31+
# (Win32\<app>\Package\, what becomes the .intunewin) are left out of the analysis.
3132
SCRIPT_PATHS: ./Intune
3233
# Error fails the build; Warning is stricter; None reports only
3334
FAIL_ON: Error

‎IntuneScriptLab.psd1‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@{
22
# Module manifest for IntuneScriptLab
33
RootModule = 'IntuneScriptLab.psm1'
4-
ModuleVersion = '0.32.0'
4+
ModuleVersion = '0.33.0'
55
GUID = '3f6b2c9e-7d41-4a8f-9c2b-5e0d8a1f4b76'
66
Author = 'Jeffrey Stuhr'
77
CompanyName = ''
@@ -64,6 +64,16 @@ pre-flight over the tenant's deployed scripts and readers for the agent's logs
6464
LicenseUri = 'https://github.com/fadwen/IntuneScriptLab/blob/main/LICENSE'
6565
ProjectUri = 'https://github.com/fadwen/IntuneScriptLab'
6666
ReleaseNotes = @'
67+
0.33.0 - The CI pieces, after a run against a repository laid out the way the templates describe.
68+
The gate script no longer analyzes a Pester suite next to the scripts or the contents of a
69+
Win32 app's Package folder, both of which the suite template puts there and both of which
70+
failed a build at -FailOn Warning for findings that do not apply to them; its GitHub
71+
annotations percent-encode the file and title values as well as the message.
72+
Export-IntuneFindingSarif describes the assignment, filter and schedule rules, gives a
73+
mixed-severity rule the level of its worst finding, and writes a policy check, which has no
74+
script behind it, as a result without a location instead of throwing. The workflow template
75+
uses checkout@v7 and upload-sarif@v4; the suite template names its static tests by package
76+
and runs the device's own 64-bit host, so it works on Windows on ARM. See CHANGELOG.md.
6777
0.32.0 - Get-IntuneAgentTimeline read Kind as Unknown for a policy whose lines all sat in a rolled
6878
log file (HealthScripts-20260925-101500 lost only its time part); it reads Remediation or
6979
Win32App like one from the current file. The Policy column of the health report and drift
@@ -78,15 +88,7 @@ pre-flight over the tenant's deployed scripts and readers for the agent's logs
7888
assignment: a clause that never matches excludes nobody, so the assignment reaches every
7989
device in the group. The tenant-wide help example keeps to Windows filters. See
8090
CHANGELOG.md.
81-
0.30.0 - Invoke-IntuneDetectionTest, Invoke-IntuneRequirementTest and Invoke-IntuneWin32AppTest no
82-
longer default -Architecture to x64, which Windows on ARM refuses; left out, it is the
83-
device's 64-bit host (x64, or arm64 on ARM), the one the agent uses. Two Win32 fixes: the
84-
launcher starts its child without NoDefaultCurrentDirectoryInExePath, a per-user cmd.exe
85-
setting that made a bare install.cmd fail with "not recognized" although the agent's
86-
cmd.exe finds it; and the 32-bit host warning also reads the batch file an install or
87-
uninstall command names, where a powershell.exe call runs 32-bit just the same. See
88-
CHANGELOG.md.
89-
Earlier versions, 0.1.0 to 0.29.0: CHANGELOG.md, which ships with the module.
91+
Earlier versions, 0.1.0 to 0.30.0: CHANGELOG.md, which ships with the module.
9092
'@
9193
RequireLicenseAcceptance = $false
9294
}

‎README.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,9 @@ as a Markdown table per kind, Broken first.
660660
repository of Intune scripts: on every pull request that touches a script it takes the module from a
661661
checked-in copy when `ISL_MODULE_PATH` names its manifest, or installs it from the Gallery,
662662
runs [Examples/Invoke-IntuneScriptGate.ps1](./Examples/Invoke-IntuneScriptGate.ps1) over the script
663-
folders (a Pester suite under them, `*.Tests.ps1`, is left out) and fails the build at the chosen
664-
severity. The gate script annotates the changed files
663+
folders (a Pester suite under them, `*.Tests.ps1`, and the contents of a Win32 app's `Package`
664+
folder are left out) and fails the build at the chosen severity. The gate script annotates the
665+
changed files
665666
with each finding (file, line, rule, message), appends a Markdown summary to the job, and returns
666667
the findings with `-PassThru`; it works on any CI with `-Annotate:$false`. With `-SarifPath` it
667668
also writes a SARIF 2.1.0 log (`Export-IntuneFindingSarif`: a rule entry per rule with its help

‎Tests/Integration/ScriptGate.Tests.ps1‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ BeforeAll {
2424
# A Pester suite next to the scripts, as the suite template places it: not an Intune script
2525
[System.IO.File]::WriteAllText((Join-Path $script:Scripts 'IntuneScripts.Tests.ps1'),
2626
"BeforeAll { Import-Module IntuneScriptLab }`r`nDescribe 'x' { It 'y' { 1 | Should-Be 1 } }`r`n", $utf8Bom)
27+
# A Win32 app's package content, as the suite template lays it out: the installer runs through
28+
# the install command as SYSTEM, so it is not an Intune script either. Read as one, its
29+
# machine-wide write is a user-context warning. 'Packages' is a folder of Win32 apps and stays in.
30+
$null = New-Item -ItemType Directory -Path (Join-Path $script:Scripts 'Win32\Widget\Package') -Force
31+
$null = New-Item -ItemType Directory -Path (Join-Path $script:Scripts 'Packages\Gadget') -Force
32+
[System.IO.File]::WriteAllText((Join-Path $script:Scripts 'Win32\Widget\Package\install.ps1'),
33+
"New-Item -Path HKLM:\SOFTWARE\Widget -Force | Out-Null`r`nexit 0`r`n", $utf8Bom)
34+
[System.IO.File]::WriteAllText((Join-Path $script:Scripts 'Packages\Gadget\Detect.ps1'),
35+
"Write-Output 'installed'`r`nexit 0`r`n", $utf8Bom)
2736

2837
# -File carries the script's exit code out as the process exit code on both hosts; a switch
2938
# cannot be negated that way, so the quiet run uses -Command (and expects exit 0 anyway)
@@ -110,6 +119,17 @@ Describe 'Invoke-IntuneScriptGate' -Tag 'Integration', 'Gate' {
110119
($direct.Output -join "`n") | Should-BeLikeString '*IslModuleDependency*'
111120
}
112121

122+
It 'leaves a Win32 Package folder out, keeps a Packages folder in, and analyzes a named installer' {
123+
$run = Invoke-GateFile -Arguments @('-Path', $script:Scripts, '-Annotate', '-Root', $script:Scripts,
124+
'-FailOn', 'None')
125+
$run.ExitCode | Should-Be 0
126+
($run.Output -join "`n") | Should-NotBeLikeString '*Package\install.ps1*'
127+
($run.Output -join "`n") | Should-BeLikeString '*Packages\Gadget\Detect.ps1*'
128+
$installer = Join-Path $script:Scripts 'Win32\Widget\Package\install.ps1'
129+
$direct = Invoke-GateFile -Arguments @('-Path', $installer, '-FailOn', 'None')
130+
($direct.Output -join "`n") | Should-BeLikeString '*IslContextIssue*'
131+
}
132+
113133
It 'percent-encodes the colon of an absolute path outside -Root in the file property' {
114134
# With -Root below the scripts, every path stays absolute and carries a drive letter
115135
$run = Invoke-GateFile -Arguments @('-Path', $script:Scripts, '-Annotate', '-FailOn', 'None',

0 commit comments

Comments
 (0)