0

I am trying to automate Active Directory installation on Windows Server 2008 using windows powershell. I created a text file with .tmpl extension and added:

[DCINSTALL]
ReplicaOrNewDomain=_ReplicaOrNewDomain__

Then I created an answer file in a text format:

[DCINSTALL]
ReplicaOrNewDomain=$env:ReplicaOrNewDomain

Now I want to be able to write a script in PowerShell which will use the template file to get the value of variable ReplicaOrNewDomain from environment and replace $env:ReplicaOrNewDomain by that value in the text file so that I can use that answer file for AD installation.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
samisda1
  • 87
  • 1
  • 2
  • 6

4 Answers4

2

You can do that with a simple replacement like this:

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

or like this:

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

Note that when using the -replace operator you need to escape the $ (because otherwise it'd have the special meaning "end of string"). When using the Replace() method you just need to use single quotes to prevent expansion of the variable in the search string.

However, why the intermediate step of replacing the template parameter _ReplicaOrNewDomain__ with a different template parameter $env:ReplicaOrNewDomain? You would make your life easier if you just kept the former and replaced that with the value of the environment variable ReplicaOrNewDomain.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • I appreciate that you reesponded to my query. I just tried your method and that worked for me well. But I was little concerned if I have to replace multiple environment variables. Could you please help me with this as well. Thanks – samisda1 May 25 '15 at 14:40
  • You can daisy-chain the replacement operations. However, if you do have multiple replacements, one of the other answers might be a better solution for your problem. – Ansgar Wiechers May 25 '15 at 16:12
2

You have a few options to do this. One is Environment.ExpandEnvironmentVariables. This uses a %variable% syntax (instead of $env:variable), so it would be simpler if you only want to substitute environment variables:

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

A more complete expansion of PowerShell expressions can be achieve via ExpandString. This is more useful if you want to insert actual PowerShell expressions into the template:

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

A third option would be something like a customized templating scheme that uses Invoke-Expression, which I implemented here.

Community
  • 1
  • 1
Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
1

One thing that I like to do with my template files is something like this.

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

Then in my code I can use the format operator -f to make the changes.

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

It can help if you have multiple things that you need to update at once. Update your file with as many place holders as you need. You can use the same one multiple times if need be in the file.

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

Caveat

If your actual file is supposed to contain curly braces you need to double them up to the are escaped.

Matt
  • 45,022
  • 8
  • 78
  • 119
  • 1
    That is not very maintenable - you need to keep focus on indices and you can't do some more advanced stuff like for instance iterations. ExpandString is far more general solution as you can inject any code (even recursively). – majkinetor May 25 '15 at 18:40
  • @majkinetor I do agree about the maintaining of incidences. As long as the numbers are not to high, and the user is willing to manage it, this can still work. – Matt May 25 '15 at 18:43
-1

You can use the ExpandString function, like this:

$ExecutionContext.InvokeCommand.ExpandString($TemplVal)

(assuming $TemplVal has the template string).

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
majkinetor
  • 8,730
  • 9
  • 54
  • 72
  • 1
    Please do not post link-only answers. If you refer to external resources, include the relevant parts in your answer in addition to the link. – Ansgar Wiechers May 25 '15 at 16:11
  • The answer is given - name of the function used for such things, that should be enough in this case.. Link is for the details. – majkinetor May 25 '15 at 18:37
  • 1
    You should at least show an example in your question. If the link dies someone will have to google it anyway – Matt May 25 '15 at 18:44
  • Not sure about that in this case - keyword is given, there will always be online documentation for the function. – majkinetor May 25 '15 at 20:46
  • @majkinetor ..Hi, I am trying to install AD using unattended method. I have created an answer file and I don't want to hardcode the values in an answer file. The file is as below: [DCINSTALL] ReplicaOrNewDomain=$env:ReplicaOrNewDomain NewDomain=$env:Domain I want to be able to run the following function and pass the values of these variables to this answer file so that the answer file looks like: [DCINSTALL] ReplicaOrNewDomain=Domain NewDomain=Forest When I run this function, I get the correct values but I am unable to pass those values to the text file. – samisda1 Jun 02 '15 at 13:22
  • @majkinetor .. function Expand-String { param( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] [System.String]$Value, [switch]$EnvironmentVariable ) if($EnvironmentVariable) { [System.Environment]::ExpandEnvironmentVariables($Value) } else { $ExecutionContext.InvokeCommand.ExpandString($Value) } } Expand-String -Value “$env:DomainNetbiosName“ Expand-String -Value “$env:DomainLevel“ Expand-String -Value “$env:InstallDNS“ Any help would be appreciated. – samisda1 Jun 02 '15 at 13:24
  • Your code is wrong. It is simply `.. ExpandString((get-content dcinstall.ini)) |set-content dcinstall-expanded.ini` given that environment variables exist. – majkinetor Jun 02 '15 at 14:51