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

Christopher Cass
  • 817
  • 4
  • 19
  • 31
  • You have a comma after `*.config`. It should not be there since your array ends there. – AdminOfThings May 09 '19 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? – Christopher Cass May 09 '19 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"` – AdminOfThings May 09 '19 at 17:26

2 Answers2

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 $_ 
}
js2010
  • 23,033
  • 6
  • 64
  • 66
  • 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? – Christopher Cass May 20 '19 at 18:50
  • I guess you could do `if(select-string "$oldip|$oldhost|${olddriveletter}:\\folder" $_ -quiet)`, but I don't see much advantage in it. – js2010 May 20 '19 at 18:56
  • 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! – Christopher Cass May 20 '19 at 19:54
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
}
  • 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? – Christopher Cass May 09 '19 at 18:52
  • Try to append the `-NoNewline` parameter to `Set-Content $File.FullName -NoNewline` –  May 09 '19 at 19:17
  • Yeah, I tried that. It actually takes my entire file and puts it all on a single line. That's no good either. – Christopher Cass May 09 '19 at 19:19
  • You've to also append the `-raw` parameter to the `Get-Content` [reference](https://stackoverflow.com/questions/45266461/set-content-appends-a-newline-line-break-crlf-at-the-end-of-my-file) –  May 09 '19 at 19:23