用文本文件中环境的实际值替换环境变量的名称

Replace the name of environment variable by it's actual value from environment in a text file

我正在尝试使用 windows powershell 在 Windows Server 2008 上自动安装 Active Directory。我创建了一个扩展名为 .tmpl 的文本文件并添加了:

[DCINSTALL]
ReplicaOrNewDomain=_ReplicaOrNewDomain__

然后我创建了一个文本格式的应答文件:

[DCINSTALL]
ReplicaOrNewDomain=$env:ReplicaOrNewDomain

现在我希望能够在 PowerShell 中编写一个脚本,该脚本将使用模板文件从环境中获取变量 ReplicaOrNewDomain 的值,并用文本文件中的该值替换 $env:ReplicaOrNewDomain这样我就可以使用那个应答文件来安装 AD。

您可以通过这样的简单替换来做到这一点:

$f = 'C:\path\to\your.txt'
(Get-Content $f -Raw) -replace '$env:ReplicaOrNewDomain', $env:ReplicaOrNewDomain |
  Set-Content $f

或者像这样:

$f = 'C:\path\to\your.txt'
(Get-Content $f -Raw).Replace('$env:ReplicaOrNewDomain', $env:ReplicaOrNewDomain) |
  Set-Content $f

请注意,在使用 -replace 运算符时,您需要对 $ 进行转义(因为否则它会有特殊含义 "end of string")。使用 Replace() 方法时,您只需使用单引号来防止搜索字符串中变量的扩展。

但是,为什么要用不同的模板参数 $env:ReplicaOrNewDomain 替换模板参数 _ReplicaOrNewDomain__ 的中间步骤?如果你只保留前者并将其替换为环境变量 ReplicaOrNewDomain.

的值,你会让你的生活更轻松

可以使用ExpandString函数,like this:

$ExecutionContext.InvokeCommand.ExpandString($TemplVal)

(假设 $TemplVal 有模板字符串)。

我喜欢用我的模板文件做的一件事是这样的。

[DCINSTALL]
ReplicaOrNewDomain={0}
OtherVariable={1}

然后在我的代码中,我可以使用 format operator -f 进行更改。

$pathtofile = "C:\temp\test.txt"
(Get-Content $pathtofile -Raw) -f $env:ReplicaOrNewDomain, "FooBar" | Set-Content $pathtofile

如果您有多项需要同时更新的内容,它会有所帮助。根据需要使用尽可能多的占位符更新您的文件。如果需要,您可以在文件中多次使用同一个。

[DCINSTALL]
ReplicaOrNewDomain={0}
SimilarVariable={0}

警告

如果您的实际文件应该包含花括号,您需要将它们加倍,直到被转义。

您有几种选择可以做到这一点。一个是Environment.ExpandEnvironmentVariables。这使用了 %variable% 语法(而不是 $env:variable),所以如果你只想替换环境变量会更简单:

gc input.tmpl | foreach { [Environment]::ExpandEnvironmentVariables($_) } | sc out.ini

可以通过 ExpandString 实现更完整的 PowerShell 表达式扩展。如果您想将实际的 PowerShell 表达式插入模板,这会更有用:

gc input.tmpl | foreach { $ExecutionContext.InvokeCommand.ExpandString($_) } | sc out.ini

第三个选项类似于使用 Invoke-Expression 的自定义模板方案,我实施了