2

I have hundred thousands files located in ~40 folders (these subfolders being located in a same super-folder which I am going to call 'test'). I have tried to use powershell to replace a syntax found in the folder name but also in the filenames.

Basically my folders and files contains the same string of characters "PXXXX_0" that I want to batch rename in "PXXXX_"

Here is the code I used to first map the files & folders of interest

cd C:\test

Get-ChildItem -Filter "*PXXXX_0*" -Recurse | Rename-Item -NewName {$_.name -replace 'PXXXX_0', 'PXXXX_'} -whatif

This gives me the right files and previewed action (e.g.

What if: Performing operation "Rename File" on Target "Item: C:\test\PXXXX_053\PXXXX_053_558.jpg Destination C:\test\PXXXX_053\PXXXX_53_558.jpg

So this seems to work, but only on the files inside the folders that I also want to rename.

Now if I launch the code without -whatif it appears that only the folder names are rename, not the files...

I pretty sure I have missed something but since I am not really familiar with this language, I am struggling to find the solution. I am using Powershell v1.0

Thanks for any help.

Best

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Rhiz
  • 23
  • 6
  • 4
    Presumably once the folder is renamed, the file paths inside the folder are wrong because the folder no longer exists under that name. Try renaming the files first by filtering `.. -Recurse|where-object { -not $_.PsIsContainer } | Rename-Item ..` and then redo it to rename the folders, maybe? – TessellatingHeckler Jul 06 '17 at 18:24
  • Thanks, it worked like a charm ! – Rhiz Jul 06 '17 at 20:31

1 Answers1

3

One Liner:

 $items = get-childitem -filter "*PXXXX_0*" -Recurse; foreach ($item in $items) { $newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_'; rename-item $item.fullname -NewName $newName; }

Easy on the eyeballs:

$items = get-childitem -filter "*PXXXX_0*" -Recurse;
foreach ($item in $items) { 
  $newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_'; 
  rename-item $item.fullname -NewName $newName; 
}

In short, PowerShell 1 was trying to rename the file with just the file name, not the full path. Basically it was not able to find your files when they were in subfolders.

I tested your logic in v5 and it works like you would expect it to.

I'm going to go out on a limb here and assume you are trying to run this script via System Center Orchestrator since you are working with PowerShell v1. I've felt that pain. I recommend wrapping all your PS scripts headed for runbooks in invoke-command -scriptblock {} -Credential $myCreds blocks. This promotes the execution to the target system's version of PowerShell. It also makes it very easy to tack on a -ComputerName to run the script on the target instead of the runbook server.

You can then store a username and password pair as Orchestrator variables ( use the encryption option ) and insert them in your get-credential statement above. It feels very messy at first but you get used to it.

to test this, I ran PowerShell with -version 1. Here is my $PSVersionTable:

Name                           Value
----                           -----
CLRVersion                     2.0.50727.8689
BuildVersion                   6.1.7600.16385
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

It had the same problem but it might not be a 1 for 1 match to what Orchestrator is going to run in. Post Output if it does not work and I'll do my best.

Ty Savercool
  • 1,132
  • 5
  • 10