Eric Liu
Eric Liu

Reputation: 13

Using powershell to duplicate file and change file name with datetime

I would like to move a file to another folder to become two files with different file name with datetime, prefix and specific characters. Then remove the original file after completion.

For example, I have c:\source\aaa.pdf and want it to be duplicated to

Now I was stuck at even only file name changing, I tried

Get-ChildItem *.pdf | rename-item -newname ('12345'+'_TPE'+$_.Name+'_'+(Get-Date -f yyyymmddhhmmss)+'.pdf') 

but the original name will not be included.

Can any expert please help?

Upvotes: 1

Views: 1149

Answers (4)

henrycarteruk
henrycarteruk

Reputation: 13217

You can loop through the files you're getting from Get-ChildItem using ForEach-Object.

Then copy the file to each destination as the new name. This saves copying then renaming the file.

Then lastly delete the original file from source.

$source = "c:\source"
$destination = "C:\destination"

Get-ChildItem -Path $source -Filter *.txt | ForEach-Object {
    $date = Get-Date -Format yyyyMMddhHHmmss
    Copy-Item -Path $_ -Destination "$destination\12345_TPE_$($_.Basename)_$date.pdf"
    Copy-Item -Path $_ -Destination "$destination\12345_TXG_$($_.Basename)_$date.pdf"
    Remove-Item -Path $_
}

Upvotes: 0

user6811411
user6811411

Reputation:

I like the way Joey took it modular, to extend on this

## Q:\Test\2018\06\14\SO_50852052.ps1
$Src = 'C:\Source'
$Dst = 'c:\destination'
$Prefix = '12345'
$Types = 'TPE','TPG'

Get-ChildItem -Path $Src *.pdf | ForEach-Object {
    ForEach ($Type in $Types){
        $_ | Copy-Item -Destination (Join-Path $Dst (
        "{0}_{1}_{2}_{3:yyyyMMddHHmmss}.pdf" -f $Prefix,$Type,$_.Basename,(Get-Date)))
    }
    $_ | Remove-Item 
}

Upvotes: 0

Vivek Kumar Singh
Vivek Kumar Singh

Reputation: 3350

Here's the other part to your problem -

$source = "C:\Source"
$dest = "C:\Destination"
$files = Get-ChildItem *.pdf 
foreach($file in $files)
{
    $filename1 = '12345'+'_TPE_'+$file.Basename+'_'+(Get-Date -f yyyymmddhhmmss)+'.pdf'
    $filename2 = '12345'+'_TXG_'+$file.Basename+'_'+(Get-Date -f yyyymmddhhmmss)+'.pdf'
    Copy-Item $file.FullName -Destination $dest -PassThru | Rename-Item -NewName $filename1
    Copy-Item $file.FullName -Destination $dest -PassThru | Rename-Item -NewName $filename2
    Remove-Item $file.FullName -Force
}

Could have made that smaller with continuous pipes, but the present one is easier to understand and looks cleaner.

Upvotes: 0

Joey
Joey

Reputation: 354416

This is a rather easy fix, actually: $_ only exists in scriptblocks that are arguments to cmdlets. You've been using normal parentheses, which are not a scriptblock. Just change it as follows:

Get-ChildItem *.pdf | rename-item -newname {'12345'+'_TPE'+$_.Basename+'_'+(Get-Date -f yyyyMMddhHHmmss)+'.pdf'}

(Also, your date format string is suspect, as you include minutes instead of months there; I've fixed that.)

Or, as a slightly easier to read alternative using a single format string, maybe:

Get-ChildItem *.pdf |
  Rename-Item -NewName { '{0}_TPE_{1}_{2:yyyyMMddHHmmss}.pdf' -f 12345,$_.Basename,(Get-Date) }

Upvotes: 2

Related Questions