如何使用PowerShell cmdlet对PowerShell脚本文件进行完整的语法检查

3

我正在编写一个控制台应用程序来验证PowerShell脚本的语法。 我的要求是在不执行脚本的情况下验证PowerShell脚本。我找到了下面这个PowerShell命令,可以在不执行脚本的情况下进行语法检查。

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

然而,我发现它并没有进行完整的语法检查。例如,在PowerShell中使用变量而不声明,或者在(Function、if、ForEach等)中出现拼写错误等此类语法错误不会被以上命令捕获。

以下是PowerShell脚本文件(.\deleteDemoFile.ps1)的示例代码。请注意,在下面的代码中,(if、Function)的拼写有误,并且使用了未声明的'$log_dir'变量。

当我运行PowerShell命令Get-Command -syntax 'D:\powershell\deleteDemoFile.ps1'时,该命令不会抛出任何语法错误。

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

我在想:

  • 这个PowerShell命令在进行语法检查时的效率如何?
  • 它只验证PowerShell cmdlets、函数和别名的语法吗?
  • 此命令与哪个版本的PowerShell脚本兼容?

是否还有其他命令可以执行完整的语法检查?

以下是PowerShell命令的参考链接:https://dev59.com/SFgQ5IYBdhLWcg3wJwsv#55337824


3
Invoke-ScriptAnalyzer是一个PowerShell模块,用于分析和提供代码质量建议。它可以帮助开发者编写更好的PowerShell脚本,提高代码可维护性和可读性。 - iRon
1
Get-Command 不会对任何东西进行“验证” - 它只会“发现”事物。 - Mathias R. Jessen
1
@MathiasR.Jessen,是的,Get-Command -Syntax 的目的是显示语法图(使用信息),但为了这样做,脚本必须被解析,因此作为副作用,语法错误确实会浮出水面。 - mklement0
1个回答

5
请注意,Get-Command-Syntax开关的目的是显示命令的语法图表,即显示其参数及其类型,即如何调用它
由于发现脚本的此信息需要进行解析,因此副作用是确实会检测到语法错误[1](然后Get-Command调用失败并报告遇到的具体语法错误)。
但是,您的示例脚本没有包含语法错误:虽然执行时它不会做您想要的事情,但它在语法上是有效的
  • ifTypoFunctionTypo被解释为命令名称,而不是错拼的关键字

    • 因此,只有在尝试调用名为ifTypo命令(cmdlet、函数、脚本、别名、可执行文件)时,才会在执行期间看到问题。
  • 有关PowerShell的两种基本解析模式,参数模式(类似于shell)和表达式模式(类似于编程语言),请参阅概念 about_Parsing 帮助主题。


Invoke-ScriptAnalyzer命令 (属于PSScriptAnalyzer模块,可使用Install-Module PSScriptAnalyzer进行安装) 由iRon建议使用,在Visual Studio Code的PowerShell扩展中用于设计时分析,可能能够指出潜在的其他问题,但在这种情况下不会(它只会警告您的脚本中是否使用了Write-Host命令)。


注意:
PowerShell的两种解析模式不可避免地会导致相当宽松的语法,而在动态语言中,静态分析能做的事情总是有限的。
没有现有的功能可以检测到您脚本中的问题;一个潜在的解决方案是要求向Invoke-ScriptAnalyzer添加用于标记潜在关键字拼写错误的新规则,方法是在项目的GitHub存储库中开放一个问题,但请注意,这样的规则最终是猜测,因为看起来像是错拼的关键字可能是合法的命令名称。

[1] 实际上,Get-Command -Syntax 间接地是调用官方的PowerShell解析器以查找语法错误的便捷快捷方式,这需要更多的努力 - 参见this answer


1
@Azhar,Get-Command -Syntax是您可以进行的最佳检查,因为它在幕后使用官方解析器-请参见我刚添加的脚注。再次强调:_您的脚本在语法上是有效的_。除非您向Invoke-ScriptAnalyzer添加检测_potential_问题的新规则,例如查找看起来像拼写错误关键字的命令名称,否则没有现有代码可以检测到您脚本中的问题。我还添加了一个新的底部部分来涵盖此内容。 - mklement0
1
非常感谢您提供如此详细的解释。我喜欢它的解析性质,因为它可以在不添加任何新规则的情况下进行快速语法检查。这将基本上完成我的任务,验证脚本。 - Azhar
你能告诉我这个命令 Get-Command -Syntax 兼容到哪个版本的 PowerShell 吗?这个命令会在旧版本的 PowerShell 上工作吗?我正在使用 PSVersion 5.1。 - Azhar
1
@Azhar。是的,它似乎也适用于旧版本;我刚在v2中验证过了。 - mklement0
谢谢@mklement0,我们有没有办法在同一台机器上检查低版本的脚本?还是需要安装低版本来测试。 - Azhar
1
@Azhar,是的,您需要安装相应的版本。您可以与5.1并行安装v2,但不能与其他版本并行安装。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接