Repository navigation
feat(repair): eight more findings carry the edit their message asks for #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,12 @@ function Find-IslExecutionPolicyCall { | |
| Evidence = $evidence | ||
| } | ||
| } | ||
| # 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 | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| $pipeline.Parent.GetType().Name -in 'NamedBlockAst', 'StatementBlockAst' | ||
| if ($alone) { $findingSplat.Fix = @{ Replacement = '' } } | ||
| New-IslFinding @findingSplat | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,6 +107,8 @@ function Find-IslExitCodeIssue { | |
| "again. Use exit 1 for 'issue found'") | ||
| 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' } | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| } | ||
| New-IslFinding @findingSplat | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -168,6 +168,8 @@ function Find-IslInteractiveCall { | |
| "$source, so it is a credential that is already built and nothing prompts; the call " + | ||
| 'can go') | ||
| Evidence = $builtEvidence | ||
| # The call returns what it was handed, so the argument stands in for it | ||
| Fix = @{ Replacement = $handed.Extent.Text } | ||
| } | ||
| New-IslFinding @findingSplat | ||
| continue | ||
|
|
@@ -241,6 +243,13 @@ function Find-IslInteractiveCall { | |
| "-Force / -Confirm:`$false or it hangs until the $timeout timeout") | ||
| Evidence = $evidence | ||
| } | ||
| # 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') { | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| $switch = if ($confirming[$commandName]) { " -$($confirming[$commandName])" } | ||
| else { ' -Confirm:$false' } | ||
| $findingSplat.Fix = @{ Replacement = $command.Extent.Text + $switch } | ||
| } | ||
| New-IslFinding @findingSplat | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,15 +57,21 @@ function Find-IslPowerShell7Syntax { | |
|
|
||
| $requires = $ast.ScriptRequirements | ||
| 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 { | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| $_.Kind -eq 'Comment' -and $_.Text -match '(?i)^#requires\s+-version\b' | ||
| }) | Select-Object -First 1 | ||
| $findingSplat = @{ | ||
| RuleName = $rule | ||
| Severity = 'Error' | ||
| Context = $Context | ||
| Extent = $ast.Extent | ||
| Extent = if ($requiresToken) { $requiresToken.Extent } else { $ast.Extent } | ||
| Message = ("'#Requires -Version $($requires.RequiredPSVersion)' cannot be satisfied: Intune runs " + | ||
| 'Windows PowerShell 5.1, so the script exits 1 before its first line') | ||
| Evidence = $requiresEvidence | ||
| } | ||
| if ($requiresToken) { $findingSplat.Fix = @{ Replacement = '' } } | ||
| New-IslFinding @findingSplat | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,10 @@ function Find-IslRelativePath { | |
| 'the script') | ||
| 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') { | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $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. |
||
| $findingSplat.Fix = @{ Replacement = ($variable.Extent.Text -replace '(?i)PWD', 'PSScriptRoot') } | ||
| } | ||
| New-IslFinding @findingSplat | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.