Private/Rules/Find-IslRelativePath.ps1
|
function Find-IslRelativePath { <# .SYNOPSIS Flags paths that depend on the working directory. .DESCRIPTION The working directory is not the script's folder. SYSTEM scripts start in C:\WINDOWS\system32; Win32 install commands start in the extracted content folder; and a user-context platform script was observed inheriting whatever folder the agent had last used for a Win32 install. Relative paths therefore point somewhere different on every run. .PARAMETER Context The IntuneScriptLab.ScriptContext from Get-IslScriptContext: AST, tokens, bytes and the effective ScriptType, Context and Architecture. .EXAMPLE Find-IslRelativePath -Context (Get-IslScriptContext -Path .\Detect.ps1) The findings this rule produces for one script, as IntuneScriptLab.Finding objects. #> [CmdletBinding()] param( [Parameter(Mandatory)] [pscustomobject]$Context ) $rule = 'IslRelativePath' $evidence = ('cwd was C:\WINDOWS\system32 for SYSTEM scripts, the content folder for Win32 installs, and ' + 'once ' + 'an old IMECache folder for a user script (PS-PROBE-USER)') foreach ($literal in (Get-IslStringLiteral -Ast $Context.Ast)) { if ($literal.Value -match '^\.{1,2}[\\/]') { $findingSplat = @{ RuleName = $rule Severity = 'Warning' Context = $Context Extent = $literal.Extent Message = ("Relative path '$($literal.Value)' resolves against an unpredictable working " + "directory. Anchor it to `$PSScriptRoot or use a full path") Evidence = $evidence } New-IslFinding @findingSplat } } $pwdVariables = Find-IslAstNode -Ast $Context.Ast -TypeName VariableExpressionAst -Where { param($node) $node.VariablePath.UserPath -eq 'PWD' } foreach ($variable in $pwdVariables) { $findingSplat = @{ RuleName = $rule Severity = 'Information' Context = $Context Extent = $variable.Extent Message = ('$PWD is not the script folder under Intune; use $PSScriptRoot for files shipped with ' + 'the script') Evidence = $evidence } New-IslFinding @findingSplat } } |