views:

271

answers:

3

I have several configuration files on Windows Server 2008 nested like such:

C:\Projects\Project_1\project1.config

C:\Projects\Project_2\project2.config

In my configuration I need to do a string replace like such:

<add key="Environment" value="Dev"/>

will become:

<add key="Environment" value="Demo"/>

I thought about using batch scripting, but there was no good way to do this, and I heard that with PowerShell scripting you can easily perform this. I have found examples of find/replace, but I was hoping for a way that would traverse all folders within my C:\Projects directory and find any files that end with the '.config' extension. When it finds one, I want it to replace my string values.

Any good resources to find out how to do this or any PowerShell gurus that can offer some insight?

+1  A: 

PowerShell is a good choice ;) It is very easy to enumerate files in given directory, read them and process.

The script could look like this:

Get-ChildItem C:\Projects *.config -recurse |
    Foreach-Object {
        $c = ($_ | Get-Content) 
        $c = $c -replace '<add key="Environment" value="Dev"/>','<add key="Environment" value="Demo"/>'
        [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
    }

I split the code to more lines to be readable for you. Note that you could use Set-Content instead of [IO.File]::WriteAllText, but it adds new line at the end. With WriteAllText you can avoid it.

Otherwise the code could look like this: $c | Set-Content $_.FullName.

stej
+3  A: 

Here a first attempt at the top of my head.

$configFiles=get-childitem . *.config -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) | 
Foreach-Object {$_ -replace "Dev", "Demo"} | 
Set-Content $file.PSPath
}
David Relihan
I would like to add that testing the solutions provided out all worked, but this one was the easiest for readability. I was able to hand this to a co-worker and he could easily understand what was going on. Thanks for the assistance.
Brandon
Great stuff Brandon. I havn't fully embraced Powershell but when you consider how long this would take in VBScript!!!!
David Relihan
For this to work in files in subdirectories, you need ".PSPath". Interestingly, when I tried to make this work without a () around get-content it failed at write-content because the file was locked.
Frank Schwieterman
@Frank Thanks for correcting
David Relihan
A: 

I would go with xml and xpath:

dir C:\Projects\project_\project.config -recurse | foreach-object{
$wc = [xml](Get-Content $.fullname) $wc.SelectNodes("//add[@key='Environment'][@value='Dev']") | Foreach-Object {$.value = 'Demo'}
$wc.Save($_.fullname)
}

Shay Levy