问题描述
模块清单,让我们指定对.NET和CLR的要求,来自清单* .psd1
# Minimum version of Microsoft .NET Framework required by this module.
# This prerequisite is valid for the PowerShell Desktop edition only.
DotNetFrameworkVersion = "3.5"
# Minimum version of the common language runtime (CLR) required by this module.
# This prerequisite is valid for the PowerShell Desktop edition only.
CLRVersion = "2.0"
我有几个正在使用的模块,但找不到任何资源来帮助我指定模块所需的最低版本。
为解决此问题,我正在考虑编写一个正则表达式脚本,该脚本将扫描模块中使用的.NET类型,例如,该脚本将收集诸如以下的类型:
[System.Net.IPAddress]
[System.Management.Automation.ValidateUserDriveAttribute]
根据使用的类型,我可以检查引入了哪些类型的.NET和CLR。
然后,我也可以使用旧版PowerShell运行测试,但只能使用“ Core”版运行,我不确定是否可以安装旧版Windows PowerShell。
这是很多工作,我什至不确定是否能解决我的问题,您知道更好的方法可以用来学习需求吗?
解决方法
我正在考虑编写一个正则表达式脚本,该脚本将扫描.NET类型的模块
它不会给您完整的图片,但这是一个好的开始!
我要强调的一件事-不要在这种类型的静态分析中使用正则表达式!
PowerShell公开了其语言解析器,因此使用它来生成抽象语法树,然后可以使用它来发现诸如类型文字名称之类的东西:
using namespace System.Management.Automation.Language
Get-ScriptTypeLiteral
{
param([string]$LiteralPath)
$filePath = Resolve-Path @PSBoundParameters
# Step 1,parse the file to produce an AST
$AST = [Parser]::ParseFile($filePath,[ref]$null,[ref]$null)
# Step 2,find all type literals
$TypeLiterals = $AST.FindAll({
param($SubAST)
# Type literals come in two variants - expressions and attributes
# Expressions are things like the first half of `[type]::Member`
# Attributes cover things like [ValidateLength()] as well as type constraints in param blocks
$SubAST -is [TypeExpressionAst] -or $SubAST -is [AttributeAst]
},$true)
# Step 3,return the type names
return $TypeLiterals.TypeName
}
您可以进一步采用这种方法,并使用它来发现诸如member access expressions之类的事物,以同时考虑各个版本之间的BCL类型差异。
虽然我从未将其用于特定目的,但我怀疑您可以利用PSScriptAnalyzer通过自定义规则简化此过程。
这是很多工作,我什至不确定是否能解决我的问题,您知道更好的方法可以用来学习需求吗?
我不确定我是否会考虑上述任何“最佳实践”,但是可能值得在the PowerShell GitHub repo
中提交问题以寻求指导 ,在@Mathias答案的帮助下,我进行了一些研究,得出了非常简单且准确率达到90%的解决方案。
第一步是为PSScriptAnalyzer定义规则,该规则应在文件PSScriptAnalyzerSettings.psd1
中定义,并将其放入存储库中的根目录中。
文件应包含以下规则:
@{
IncludeRules = @(
'PSUseCompatibleCmdlets'
'PSUseCompatibleSyntax'
Rules = @{
PSUseCompatibleSyntax = @{
Enable = $true
TargetVersions = @(
"7.0","5.1"
)
}
PSUseCompatibleCmdlets = @{
compatibility = @(
"core-6.1.0-windows"
"desktop-5.1.14393.206-windows"
)
}
}
)
}
然后从存储库的根目录调用分析器:
Invoke-ScriptAnalyzer .\ -Recurse -Settings .\PSScriptAnalyzerSettings.psd1
这将使您知道模块是否调用了任何与Core 6.1或Desktop 5.1不兼容的Commandlet。
如果收到警告,则不支持这些版本,这意味着需要在更高的PowerShell版本上执行测试。
为什么这很重要?这是关于PowerShell版本而不是.NET或CLR ... 如果5.1是最新的Windows PowerShell版本,又如何测试?
上面的规则中还有一个内部版本号14393
,可能会报告问题,下一步是确定该内部版本的Windows版本,具体操作请参见:
Windows 10 release information
从这里我们看到内部版本号是针对Windows v1607的。
下一步是查看哪些版本的Windows中包含了.NET版本,请参见:
.NET Framework versions and dependencies
从这里我们看到Windows 10中包含的最低.NET版本是.NET Framework 4.6
,具体取决于CLR 4.0
目前,这一切都取决于要在哪个系统上部署模块,如果您从PSScriptAnalyzer得到警告,则最低要求是.NET 4.6和CLR 4.0
下一步是确定模块发生故障的确切操作系统内部版本号,为此,请参见:
Determine which .NET Framework versions are installed
这应该会有所帮助,但是需要进行测试,所以我对大致的结果感到满意。