0
votes

I am new to PowerShell and trying to write my first script to copy files from one directory to another and then rename the files in the $DESTINATION directory once they are copied over there.

I am executing the script below from C:\Scripts directory on my machine.

The first foreach loop works great and my files land in the $DESTINATION.

But when I to through the 2nd loop I get the errors below

Any help/direction would be appreciated. Thanks.

Here is my code:

# Define variables.
$Source = "C:\ETLFILES\WinSCP\FilesETL\*.*"
$Destination = "C:\ETLFILES\WinSCP\SFE_Archive\"
$DestinationFiles = "C:\ETLFILES\WinSCP\SFE_Archive\*.*"

# Create the $sourceFileList variable to loop through
$sourceFileList = Get-ChildItem -path $Source 

# Loop through the $soureFileList and copy the items to the $Destination.
foreach ($item in $sourceFileList) {
    Copy-Item -Path $Source -Destination $Destination
}

# Create the $destinationFileList variable to loop through 
$destinationFileList = Get-ChildItem -path $DestinationFiles

# Loop through the $destinationFileList and rename the files with appended DateTime stamp.
foreach ($itemDest in $destinationFileList) {
    $Date = (Get-Date).ToString("yyyyMMdd_HHmmss")
    $newFileName = $Date + "_" + $itemDest
    Rename-Item $itemDest $newFileName
}

Here are the errors I'm getting and I think that I need to change the -path as it is looking to where the script is executing from and not looking at the $DestinationFiles directory like it looked to the $Source above:

PS C:\Scripts> C:\Scripts\ArchiveSFE_files.ps1 Rename-Item : Cannot rename the specified target, because it represents a path or device name. At C:\Scripts\ArchiveSFE_files.ps1:21 char:5 + Rename-Item $itemDest $newFileName + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Rename-Item], PSArgumentException + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand

Rename-Item : Cannot rename the specified target, because it represents a path or device name. At C:\Scripts\ArchiveSFE_files.ps1:21 char:5 + Rename-Item $itemDest $newFileName + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Rename-Item], PSArgumentException + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand

Rename-Item : Cannot rename the specified target, because it represents a path or device name. At C:\Scripts\ArchiveSFE_files.ps1:21 char:5 + Rename-Item $itemDest $newFileName + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Rename-Item], PSArgumentException + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand

Rename-Item : Cannot rename the specified target, because it represents a path or device name. At C:\Scripts\ArchiveSFE_files.ps1:21 char:5 + Rename-Item $itemDest $newFileName + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Rename-Item], PSArgumentException + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand

PS C:\Scripts>

4
What errors do you get? And what is your version of powershell?Andrey Marchuk
Sorry for not copying the errors. I'm revising the code and trying to simplify. I'll edit my code above and I'll put in the new errors below. Thanks for the quick response.Melinda
I'm using PS version 4.0Melinda
Try putting your '\' at the end of both paths in the declaration. Better style and might help resolve the issue too...Austin T French

4 Answers

5
votes

PowerShell can be a bit tricky if you're used to text-based languages and tools, because everything in PowerShell is a .NET object.

This line:

$newFileName = Get-Date + "_" + $item # .ToString("yyyyMMdd-HHmmss") + "_" + $item

will most certainly result in an error. Get-Date returns a [datetime] object.
Although [datetime] does support the + operator, it expects an argument of the type [timespan] - and the string "_" can't be converted to a timespan.

What you want is a string representing the current date. Either use the ToString() statement that you've commented out, or use the -Format parameter to produce a formatted string instead of a [datetime] object:

$newFileName = (Get-Date).ToString("yyyyMMdd-HHmmss") + "_" + $item

or

$newFileName = (Get-Date -Format "yyyyMMdd-HHmmss") + "_" + $item
4
votes

I'm not a betting man, but I'll bet the error you're having is this one.

Get-Date : Cannot bind parameter 'Date'. Cannot convert value "+" to type "System.DateTime". 
Error: "String was not recognized as a valid DateTime."

This is because the code you've got here is trying to add a character to a PowerShell DateTime object, and that simply does not fly. You can pick a single property though and concatenate characters onto that, however.

But, I noticed that you commented out some lines in your code, and am guessing that you'd like to get the date in this format: "yyyyMMdd-HHmmss".

If that's so, this little snippet will do that for you:

# Define logic to rename and copy .
foreach ($item in $sourceFileList) {
    $newFileName = $(Get-Date -UFormat %Y%m%d-%H%m%S)  + "_" + $item 
    "the item $($item.BaseName) would become $newFileName"
    }

This will output to the screen the new name for the file, like this:

the item q1 would become 20160921-110907_q1.png

the item q2 would become 20160921-110907_q2.png

the item q3 would become 20160921-110907_q3.png

You can comment out that line once you're happy with the new name. And the best part? Just drop this into your code inplace of your current $newFileName line and it will work with your previous code.

If I'm wrong, let me know the error you're getting and I'll help you get this sorted.

2
votes

Looks like you are trying to write a file with : in the time part of the Get-Date when you try to rename to $newFileName. This will kick an error out.

$Date = Get-Date.ToString("yyyyMMdd_HHmmss")
$newFileName = $Date + "_" + $item

Include the above and that should prevent that problem.

0
votes

thanks for everyone's help and input. I really appreciate it. I was finally able to resolve my problem whereby in the variable assigned in the foreach loop the FULL PATH was being defined that is what was generating the errors above. Once I used the .NAME property the issue was resolved. Thanks again to everyone.