6

I've been doing my best to get more familiar with PowerShell as a way to automate many of our regular tasks in an effort to eliminate human error. I support a web based application, and my current goal is to create a script to migrate the application from one server to another. So far I've gotten the script to install the application on the new server, copy the configuration files from the old server, and backup all the files prior to making any additional changes. The last thing I need to do is search through the configuration directory and all sub folders to replace all instances of the hostname, the IP address, and the directory location (in the event the drive letter changes on the new server) There is a folder called X:\Website\Tools\Database\Upgrade that contains a folder for every version that the customer has ever been on, and within that folder is the database upgrade script. I do not have permission to change anything in this folder, and frankly don't really care to change anything within X:\Website\tools.

I have written this portion of the script as follows:

#Replace all instances of hostname, IP address, and drive letter
$path = "\\$newip\$newdriveletter$\Website"
$exclude = @("$path\tools\*")
$files = get-childitem $path\*.* -recurse -exclude $exclude 
$files | %{
    (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -replace 
"${olddriveletter}:\Website", "${newDriveLetter}:\Website" | set-content 
$_.fullname
}

When I do this, it replaces everything I'm wanting it to replace, but it's still throwing the following error:

gc : Access to the path 
'\\10.5.17.60\E$\Website\Tools\Database\Upgrade\6.2.0' is denied.
At C:\Folder\Powershell\Migrate.ps1:72 char:6
+     (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -repl ...
+      ~~~~~
     + CategoryInfo          : PermissionDenied: 
(\\10.5.17.60\E$...e\Upgrade\6.2.0:String) [Get-Content], 
UnauthorizedAccessException
    + FullyQualifiedErrorId : 

I've also read that the -exclude parameter is pretty much broken in PowerShell and doesn't work well for excluding folders. The suggestion was to format it like so:

#Replace all instances of hostname, IP address, and drive letter
$path = "\\$newip\$newdriveletter$\Website"
$files = get-childitem $path\*.* -recurse | select-object -expandproperty 
fullname | where-object{$_ -notlike "\\tools\\"}
$files | %{
(gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -replace "${olddriveletter}:\Website", "${newDriveLetter}:\Website" | set-content $_.fullname
}

Unfortunately, when I run this, I get the error:

Set-Content : Cannot bind argument to parameter 'Path' because it is null.
At C:\Folder\Powershell\Migrate.ps1:72 char:151
+ ... \WebAccess", "${newDriveLetter}:\Website" | set-content $_.fullname

So basically I've achieved the end goal, but I'd really like to do this without any errors popping up. If people start running this and see red they're likely to freak out. So I'm thinking there has to be a way to exclude even looking into these folders. Possibly an If statement, but I'm not quite sure how to format that. Any suggestions?

1
  • Remove .fullname from set-content $_.fullname Commented May 1, 2017 at 22:35

2 Answers 2

6

If you just run

get-childitem $path\*.* -recurse -exclude $exclude 

you should see that it's still returning the folder you are trying to exclude. This is because get-childitem -exclude doesn't work on containers.

Instead try

$files = get-childitem $path\*.* -recurse | where-object{$_.fullname -notlike $exclude}
Sign up to request clarification or add additional context in comments.

11 Comments

gc : Access to the path '\\10.5.17.60\E$\Backups\Website Backups\Website 6.3.1' is denied. At C:\Backups\Powershell\Migrate.ps1:72 char:6 + (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -repl ... + ~~~~~ + CategoryInfo : PermissionDenied: (\\10.5.17.60\E$...Website 6.3.1:String) [Get-Content], UnauthorizedAccessException + FullyQualifiedErrorId : GetContentReaderUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetContentCommand
That's the error I'm seeing now... My $path variable is to \\10.5.17.60\E\Website. Any idea why it's trying to hit a folder that's not in that directory?
there was supposed to be a "\" in there.. had a little trouble getting it to show up I'm assuming $newip = '10.5.17.60' and $newdriveletter = 'E'
It seems to work without the \ and breaks with the \. Only issue is without the \ it seems to be trying to hit a folder that's not in the path. Path is \\10.5.17.60\E$\Website. Any idea why it's trying to hit \\10.5.17.60\Backups...? That's not in the $path...
what are all you're variables set to? did you change any of the code in your original question? I understand it previously was doing what you wanted - only that it was hitting the \tools directory and giving you the error, correct? Is that still the case with your original code?
|
0

Not sure if there's a difference in PS version (I'm using 4) .. but there were a few tweaks i had to do to get it to work. This is how i did my test...

$oldhost = "RBABBITT1"
$oldip = "192.168.1.21"
$olddriveletter = "C"

$newhost = "RBABBITT2"
$newip = "192.168.1.22"
$newdriveletter = "D"


$path = "\\$newip\$newdriveletter$\test1"
$exclude = "$path\tools\*"
$files = get-childitem $path -Recurse | where-object{$_.fullname -notlike $exclude -and $_.PSIsContainer -eq $false}
$files | %{
    (gc $_.FullName) -replace $oldhost, $newhost -replace $oldip, $newip -replace [regex]::Escape("${olddriveletter}:\Website"), "${newDriveLetter}:\Website" | set-content $_.fullname
}

Comments

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.