1

Powershell V3 (there is a TL;DR version at the bottom of the full description)

I am a little new to coding but adapting with the times, and practicing by solving / making more efficient some tasks at work - I am currently writing a script to automate a daily file management task (there's already a batch file, but that's not educational!). I want to write a powershell script that is easy for a future administrator to troubleshoot/adapt if necessary and include Best Practices techniques such as meaningful error messages.

This one is a little tricky, or really simple if I'm missing something....

In MS-DOS, what I want to do would be pretty simple because destination sources accept wild-cards on the extension of files.

example (file structure is below): copy Group01.* RnGrp01.*

I could brute force every item in the directory, since the start of the name never changes, just the extension... but that would be way too many code lines and annoying for a future admin since they'd have to upkeep it whenever additional files were added to the directory.

Directory (Child) Items Example: Note: x, y, and z are numbers - these numbers will go from variable numbers from 100 to 500

Group01.x.3
Group02.y.3
Group03.z.3

I need to keep all files with the START of name Group01 together, and all files with Group02 together, and all files with Group03 together - and rename them to have a different name, while keeping the number contained within x, y, and z the same.

Further example - expected result after running:

Group01.100.3 -> RnGrp01.100.3
Group01.101.3 -> RnGrp01.101.3
Group02.100.3 -> RnGrp02.100.3
Group02.101.3 -> RnGrp02.101.3
Group03.100.3 -> RnGrp03.100.3
Group03.101.3 -> RnGrp03.101.3

What I tried that almost worked ($datestamp is a get-date.tostring and works perfect, tested through write-hosts):

Get-ChildItem $dest\Group01.* | foreach {Rename-Item $_ $_.Name.Replace("Group01","$datestamp_RnGrp01")}
Get-ChildItem $dest\Group02.* | foreach {Rename-Item $_ $_.Name.Replace("Group02","$datestamp_RnGrp02")}
Get-ChildItem $dest\Group03.* | foreach {Rename-Item $_ $_.Name.Replace("Group03","$datestamp_RnGrp03")}

-----> THIS KIND OF ALMOST WORKED. The result was 2 files and an error

Rename-Item : Cannot create a file when that file already exists.

The 2 files:

.100.3
.101.3

so it kept the extensions but removed the name entirely... which is just weird.

WHAT I TRIED THAT DIDN'T WORK, THAT I THOUGHT SHOULD: (brute-force, kind of, but still scalable for the environment its being used in):

Get-ChildItem "$dest\Group01.*" | Copy-Item -Dest {"$dest\$datestamp_majsales.${_}"}
  • this throws a directory error, even though the directory is valid.

TL:DR version:

MS-DOS code:

copy Group01.* %dateformula%_RnGrp01.* 
copy Group02.* %dateformula%_RnGrp02.*
copy Group03.* %dateformula%_RnGrp03.*

Further example - expected result after running:

Group01.100.3 -> RnGrp01.100.3
Group01.101.3 -> RnGrp01.101.3
Group02.100.3 -> RnGrp02.100.3
Group02.101.3 -> RnGrp02.101.3
Group03.100.3 -> RnGrp03.100.3
Group03.101.3 -> RnGrp03.101.3

Does not work:

Get-ChildItem $dest\Group01.* | foreach {Rename-Item $_ $_.Name.Replace("Group01","$datestamp_RnGrp01")}
Get-ChildItem $dest\Group02.* | foreach {Rename-Item $_ $_.Name.Replace("Group02","$datestamp_RnGrp02")}
Get-ChildItem $dest\Group03.* | foreach {Rename-Item $_ $_.Name.Replace("Group03","$datestamp_RnGrp03")}

Please help.

1 Answer 1

1

Seems to me you want something more like this:

Get-ChildItem $dest\Group*.* | 
    Rename-Item -NewName {$_.Name -replace 'Group(\d\d)',"${datestamp}_RnGrp`$1"} -Whatif

Part of your problem is that the variable name in this double quoted string "$datestamp_RnGrp01" is interpreted to be datestamp_RnGrp01 - a perfectly valid variable name. I think you want the variable name to be datastamp though. That is were the {} come in e.g. "${datestamp}_RnGrp0". This tells PowerShell where the variable name starts and stops in a double quoted string.

You can also get rid of the Foreach and pipe directly into Rename-Item. Since the NewName parameter is pipeline bound, you can provide its argument via a scriptblock where $_ is mapped to the current pipeline object.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm going to give this a try! You're right in that I was totally not thinking about $datestamp_RnGrp01 being a totally valid variable name, which doesn't exist, which completely explains why I got blank. Also, it's datestamp since it attaches part of the date to the file. I didn't know about the syntax for the {}, and really appreciate that education! I'll mark this as an answer if it works (which I think it will), THanks!

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.