我有多个脚本利用模块 (psm1) 中的函数。我还有当前位于模块的全局哈希表中的通用值(文件路径/名称)。 MS 现在不鼓励全局对象,因此我试图找到一种方法将我的值包含在模块中,而不是使用其他文件(XML、CSV 等),也不将它们放入每个脚本中。当事情发生变化时(而且它们会发生变化),我只想在一个位置进行更新 - 我的模块。
对于全局可用的值“字典”/“哈希表”有什么想法吗?可以将其放入模块中,然后在每个脚本开头导入模块时导入?我使用 -global 参数导入模块,但没有专门使哈希表全局化,值不会持续存在。功能很好(设计使然)。
PSSharper 抛出有关全局变量、对象、哈希表等的警告。PS ScriptAnalyzer 调用全局哈希表,并且 MS 的多篇文章不鼓励全局使用。
蒂亚
我可能为您提供了一个基于放置在模块可见性范围中的变量的解决方案。它基于这篇博文
您在模块作用域中创建一个变量,并将模块工作所需的所有内容放入其中:
$DynDnsSession = [ordered]@{
ClientUrl = 'https://api.dynect.net'
ApiVersion = $null
AuthToken = $null
StartTime = $null
RefreshTime = $null
}
New-Variable -Name DynDnsSession -Value $DynDnsSession -Scope Script -Force
由于变量将在模块作用域中定义,因此您将无法通过直接从脚本中寻址来更改它 - 您必须在模块内为该变量提供包装器(一个 getter 和一个 setter)。
例如(即整个.psm1
模块
;基于同一篇博文)
$DynDnsSession = [ordered]@{
ClientUrl = 'https://api.dynect.net'
ApiVersion = $null
AuthToken = $null
StartTime = $null
RefreshTime = $null
}
Function Get-DynDnsSession {
return $DynDnsSession
}
Function Set-DynDnsSession {
[CmdletBinding()]
param(
)
DynamicParam {
# define dictionary for dynamic parameters
$ParamDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
# get all the keys from the module variable; please note the .GetEnumerator()
# it's to separate properties from each other, otherwise you just get all the values as a single object and not an array
$DynProps = $DynDnsSession.Keys.GetEnumerator()
foreach ($Prop in $DynProps) {
# type of the attribute. You probably can base this
# on the type of variables you have in your dictionary
$AttrType = "String"
$AttrCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
$ParamAttr = [System.Management.Automation.ParameterAttribute]@{
ParameterSetName = "DynamicFields"
Mandatory = $false
HelpMessage = $Prop # you can define this with a switch based on a property name if you want to
}
$AttrCollection.Add($ParamAttr)
$DynParam = [System.Management.Automation.RuntimeDefinedParameter]::new(
$Prop, $AttrType, $AttrCollection
)
$ParamDictionary.Add($Prop, $DynParam)
}
return $ParamDictionary
}
PROCESS {
foreach ($Param in $PSBoundParameters.GetEnumerator()) {
if ($DynDnsSession.Contains($Param.Key)) {
Write-Output $Param
Write-Verbose "Setting $($Param.Key) to $($Param.Value)" -Verbose
$DynDnsSession.$($Param.Key) = $Param.Value
}
}
}
}
我还定义了动态参数来验证您想要设置的内容。但是
如果您想在该模块变量中添加或删除属性,则必须使用另一种方法(尽管这比 DynamicParam 更容易)。我在我的多个 RestAPI 模块中使用它没有任何问题,并且从未有 PSScriptAnalyzer 抱怨。 DynamicParam 松散地基于
这篇文章