I get errors when trying to rename files - powershell

I have files in a folder C:\Users\xxx\Documents\Projects\files\old\. I have built a loop to rename them but it doesn't work out:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName $newfiles+"$($entry.Custom_ID).$($file.BaseName).PDF"
How do I concatenate properly $newfiles to the rename path? I tried everything but keep getting errors:
Rename-Item : A positional parameter cannot be found that accepts argument '-'

you need to either copy and rename or move and rename files.using -whatif is a good practise because it shows you what is going to happen if you execute a particular command.
Notice also i am using a filter to get-childitem to only get the pdf files so that i know that the files i am going to rename will only be pdf files. of course if the oldfiles folder only contains pdf files then you dont need to use the filter.
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
$oldfiles = "C:\Users\xxx\Documents\Projects\files\old\"
Get-ChildItem -Path $oldfiles -Filter *.pdf |
Move-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
or
Get-ChildItem -Path $oldfiles -Filter *.pdf |
copy-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf

This is how I always concatenate things in Powershell:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName ("{0}{1}.PDF" -f $newfiles,$($entry.Custom_ID).$($file.BaseName))
From experience, this always works.

Related

Place files with prefix in folder with number

I have batch changed multiple files that all start with a prefix of a folder where I need them in.
The files are located on another location, like a folder on the desktop.
For example:
101AA0001.dat
101AA0002.dat
102AA0001.dat
102AA0002.dat
The destination folder will for example be:
C:\destfolder\101\ or C:\destfolder\102\
Files starting with 101 need to go in the 101 folder and the files starting with 102 go to folder 102.
I can find some scripts that creates the folder based on the filename. But in this situation the folders already exist. I also know for sure the files don't exist, so I don't have to overwrite files or something.
I guess it is easy for the people that know PowerShell very well, but I don't know how to do this. Can someone please help me? This can save me a lot of time.
I have tried to move the files with the following rule:
Move-Item -Path C:\Users\Username\Desktop\test*.dat -Destination C:\Users\Username\Desktop\test2\ -include "*.dat"
But it copies the whole folder except for the files.
You can do that quite easily with code like below:
$sourceFolder = Join-Path -Path $env:USERPROFILE -ChildPath 'Desktop'
$destination = 'C:\destfolder'
Get-ChildItem -Path $sourceFolder -File -Filter '*.dat' | ForEach-Object {
$targetFolder = Join-Path -Path $destination -ChildPath $_.Name.Substring(0, 3)
# if the target folder does not exist yet, create it
if (!(Test-Path -Path $targetFolder -PathType Container)) {
$null = New-Item -Path $targetFolder -ItemType Directory
}
$_ | Move-Item -Destination $targetFolder -WhatIf
}
The -WhatIf switch shows what would happen in the console without actually performing the move. If you are satisfied with what is output, remove that switch.
This will take all files that end in ".dat" from the $Source folder into a subfolder inside the $DestinationRoot named for the first three characters of the ".dat" file.
$Source = "C:\Users\Username\Desktop"
$DestinationRoot = "C:\Users\Username\Desktop\test2"
$Filelist = Get-ChildItem -Path $Source -Filter "*.dat" -File
foreach ($File in $Filelist){ $DestinationFolder = $File.Name.Substring(0,3)
$FinalPath = "$DestinationRoot\$DestinationFolder"
Move-Item -Path $File.Fullname -Destination $FinalPath -Whatif }
Remove the -Whatif when you're ready to run it for real.
This doesn't handle folder creation and should error out if the file already exists in the target location so it won't accidentally overwrite anything.

Replace Part of Filename if Filename Already Exists

In this question, How do I rename part of a filename, if the newly renamed filename already exists? Want the newly attempted filename to overwrite the existing file. Also want to rename folders within folders within folders.
Replace "Default" with "VOD" in filename,
Replace Part of File Name Powershell
Get-ChildItem Default_*.csv |
Rename-Item -NewName {$_.Name -replace '^Default','VOD'}
ls *.csv | Rename-Item -NewName {$_.Name -replace "Default","VOD"}
Solution here was not working with -Force:
Get-ChildItem *.* -File -Recurse |
Rename-Item -NewName {$_.Name -replace 'Default','VOD'} -Force
As per this question and answer: rename-item and override if filename exists
Use Move-Item and -Destination, and also swap $_.Name for $_.FullName (if you don't do that it will throw everything into your current directory, because Name is just the name of the file, not the full path). Check using -WhatIf to see what operations will be carried out, just in case:
With -WhatIf:
Get-ChildItem *.* -File -Recurse |
Move-Item -Destination {$_.FullName -replace 'Default','VOD'} -WhatIf
Output:
What if: Performing the operation "Move File" on target "Item: C:\temp\pstest\Default_77.txt Destination: C:\temp\pstest\VOD_77.txt".
Now with -Force:
When you're comfortable with the output from using the -WhatIf parameter, change it to -Force to complete the file move.
Get-ChildItem *.* -File -Recurse |
Move-Item -Destination {$_.FullName -replace 'Default','VOD'} -Force

powershell copy all folder structure and exclude one or more folders

I'm trying to use PowerShell to copy a folder with sub-folders from our users to a small backup. These folders contain a folder called "windows" I don't want to copy.
I have tried "exclude" but can't seem to get it to work.
This is the script so far:
Copy-Item "E:\Curos folder" -Exclude 'Windows' -Destination "E:\Curos folder backup" -Recurse -Verbose
I have read other posts but don't quiet understand how it works
It's my first time working with PowerShell
You are complete right.
Actually the script it's simpler than the one I have wrote before.
Here we go:
$source = "C:\Users\gaston.gonzalez\Documents\02_Scripts"
$destination = "D:\To Delete"
$exclude = "Windows"
$folders = Get-ChildItem -Path $source | Where {($_.PSIsContainer) -and ($exclude -notcontains $_.Name)}
foreach ($f in $folders){
Write-Host "This folders will be copied: $f"
Copy-Item -Path $source\$f -Destination $destination\$f -Recurse -Force
}
I'd use something like this:
Get-ChildItem $root -Directory -Recurse | % {$_.name -ne 'Windows'} | foreach {Copy-Item "$($_.FullName)" -Destination $dest -Recurse}
I haven't tested it but it's the skeleton of something you should be able to make work, although I don't find the point of using recurse on both, Get-ChildItem and Copy-Item my advice is to use it on Get-ChildItem.

Recursively compare file contents from two folders, archive if different, then copy

I have been asked to put together this utility in a hurry which will compare files in source/destination folders, check if different, and if so, archive the file in destination via renaming and copy the source file over. I dug around some of the commands and looked at things like Compare-Object -Recursive, however I'm not sure if this is the correct command. This is my progress so far:
get-childitem -recurse $source | Where-Object {$_.Name -eq (Get-ChildItem -recurse $destination)} | Copy-Item -recurse -path "$source\*" -destination $destination -force
But I don't think this is correct. Would greatly appreciate being pointed in the right direction here.
This is an example how you can compare with the compare command.
$items1 = Get-ChildItem -Path C:\temp -Recurse
$items2 = Get-ChildItem -Path C:\temp2 -Recurse
$diffent = Compare-Object -ReferenceObject $items1 -DifferenceObject $items2
foreach($item in $diffent){
$path = $item.InputObject.FullName
#copy the item with the path in the variable $path
}

Copy all files and folders from a source folder to multiple folders with a specic name

I have a source folder(c:\test*) and I want that folder copied to all folders in the same location (c:\resultaat) but only to the folders in that location that contains the name demo_profit.
I think I'm almost there, but I'm missing a small part I think.
$destination = get-item -include demo_profit* -path C:\resultaat\*
copy-item C:\test\* $destination -recurse -force
thanks for your help
The -Directory parameter of Get-ChildItem requires AFAIK PSv5
Get-ChildItem -Directory -Path 'C:\resultaat\' | ForEach-Object{
if (Test-Path (Join-Path $_.FullName 'demo_profit')){
Copy-Item C:\test\* $_.FullName -recurse -force
}
So it is not clear if you want to copy the files to a folder containing an item named demo_profit, or to folder with demo_profit in the name. The second is simple, so I'll start there:
Get-ChildItem C:\resultaat\* -Directory |
Where{$_.Name -match 'demo_profit'} |
ForEach{ Copy-Item C:\test\* -dest $_.FullName -recurse -force }
That finds any folder within c:\resultaat that has 'demo_profit' as part of its name, and copies the desired files/folders into that folder. Example: C:\resultaat\Folder1_demo_profit would have all the files from C:\temp copied into it.
If you are looking for things named demo_profit, and want to copy the files into the same folder as that item you need to use the PSParentPath property, and some wildcards.
Get-ChildItem c:\resultaat\*\*demo_profit*
This command would find a file or folder with a path such as 'C:\resultaat\Amazon\az_demo_profit'. Then to copy files into the folder containing that you would use the PSParentPath property as such:
Get-ChildItem c:\resultaat\*\*demo_profit* |
Select -Expand PSParentPath -Unique
ForEach{ Copy-Item C:\test\* -dest $_ -recurse -force }