所以我今天的挑战。
我有一个配置文件(实际上只是一个txt文档),该文件存储变量以存储脚本之间传递的信息或在重启后使用的信息。
我正在寻找一种更有效的方式来读取和更新文件。目前,我通过以下方式读取文件:
Get-Content $current\Install.cfg | ForEach-Object {
Set-Variable -Name line -Value $_
$a, $b = $line.Split('=')
Set-Variable -name $a -Value $b
}
但是要覆盖内容,我使用以下命令重新创建文件:
ECHO OSV=$OSV >>"$ConfigLoc\tool.cfg"
ECHO OSb=$OSb >>"$ConfigLoc\tool.cfg"
ECHO cNum=$cNum >>"$ConfigLoc\tool.cfg"
ECHO cCode=$cCode >>"$ConfigLoc\tool.cfg"
ECHO Comp=$Comp >>"$ConfigLoc\tool.cfg"
每次添加新的已保存变量时,我都将新变量硬编码到原始配置文件和配置更新程序中。 由于我的下一个更新要求将当前的15个变量增加到当前的15个变量。
Get-Content $current\Install.cfg | ForEach-Object {
Set-Variable -Name line -Value $_
$a, $b = $line.Split('=')
ECHO $a=$$a
}
$$a
在循环中使用变量$ a作为变量名称来加载值。
我可以说明的最佳例子是:
ECHO $a=$$a (in current loop)
Echo OSV=$OSV (actually appears in code as)
不确定如何再次阐明这一点,或者不确定如何在变量标题也是变量的情况下实现它。
答案 0 :(得分:0)
如果您要创建一个具有name = value参数的文件,这是另一种建议。这是我每天使用的真实脚本的片段。您可以对其进行修改,以便它读取您的.csv输入并使用它代替硬编码值。
$Sites = ("RawSiteName|RoleName|DevUrl|SiteID|HttpPort|HttpsPort", `
"SiteName|Name of role|foo.com|1|80|443" `
) | ConvertFrom-CSV -Delimiter "|"
$site = $sites[0]
Write-Host "RawSiteName =$($site.RawSiteName)"
您也许可以使用类似于$text = Get-Content MyParameters.csv
的东西并将其通过管道传递到ConvertFrom-CSV
cmdlet。我意识到这并不是您正在做的事情的直接答案,但是它可以让您以编程方式创建一个跨脚本传递的文件。
答案 1 :(得分:0)
从本质上讲,您正在寻找可变间接:通过存储在另一个变量中的名称间接访问变量 。>
在PowerShell中, Get-Variable
允许您执行此操作,如下所示:
# Sample variables.
$foo='fooVal'
$bar='barVal'
# List of variables to append to the config file -
# the *names* of the variables above.
$varsToAdd =
'foo',
'bar'
# Loop over the variable names and use string expansion to create <name>=<value> lines.
# Note how Get-Variable is used to retrieve each variable's value via its *name*.
$(foreach ($varName in $varsToAdd) {
"$varName=$(Get-Variable $varName -ValueOnly)"
}) >> "$ConfigLoc/tool.cfg"
通过上述操作,以下几行会附加到输出*.cfg
文件中:
foo=fooVal
bar=barVal
请注意,您ConvertFrom-StringData
可以更轻松地读取这样的文件,该文件会输出一个 hashtable ,其中包含来自文件:
$htSettings = Get-Content -Raw "$ConfigLoc/tool.cfg" | ConvertFrom-StringData
例如,访问$htSettings.foo
将返回fooVal
。
使用哈希表 作为设置容器, 更新配置文件变得更加容易,因为您可以简单地使用所有设置及其当前值重新创建文件:
$htSettings.GetEnumerator() |
ForEach-Object { "$($_.Key)=$($_.Value)" } > "$ConfigLoc/tool.cfg"
注意:默认情况下,PowerShell不会枚举管道中哈希表的条目,这就是为什么需要.GetEnumerator()
的原因。
不过,通常,这种手动序列化很麻烦,正如其他人所指出的那样,并且还有很多健壮的(虽然通常不那么友好)替代方案。
使用基于字符串和行的序列化方法,需要注意两件事:
所有值都保存为字符串,因此,如果不是所有对象都提供有意义的字符串表示形式,则在必要时,甚至有可能必须手动将其转换为所需的数据类型。
Export-CliXml
,但请注意,它不是 friendly 格式-请谨慎进行手动编辑。 ConvertFrom-StringData
将失败,并且配置文件中的名称重复,这意味着您必须手动确保在添加到文件时不创建重复的条目-如果您每次都使用上述方法从哈希表重新创建文件,但是,这是安全的。
答案 2 :(得分:0)
感谢大家的帮助。这是我要解决的问题。导入和导出再简单不过了。如果我必须手动更新XML安装默认值,那么我可以轻松实现,这也很棒。我也喜欢这样一个事实,即使您以$Test
的身份导入,仍然可以使用$original
来访问变量。我将创建多个哈希表来组织今后将要使用的不同数据,并仅将其导入/导出为$config
变量作为主变量。
$original = @{
OSV='0'
OSb='0'
cNum='00000'
cCode='0000'
Client='Unknown'
Comp='Unknown'
}
$original | Export-Clixml $Home\Desktop\sample.cfg
$Test = Import-Clixml $Home\Desktop\sample.cfg
Write $Test
Write $original.Client