0

This is probably an easy one, but I'm trying to write a script to use when moving a directory for an installed program from one computer to another. In order to make this work, I have to find every instance of the old hostname, old IP address, and old drive letter from the old machine, and replace them with the new hostname, new IP address, and the new drive letter on the new machine. The primary folder contains *.xml and *.config files that need to be edited in the primary folder as well as in sub folders.

This is the code I'm working with:

$oldIP = "192.168.1.2"
$newIP = "192.168.1.3"
$oldhost = "OLDHOSTNAME"
$newhost = "NEWHOSTNAME"
$oldDriveLetter = "C"
$newDriveletter = "E"

$path = "\\$newip\$newdriveletter$\Folder"
$files = get-childitem $path\* -include *.xml, *.config, -recurse 
$files | %{
    (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -replace "${olddriveletter}:\Folder", "${newDriveLetter}:\Folder" | set-content $_.fullname
}

Currently, it is only replacing the values in the primary folder, but not any of the sub folders. Any idea what I'm missing?

Edit: Per the suggestion below, I removed the comma after *.config, and that seems to get me through the sub folders. But it's still not replacing any instance of C:\Folder with E:\Folder

3
  • You have a comma after *.config. It should not be there since your array ends there. Commented May 9, 2019 at 17:02
  • Thanks. That fixed that... Now it doesn't seem to be replacing any instance of "C:\Folder" with "E:\Folder" (there apparently were none in the primary folder. Any thought on what's wrong there? Commented May 9, 2019 at 17:12
  • -Replace uses regex to find a match. You need to escape literal backslash characters in a regex expression. So "${olddriveletter}:\Folder" should become "${olddriveletter}:\\Folder" Commented May 9, 2019 at 17:26

2 Answers 2

1

This works fine. Took the comma off the end of *.config, and added another \ in the middle of ${olddriveletter}:\Folder.

$oldIP = "192.168.1.2"
$newIP = "192.168.1.3"
$oldhost = "OLDHOSTNAME"
$newhost = "NEWHOSTNAME"
$oldDriveLetter = "C"
$newDriveletter = "E"

$path = "."
$files = get-childitem $path\* -include *.xml, *.config -recurse 
$files | %{
    (gc $_) -replace $oldhost, $newhost -replace $oldip, 
       $newip -replace "${olddriveletter}:\\Folder","${newDriveLetter}:\Folder" | 
       set-content $_.fullname
}

Tried to streamline it a little. Too bad you can't just do "get-childitem | get-content -replace | set-content".

get-childitem $path\* -include *.xml, *.config -recurse | 
foreach {
  (get-content $_) -replace $oldhost,$newhost -replace $oldip,
  $newip -replace "${olddriveletter}:\\Folder", "${newDriveLetter}:\Folder" |
  set-content $_ 
}
Sign up to request clarification or add additional context in comments.

3 Comments

I had to put this on hold for a bit, but now I'm back... This is working phenomenally well... One question you might be able to answer... Is there a way to only edit the files that contain the old values?
I guess you could do if(select-string "$oldip|$oldhost|${olddriveletter}:\\folder" $_ -quiet), but I don't see much advantage in it.
That's the ticket! I didn't initially see much advantage in it either, but it messed up a few special characters on a file that didn't really need to be edited. Added that line and everything matches up perfectly now. THANK YOU!
0

I suggest to:


## Q:\Test\2019\05\09\SO_56064191.ps1

$oldIP = "192.168.1.2"
$newIP = "192.168.1.3"
$oldhost = "OLDHOSTNAME"
$newhost = "NEWHOSTNAME"
$oldDriveLetter = "C"
$newDriveletter = "E"

$path = '\\{0}\{1}$\Folder' -f $newip,$newdriveletter

ForEach($File in (Get-ChildItem $path\* -Include *.xml,*.config -Recurse)){
    (Get-Content $File.FullName -raw) -replace [RegEx]::Escape($oldhost),$newhost `
                                 -replace [RegEx]::Escape($oldip),$newip `
                                 -replace "$olddriveletter(?=:\Folder)",$newDriveLetter | 
     Set-Content $File.FullName -NoNewline
}

4 Comments

This is definitely close to where I want to be, but it appears to be adding a blank line to the end of every file that I'm editing. Any idea how to prevent that?
Try to append the -NoNewline parameter to Set-Content $File.FullName -NoNewline
Yeah, I tried that. It actually takes my entire file and puts it all on a single line. That's no good either.
You've to also append the -raw parameter to the Get-Content reference

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.