Repository navigation
feat(repair): eight more findings carry the edit their message asks for - #20
Conversation
fadwen
left a comment
There was a problem hiding this comment.
Notes on the lines whose reason the diff does not show.
| } | ||
| # The switch the message asks for, added to the call. Set-ExecutionPolicy gets none: the | ||
| # agent launches with -ExecutionPolicy Bypass, and IslExecutionPolicyCall removes the call | ||
| if ($commandName -ne 'Set-ExecutionPolicy') { |
There was a problem hiding this comment.
Two fixes on one extent collide: Repair-IntuneScript applies edits from the end of the file and checks each against the current text, so the second edit on the same call would be skipped with a warning. IslExecutionPolicyCall removes the call; this rule steps aside for it.
| # The call is removed when it is a statement on its own: in a pipeline, or as a value, taking | ||
| # it out would leave a broken statement with nothing to say so | ||
| $pipeline = $command.Parent | ||
| $alone = $pipeline.GetType().Name -eq 'PipelineAst' -and @($pipeline.PipelineElements).Count -eq 1 -and |
There was a problem hiding this comment.
NamedBlockAst is the script body or a begin/process/end block; StatementBlockAst is the body of an if, a loop, a try or a function. Anywhere else, a pipeline element, a sub-expression, an assignment's right side, the empty replacement would leave a syntax error.
| # would match nothing at all | ||
| $parent = $literal.Parent | ||
| $matched = $parent.GetType().Name -eq 'BinaryExpressionAst' -and | ||
| "$($parent.Operator)" -in 'Imatch', 'Inotmatch', 'Cmatch', 'Cnotmatch' -and $parent.Right -eq $literal |
There was a problem hiding this comment.
The literal has to be the right operand: as the left operand of -match it is the input, not the pattern, and an alternation there would be compared against the variable's text.
| Evidence = ('exit 2 and exit -1 both triggered the remediation and ended as Recurred ' + | ||
| '(REM-EXIT-2, REM-EXIT-NEG1); docs say only exit 1 does') | ||
| # Intune reads every non-zero exit as 1 already; writing it makes the report match | ||
| Fix = @{ Replacement = 'exit 1' } |
There was a problem hiding this comment.
exit 2 and exit -1 both ran the remediation and ended as Recurred (REM-EXIT-2, REM-EXIT-NEG1), so the device already behaves as if the script said exit 1; the edit changes the report, not the behaviour.
| if ($requires -and $requires.RequiredPSVersion -and $requires.RequiredPSVersion.Major -ge 6) { | ||
| # The requirement is a comment token, not a node; the finding sits on that line, and the | ||
| # fix takes the line out. What the script then does under 5.1 the other findings say | ||
| $requiresToken = @($Context.Tokens | Where-Object { |
There was a problem hiding this comment.
ScriptRequirements knows the version but not where the line is; the token list does. The finding moved from the whole script to that line because a replacement needs an extent that is exactly the text to replace.
| Evidence = $evidence | ||
| } | ||
| # $PSScriptRoot is a string where $PWD is a PathInfo, so $PWD.Path and the like get no edit | ||
| if ($variable.Parent.GetType().Name -ne 'MemberExpressionAst') { |
There was a problem hiding this comment.
$PWD is a PathInfo and $PSScriptRoot a string: $PWD.Path would become $PSScriptRoot.Path, which is $null. The finding stays for a person to rewrite as $PSScriptRoot alone.
Repair-IntuneScript applied three fixes: the script-scope return, the encoding and the padded requirement value. Thirteen other findings told the reader what to change in words a program could apply, and left the change to them. Eight of them now carry it as a Fix: - IslInteractiveCall: -Force on Install-Module, Install-PackageProvider, Install-Package, Update-Module and Uninstall-Module; -Confirm:$false on Register-PSRepository; a Get-Credential -Credential call handed a credential that can only be one already built is replaced by that credential, since the call returns what it was handed. - IslExecutionPolicyCall: the Set-ExecutionPolicy statement is removed. - IslOutputIssue: -ErrorAction SilentlyContinue on the probing cmdlet. - IslExitCodeIssue: exit N becomes exit 1, the value Intune reads it as. - IslArchitectureIssue: $env:ProgramFiles becomes $env:ProgramW6432. - IslArm64Assumption: 'AMD64' as the pattern of a -match becomes 'ARM64|AMD64'. - IslRelativePath: $PWD becomes $PSScriptRoot. - IslPowerShell7Syntax: the #Requires -Version 7 line is removed, and the finding sits on that line rather than on the whole script. Where the edit would leave a broken statement there is no fix and the finding stays: Set-ExecutionPolicy inside a pipeline or as a value, 'AMD64' compared with -eq, $PWD followed by a member. Set-ExecutionPolicy without -Force gets no -Force either; its removal is the fix. Messages, severities and evidence are unchanged, so docs/Rules.md is unchanged.
Summary
Repair-IntuneScriptapplied three fixes: the script-scopereturn, the encoding and the padded requirement value. Thirteen other findings told the reader what to change in words a program could apply, and left the change to them. Eight of them now carry that edit as aFix, soRepair-IntuneScriptmakes it. Each edit is the one the finding's own message asks for; where it would leave a broken statement, the finding has no fix and stays. Messages, severities and evidence are unchanged, sodocs/Rules.mdis unchanged.Stacked on #19 (base branch); the diff is this change only. Merge #16 through #19, then this.
Changes
IslInteractiveCall-ForceonInstall-Module,Install-PackageProvider,Install-Package,Update-Module,Uninstall-Module;-Confirm:$falseonRegister-PSRepositorySet-ExecutionPolicy, whichIslExecutionPolicyCallremoves insteadIslInteractiveCallGet-Credential -Credential $x, where$xcan only be a credential (#13), becomes$xIslExecutionPolicyCallSet-ExecutionPolicystatement is removedIslOutputIssue-ErrorAction SilentlyContinueon the probing cmdlet, in Win32 detection and requirement scriptsIslExitCodeIssueexit Nbecomesexit 1, the value Intune reads it asIslArchitectureIssue$env:ProgramFilesbecomes$env:ProgramW6432, set in 32-bit and 64-bit processes alikeIslArm64Assumption'AMD64'as the pattern of a-matchbecomes `'ARM64IslRelativePath$PWDbecomes$PSScriptRoot$PWD.Path, which$PSScriptRoothas notIslPowerShell7Syntax#Requires -Version 7line is removedThe
#Requiresfinding now sits on its line rather than on the whole script, which the fix needs and which reads better. Not taken on: the relative path literal (needsJoin-Path $PSScriptRoot, a change of shape),'Program Files'andSystem32in a literal (a literal to an expression, or a folder that exists only in a 32-bit process on a 64-bit Windows), andutf8NoBOM(changing it changes the bytes written).Help, README and the changelog list the edits; MAML rebuilt.
Verification
docs/Rules.mdregenerates unchanged.Repair-IntuneScriptwith the file's text checked afterwards and no fixable finding left; the four withheld cases, each with its finding still reported and the file untouched.Notes
Set-ExecutionPolicycall reported by bothIslExecutionPolicyCallandIslInteractiveCall, would be skipped by the repair's text check with a warning; that is why the second rule gives that call no-Force.-ErrorAction SilentlyContinueis attached to the first unguarded cmdlet only, as the finding is; a script with several gets one per repair run.