Script to search for files and rename files - windows

I have about 11000 different files in hundreds different folders, sub folders and sub-sub folders in following location \\mastercorrespondence, and I need to rename some of the files and copy corresponding file from K:\CDS_TOOL_MANUAL_OVERRIDES daily in their own subfolder.
In short it should perform following steps
Look for any PDF format documents in K:\ CDS_TOOL_MANUAL_OVERRIDES folder.
For each document in K:\ CDS_TOOL_MANUAL_OVERRIDES look for PDF document with identical file name held in the \\mastercorrespondence” any sub-directory.
If corresponding file found then rename file in \\mastercorrespondence sub-directory as <Original Filename>_<Overwritten>_<dd.mm.yy>
Move the file from K:\ CDS_TOOL_MANUAL_OVERRIDES folder to the same location as it counterpart in the \\10.5.13.10\mastercorrespondence sub-directory.
If any documents did not have a corresponding file in \\mastercorrespondence sub-directory then write a message to log file stating names of unmatched files.
Folder Structure is Like.
\\mastercorrespondence\SIPP\21\201201\01
\\mastercorrespondence\SIPP\21\2012022
\\mastercorrespondence\ISA\10201201\201202\02
\\mastercorrespondence\ISA\10201201\201203
\\mastercorrespondence\ISA\10201201\201204
\\mastercorrespondence\ISA\10201201\201205

Here's a starting point in PowerShell, if that works for you:
#Look for any PDF format documents in K:\ CDS_TOOL_MANUAL_OVERRIDES folder.
$pdfFiles = Get-ChildItem -Path K:\CDS_TOOL_MANUAL_OVERRIDES -filter "*.pdf"
#For each document in K:\ CDS_TOOL_MANUAL_OVERRIDES look for PDF document with identical file name held in the \\mastercorrespondence” any sub-directory.
$referenceFiles = Get-ChildItem -Path \\mastercorrespondence -recurse -filter "*.pdf"
$pdfFiles | %{
$_ = $pdfFile
$matched = ""
#I don't fully understand what you're asking for, but it seems to me that the move and rename are on the same file, and technically a rename is a move... so I've combined them.
$referenceFiles | %{if ($_.Name -eq $pdfFile.Name) {$matched = $_} }
if ($matched -ne "") {
$destinationName = ($pdfFile.Name + "_OverWritten_"+(Get-Date -format dd.MM.yy))
Move-Item -Path $_.FullName -Destination ($matched.DirectoryName + "\" + $destinationName)
}
else{
#If any documents did not have a corresponding file in \\mastercorrespondence sub-directory then write a message to log file stating names of unmatched files.
("Unable to locate matching file: " + $pdfFile.FullName) | Out-File -Append -FilePath "K:\mover.log"
}
}

Related

How can I get a list of folders/subfolders that DOES NOT contain a specific type of file?

For example, I wanted to print a list of folders which contain an .html file. Correct me if I am wrong, but this worked for me:
dir /S *.html > C:\Users\PC\Desktop\with-html.txt
Now I would like to find the folders which do not contain .html files.
How do I go about that?
EDIT:
The folders are structured in a way that only the child folders (last subfolder) have any kind of files. I would like to get a list of directories to those subfolders. So the above command line is giving me:
C:\...\ml\regression\lasso-regression
C:\...\ml\regression\linear-regression
There is not output just C:\...\ml or C:\...\ml\regression.
The folder structure looks like this:
C:\...\ml
classification
regression
lasso-regression
linear-regression
There are about 10 folders in folder ml and no files. There are again about 10 folders in second folder level where C:\...\ml\regression\linear-regression contains an HTML file while C:\...\ml\regression\lasso-regression does not contain a file with file extension .html. Only the folders in last level of the folders tree have files at all.
I'd be grateful getting just the list of the last folders in folders tree not containing a file with file extension .html.
I basically output the above command line into a .csv file, filtered it with MS Excel, and have now a list of folders with .html file(s). I'm basically working with R-markdown files, and it'll be a status report, the folders list with .html files is what I have completed already. So in need now only the opposite folders list.
Not difficult using PowerShell.
Get-ChildItem -Recurse -Directory |
ForEach-Object {
if ((Get-ChildItem -File -Path $_.FullName -Filter '*.html').Length -eq 0) { $_.FullName }
}
If you must run this in a .bat file script, the following might be used.
#powershell.exe -NoLogo -NoProfile -Command ^
"Get-ChildItem -Recurse -Directory |" ^
"ForEach-Object {" ^
"if ((Get-ChildItem -File -Path $_.FullName -Filter '*.html').Length -eq 0) { $_.FullName }" ^
"}"

Unzip Multiple Files into Different Directories

I have multiple zip files.
They are called folder(1).zip, folder(2).zip, folder(3).zip. Using PowerShell, when I attempt to unzip them all into unique folders using this...
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | Expand-Archive -DestinationPath 'c:\users\name\downloads' -Force
I get all of the files into one folder called "folder". How can I get the zip folders to unzip into separate folders?
Bonus question, is there a way, as part of this process, to rename each folder as it's coming out so folder(1).zip becomes Name-Here, folder(2).zip becomes Other-Name-Here, etc?
Thanks!
Because you specify only one destination path they will all be extracted into c:\users\name\downloads. I suppose the zip archives each contain a folder named "folder", so all contents from all archives end up together in c:\users\name\downloads\folder
You would have to specify a different destination path for each archive. Not sure what your naming convention should be, I have used a simple counter:
$counter = 0
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | foreach {
$destination = Join-Path $_.DirectoryName ("YourName" + $counter++)
Expand-Archive $_.FullName -DestinationPath $destination
}
Of course I suppose, now every of those folders will have the subfolder "folder", but if that's how the archives are built there's not really a way to change that. If you are absolutely sure that all archives have that subfolder, you could do something like this:
$counter = 0
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | foreach {
# expand to the root folder first
Expand-Archive $_.FullName -DestinationPath $_.DirectoryName
# now rename the extracted "folder" to whatever you like
Rename-Item (Join-Path $_.DirectoryName "folder") -NewName ("YourName" + $counter++)
}

Copy files based on existence of other files (Windows)

I have a folder of images in jpg format called "finalpics" and also another folder ("sourcepics") which has several subfolders containing RAW files in various formats.
I need a script (batch file?) that will copy all the files from "sourcepics" and its subfolders to another folder ("sourcefinal") only if that file exists in "finalpics".
As an example:
"finalpics" contains files called mypic1.jpg, mypic2.jpg, mypic3.jpg.
"sourcepics" contains files called mypic1.dng, mypic2.psd, mypic3.cr2, yourpic1.dng, yourpic2.psd, yourpic3.cr2.
I'd want the script to copy the 'mypic' files but not the 'yourpic' files to "sourcefinal".
There's over a thousand jpgs in "finalpics" but probably 40,000 files in the various subfolders of "sourcepics".
Hope that makes sense.
Thanks for looking.
I think this PowerShell code will do what you're after; it will copy files of the same name (ignoring file extension) from "SourcePics" to "SourceFinal" if they exist in FinalPics:
# Define your folder locations:
$SourcePicsFolder = 'C:\SourcePics'
$FinalPicsFolder = 'C:\FinalPics'
$SourceFinalFolder = 'C:\SourceFinal'
# Get existing files into arrays:
$SourcePics = Get-ChildItem -Path $SourcePicsFolder -Recurse
$FinalPics = Get-ChildItem -Path $FinalPicsFolder -Recurse
# Loop all files in the source folder:
foreach($file in $SourcePics)
{
# Using the basename property (which ignores file extension), if the $FinalPics
# array contains a basename equal to the basename of $file, then copy it:
if($FinalPics.BaseName -contains $file.BaseName)
{
Copy-Item -Path $file.FullName -Destination $SourceFinalFolder
}
}
Note: There is no filtering based on file type (e.g. it will copy all files). Also, if your 'SourcePics' folder has two images of the same filename but in different subfolders, and a file of this name also exists in 'FinalPics', then you may get an error about file already existing when it tries to copy for the second time. To overwrite, use the -Force parameter on the Copy-Item command.
I tested the above code with some .dng files in 'SourcePics' and .jpg files in 'FinalPics' and it worked (ignoring the yourpic files).

How to extract multiple zips into one folder without creating separate folders with zip name? Powershell

Here's my script in powershell
$today = (Get-Date).ToString('dd_MM_yyyy')
$LocalPath = "C:\Builds\$today"
New-Item -ItemType directory -Path $LocalPath
$RemotePath = "C:\Builds\zip\$today"
$Max_hours = "-5"
#Max_mins = "-5"
$Curr_date = get-date
#Checking date and then copying file from LocalPath to RemotePath
Foreach($file in (Get-ChildItem $RemotePath))
{
if($file.LastWriteTime -gt ($Curr_date).addhours($Max_hours))
{
Get-ChildItem "C:\Builds\zip\$today\*pc*.*" | % {& "C:\Program Files\7-Zip\7z.exe" "x" "-aoa" $_.fullname "-oC:\Builds\$today"}
}
ELSE
{"not extracting $file"
}
}
I've got a few *.zip files which I want to extract into a specific folder. The problem is, that 7zip creates subfolders with *.zip name and extract files into this folders.
Eg. I've got a.zip, b.zip and c.zip files and I want them to be extracted exactly in Builds folder. Right now after my command they are extracted to:
Builds/a/(here a.zip files)
Builds/b/(here b.zip files)
Builds/c/(here c.zip files)
I want them all to be in Builds/(here a,b,c files) with full directory paths.
Are there any 7zip options in shell to do that?
'-e' option exctracts all files without folders paths and thats now what I'm looking for.
If you're using PowerShell v5 you can use Expand-Archive instead of 7zip:
Get-ChildItem "C:\Builds\zip\$today\*pc*.*" | % {Expand-Archive $_ -DestinationPath "C:\Builds\$today"}
EDIT:
I do not get folders created when using the command.
Zip file containing a file:
Running Expand-Archive C:\aaaa\nuget350.zip -DestinationPath C:\bbbb
What is extracted:

Renaming Files with PowerShell

I need to rename a bunch of files at once in Windows PowerShell. I read the HTG article here and it helped a little.
My problem is that It will only rename files in the top of the directory, nothing deeper. For example: There is FOLDER A and inside FOLDERA is a document and FOLDER B. Inside FOLDER B is another document. Both folders and both documents need to be renamed. The way it is working now is that FOLDER A, the document in FOLDER A, and FOLDER B are being renamed, but not the document inside FOLDER B.
My current code is:
Dir | Rename-Item –NewName { $_.name –replace “ “,”_” }
Thanks for the help!
You need to specify the -Recurse parameter on Dir to get it to recurse e.g.:
Dir -recurse | Rename-Item -NewName {$_.Name -replace ' ','_'}
BTW this may run into a problem because you're renaming the folder (FOLDERB) that contains the document first but the item being piped that corresponds to the file in FOLDERB still has the old name. In this case, you want to rename from the bottom up. One very crude but effective (I think) way to do this is to sort the file items on their path length descending e.g.:
Dir -recurse | Sort {$_.FullName.Length} -Desc | Rename-Item {$_.Name -replace ' ','_'}

Resources