We had a syncing issue that affected thousands of files.
A backup of the correct files was created in each folder by the sync tool. the backup has " -LocalPCName" added before the dot before the extension.
I am really a beginner in powershell.
I am trying to write a powershell script to go trough every folder and check if a file backup was create d for each file.
If a backup was created, I want to rename the file to add " -Wrongversion" and remove the " -LocalPCName" from the correct file.
This will basically recover the file to the correct version and make a copy of the wrong version.
I wrote this code but i am blocked at trying to match using -replace
Get-ChildItem *.* |
ForEach-Object {
If ($_.name -match "\s-LocalPCName")
{Get-ChildItem $_.Name -replace "\s-LocalPCName",""
}
}
Thank you for your help!
here is a newer version of my code but i get errors and i am concerned of using recurse, am i missing anything when this will go to subfolders? In this code, the LocalPCName is Didi2015
Get-ChildItem *.* -recurse|
ForEach-Object {
If ($_.name -match "\s-Didi2015")
{
$OldName = $_.Name -replace "\s-Didi2015",""
$dir=$_.DirectoryName
$ext = $_.Extension
$file = $OldName.Substring(0, $OldName.LastIndexOf('.'))
Write-Output $dir
Write-Output $ext
Write-Output $file
$Newname = $file + " -Wrongversion" + $ext
Write-Output $Newname
Rename-Item -Path $OldName -NewName $Newname -WhatIf
Rename-Item -Path $_ -NewName $OldName -WhatIf
}
}
Here is my final code. it works.
dir *-Didi2015*.* -Recurse|
ForEach-Object {
If ($_.name -match "-Didi2015")
{
$OldName = $_ -replace "-Didi2015",""
$dir=$_.DirectoryName
$ext = $_.Extension
$file = $OldName.Substring(0, $OldName.LastIndexOf('.'))
# Write-Output $dir
# Write-Output $ext
# Write-Output $file
# Write-Output $OldName
# Write-Output $Newname
# Write-Output $_.Name
$Newname = $file + "-Wrongversion" + $ext
Rename-Item -Path $OldName -NewName $Newname -WhatIf
Rename-Item -Path $OldName -NewName $Newname -Force
Rename-Item -Path $_ -NewName $OldName -WhatIf
Rename-Item -Path $_ -NewName $OldName -Force
}
}
Related
Windows 10 64 BIT
Scenario: copy files in a directory and subdirectory to the destination directory.
File Type: Only pdf
Issue: When the file name has special characters not able to copy
Tried below code not working
#Get all files and not the directories
$files = Get-ChildItem -Path "c:/source" -Recurse -filter "*.pdf" | Where {$_.PSIsContainer -eq $false}
#Copy items from sources to new destination
foreach ($file in $files)
{
if ($file.Name -match '[^a-zA-Z0-9]')
{
$file.FullName
*$file.FullName | Rename-Item -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '} $NewName
*Rename-Item -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '}
*$NewName = rename-item $file.FullName.Replace('_*(\[*?\]|\(*?\))_*', '')
Rename-Item -Path $file.fullName -NewName {$_ -replace '_*(\[.*?\]|\(.*?\))_*' -replace '_+', ' '}
}
Copy-Item -Path $file.FullName -Destination "c:/desination\"
}
How can i copy only the folders in a directory with powershell and robocopy?
Get-ChildItem 'C:\temp\test' |
ForEach-Object {
$newname = ($_.BaseName -Replace '[^\x20-\x5D,\x60-\x7E]+', '-')
write-host $_.BaseName
write-host $newname
robocopy.exe 'C:\temp\test\'$_.BaseName 'C:\temp\test\copy\'$newname
}
Edit
Thanks works great
Get-ChildItem 'C:\temp\test' |
ForEach-Object {
$newname = ($_.BaseName -Replace '[^\x20-\x5D,\x60-\x7E]+', '-')
if (($_.GetType()).Name -eq "DirectoryInfo"){
write-host "folder"
}
write-host $_.BaseName
write-host $newname
robocopy.exe "C:\temp\test\$($_.BaseName)" "C:\temp\test\copy\$newname"
}
Corrected errors, modified code below.
Get-ChildItem 'C:\temp\test' |
ForEach-Object {
$newname = ($_.BaseName -Replace '[^\x20-\x5D,\x60-\x7E]+', '-')
write-host $_.BaseName
write-host $newname
robocopy.exe "C:\temp\test\$($_.BaseName)" "C:\temp\test\copy\$newname"
}
You could do something like:
$items = Get-ChildItem 'C:\temp\test'
foreach($item in $items){
if(($item.GetType()).Name -eq "DirectoryInfo"){
$newname = ($item.BaseName -Replace '[^\x20-\x5D,\x60-\x7E]+', '-')
Write-Host $item.BaseName
Write-Host $newname
robocopy.exe "C:\temp\test\$($_.BaseName)" "C:\temp\test\copy\$newname"
}else{
Write-Host "$item is not a directory"
}
}
newbie here. I am trying to write a PowerShell script to:
loop through all files in directory
List item
Get all .pdf files ONLY
Rename them-the file names are long - over 30 chars
-They contain 2 numbers which I need to extract
-Example:
Cumulative Update 11 for Microsoft Dynamics NAV 2018 (Build 25480).pdf ->
RESULT : = 18CU11.pdf
I tried examples from bunch of sites and I can't seem to even loop successfully.
Either get an error - that path doesn't exist or that can't rename files as somehow loop gets a filepath and that I can't rename
Get-ChildItem "C:\Users\******\Desktop\PowerShell Practice" -Filter *.pdf | #create list of files
ForEach-Object{
$oldname = $_.FullName;
$newname = $_.FullName.Remove(0,17);
#$newname = $_.FullName.Insert(0,"CU")
Rename-Item $oldname $newname;
$oldname;
$newname; #for testing
}
That's just latest attempt, but any other ways of doing it will be fine - as long as it does the job.
Try this logic:
[string]$rootPathForFiles = Join-Path -Path $env:USERPROFILE -ChildPath 'Desktop\PowerShell Practice'
[string[]]$listOfFilesToRename = Get-ChildItem -Path $rootPathForFiles -Filter '*.PDF' | Select-Object -ExpandProperty FullName
$listOfFilesToRename | ForEach-Object {
#get the filename wihtout the directory
[string]$newName = Split-Path -Path $_ -Leaf
#use regex replace to apply the new format
$newName = $newName -replace '^Cumulative Update (\d+) .*NAV 20(\d+).*$', '$2CU$1.pdf' # Assumes a certain format; if the update doesn't match this expectation the original filename is maintained
#Perform the rename
Write-Verbose "Renaming '$_' to '$newName'" -Verbose #added the verbose switch here so you'll see the output without worrying about the verbose preference
Rename-Item -Path $_ -NewName $newName
}
Check the Help for Rename-Item. The Parameter -NewName requires the name of the file only, not the full path.
Try out this:
Get-ChildItem "C:\Users\******\Desktop\PowerShell Practice-Filter" -Filter *.pdf | #create list of files
ForEach-Object{
$oldname = $_.FullName
$newname = $_.Name.Remove(0,17)
Rename-Item -Path $oldname -NewName $newname
$oldname
$newname #for testing
}
Please try this
Get-ChildItem -Path "C:\Users\******\Desktop\PowerShell Practice-Filter" -Filter *.pdf | Rename-Item -NewName $newname
I have a variety of files with names in the directory that look like this:
first_file_123456.jpg
5 * second_file_246531 (2).jpg
What I am looking to do is lay my hands on a PowerShell script that can take these files and rename them like this:
123456.jpg
246531 (2).jpg
I am looking to strip the last underscore and all text leading up to it to rename my files so they can match item numbers in my enterprise resource planning system. This system is much older (2004 technology) so automating from that side is out.
What i have tried to wire up so far and does not seem to work properly is as follows:
Get-ChildItem -Recurse -filter *_* | `
Foreach-Object {
$oldName = $_.Name
$pos = $oldName.LastIndexOf("_")
$newName = $oldName.Substring($pos + 1)
if (Test-Path $newName) {
# This is where I get lost - if it runs into a duplicate file name
# how can I make the name unique
}
#write-host $_.fullname
write-host $oldName renamed To: $newName | Out-File renamelog.txt
#rename-item $_.FullName -NewName $newName
}
I commented out the commands that actually do something to see what the output is.
Enumerate your files, filter for filenames containing an underscore, then rename them with everything up to and including the last underscore removed.
$re = '^.*_'
Get-ChildItem 'C:\some\folder' |
Where-Object { $_.Name -match $re } |
Rename-Item -NewName { $_.Name -replace $re }
Here's a short demo that uses the LastIndexOf and Substring methods:
$name = "first_file_123456.jpg"
$indexOfLastUnderscore = $name.LastIndexOf("_")
$newName = $name.Substring($indexOfLastUnderscore + 1, $name.Length - $indexOfLastUnderscore - 1)
# $newName now contains "123456.jpg"
Here's another way that uses PowerShell's -split operator and array indexing:
$name = "first_file_123456.jpg"
$newName = ($name -split '_')[-1]
$newName
# $newName now contains "123456.jpg"
Batch rename:
Get-Childitem -path $startDir -recurse |
where { ! $_.PSIsContainer } |
foreach {
$newName = Join-Path $_.Directory ($_.Name -replace '.*_', '');
Rename-Item $_.FullName $newName;
};
I have to go through many levels of child folders and remove special characters that are invalid in SharePoint, mainly '#&'
I have scoured the internet trying different commands; rename-item/move-item, variations of the two, all to no avail. The closest i've gotten is using:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'}
but i keep getting this error: Rename-item: Source and destination path must be different.
Could someone point me in the right direction?
Regards
That error only happens when you attempt to rename a directory to the same NewName as the current name, you can safely ignore it.
Add -ErrorAction SilentlyContinue to silently suppress the error message:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'} -ErrorAction SilentlyContinue
You need to filter out the files that you're not planning to rename:
Get-ChildItem -Recurse |
Where-Object { $_.Name -match '[!##&]' } |
Rename-Item -NewName {$_.Name -replace '[!##&]','_'}
something like this may work
dir -Recurse -File | ? basename -Match '[!##&]' | % {
# if the file.txt already exists, rename it to file-1.txt and so on
$num = 1
$base = $_.basename -replace'[!##&]', '_'
$ext = $_.extension
$destdir = Split-Path $_.FullName
$newname = Join-Path $destdir "$base$ext"
while (Test-Path $newname) {
$newname = Join-Path $destdir "$base-$num$ext"
$num++
}
ren $_.fullname $newname
}