3

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://stackoverflow.com/a/55337824/3725706

mklement0
  • 382,024
  • 64
  • 607
  • 775
Azhar
  • 107
  • 12
  • 3
    [`Invoke-ScriptAnalyzer`](https://learn.microsoft.com/en-us/powershell/module/psscriptanalyzer/invoke-scriptanalyzer)? – iRon Jul 15 '21 at 16:58
  • 1
    `Get-Command` doesn't _validate_ anything - it only _discovers_ things – Mathias R. Jessen Jul 15 '21 at 18:01
  • 1
    @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. – mklement0 Jul 16 '21 at 14:41

1 Answers1

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.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    @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. – mklement0 Jul 16 '21 at 14:38
  • 1
    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. – Azhar Jul 17 '21 at 06:45
  • 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.1 – Azhar Jul 17 '21 at 06:50
  • 1
    @Azhar. Yes, it seems to work in older versions too; just verified in v2. – mklement0 Jul 19 '21 at 12:58
  • Thanks @mklement0 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. – Azhar Jul 22 '21 at 06:23
  • 1
    @Azhar, yes, you''ll need to install the respective version. You can install v2 in parallel with 5.1, but not the others. – mklement0 Jul 22 '21 at 13:11