How to do full syntax check of PowerShell script file using the PowerShell cmdlet
Asked Answered
H

1

4

I'm writing a console application to validate the PowerShell script syntax. My request is to validate the PowerShell script without executing the script. I found this below PowerShell command which can perform the syntax check without executing the scripts.

Get-Command -syntax 'D:\powershell\deleteDemoFile.ps1'

However, I found that it does not do a complete syntax check. For example a variable is used in the PowerShell without declaring or their is typos in the (Function, if, ForEach, etc.) such syntax error is not captured by the above command.

Below is the sample code of the PowerShell script file (.\deleteDemoFile.ps1) Notice in the below code the spelling of (if, Function) is wrong and a variable '$log_dir' is used but is not declared.

When I run the PowerShell Command Get-Command -syntax 'D:\powershell\deleteDemoFile.ps1' the command does not throw any syntax error.

Write-Host "Hello, World!"

ifTypo(-not (test-path -path $log_dir )) {
   new-item -itemtype directory -path $log_dir
}


FunctionTypo log {
   Param ([string]$log_string)
   write-host $log_string
   add-content $log_file -value $log_string
}

log("Deleting a demo txt file")

# PowerShell -WhatIf safety parameter
Clear-Host
Get-Childitem D:\powershell\SomeFile\demo.txt -Recurse | Remove-Item

So I was wondering.

  • How efficient is this PowerShell command in order to do a syntax check?
  • Does it only validate the syntax of PowerShell cmdlets, functions, and aliases?
  • Up to which version of PowerShell script this command is compatible?

Is there any other Command which can perform full syntax check?

Here is the reference of the PowerShell command: https://mcmap.net/q/714220/-how-can-i-automatically-syntax-check-a-powershell-script-file

Haematogenesis answered 15/7, 2021 at 16:50 Comment(3)
Invoke-ScriptAnalyzer?Hoehne
Get-Command doesn't validate anything - it only discovers thingsCati
@MathiasR.Jessen, true, the purpose of Get-Command -Syntax is to show the syntax diagram (usage information), but to do so the script must be parsed, so as a side effect syntax errors do surface.Sarazen
S
5

Note that the purpose of Get-Command's -Syntax switch is to show a command's syntax diagram, i.e. to show its parameters and their types, i.e. how to invoke it.

Since discovering this information for scripts requires parsing them, as a side effect you would indeed detect syntax errors[1] (the Get-Command call then fails and reports the specific syntax error encountered).

However, your example script does not contain syntax errors: while it won't do what you want when executed, it is syntactically valid:

  • ifTypo and FunctionTypo are interpreted as command names, not as misspelled keywords.

    • As such, you'd only see the problem on execution, when an attempt to call a command (cmdlet, function, script, alias, executable) named ifTypo, for instance, is made.
  • See the conceptual about_Parsing help topic for information about PowerShell's two fundamental parsing modes, argument mode (like shells) and expression mode (like programming languages).


The Invoke-ScriptAnalyzer cmdlet (part of the PSScriptAnalyzer module you can install with Install-Module PSScriptAnalyzer) suggested by iRon, which is also used in the PowerShell extension for Visual Studio Code for design-time analysis, may be able to point out potential additional problems, but in the case at hand it wouldn't (it only warns against Write-Host use in your script).


Note:

  • PowerShell's two parsing modes invariably amount to a pretty permissive syntax, and in general there's only so much you can do with static analysis in a dynamic language.

  • No existing features can detect the problems with your script; a potential solution is to ask that new rules for flagging potential keyword misspellings be added to Invoke-ScriptAnalyzer, by opening an issue in the project's GitHub repo, but note that such rules are ultimately guesswork, because what looks like a misspelled keyword could be a legitimate command name.


[1] In effect, Get-Command -Syntax is indirectly a convenient shortcut to calling the official PowerShell parser in order to find syntax errors, which requires more effort - see this answer.

Sarazen answered 15/7, 2021 at 19:30 Comment(6)
@Azhar, Get-Command -Syntax is the best check you can do, because it uses the official parser behind the scenes - please see the footnote I've just added. Again: Your script is syntactically valid. No existing code can detect the problems with your script, unless you add new rules to Invoke-ScriptAnalyzer that detect potential problems, such as looking for command names that look like misspelled keywords. I've also added a new bottom section to cover this.Sarazen
Thank you for such a detailed explanation. I liked that due to its parsing nature it helps to do a quick syntax check without adding any new rules. This will pretty much accomplish my task to validate the script.Haematogenesis
Can you also help me with till which version of PowerShell this command Get-Command -Syntax is compatible? Will this command work on older versions of PowerShell. I'm on PSVersion 5.1Haematogenesis
@Azhar. Yes, it seems to work in older versions too; just verified in v2.Sarazen
Thanks @Sarazen do we have any way to check the script in lower versions on same machine? Or we need to install the lower version to test.Haematogenesis
@Azhar, yes, you''ll need to install the respective version. You can install v2 in parallel with 5.1, but not the others.Sarazen

© 2022 - 2024 — McMap. All rights reserved.