Writing a powershell command to combine specifically named folders - windows

I'm looking for a command that will search through all of the subfolders of my main customer files folder, identify any folders labelled as "Quotes-Tenders" and merge them with the file called "Quotes and Enquiries".
The customer files folder is located Y:\Customer Files and contains 1,285 to search, the search only needs to go one level down.
I have tried the rename command on a test folder however this runs into a conflict error with having two of the same named file.
PS C:\Users\Gareth> Get-ChildItem C:\Users\Gareth\Desktop\Test -Recurse -Directory | Where-Objects-Tenders*"} | Rename-Item -NewName { $_.name-replace 'Quotes-Tenders', 'Quotes and Enquiries'}
Any help on how to get around this issue would be great.

i propose you this code
Get-ChildItem "C:\Users\Gareth\Desktop\Test" -Recurse -Directory |
Where Name -like "*Quotes-Tenders*" |
sort -Descending {($_.FullName -split '\\').Length } |
%{
$newname=Join-Path -Path $_.Parent.FullName -ChildPath $_.Name.Replace('Quotes-Tenders', 'Quotes and Enquiries')
Rename-Item $_.FullName -NewName $newname
}
For explain:
List item
I take all directory tree
I select with where clause,
I sort by number of directory section because you can have a diretory
like this
'C:\temp\Quotes-Tendres ggg\Quotes-Tendres. ffff'
and
'C:\temp\Quotes-Tendres ggg' in you list, in this case i want rename first 'C:\temp\Quotes-Tendres ggg\Quotes-Tendres. ffff'
I rename the directory

Related

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++)
}

How to create destination folder with date appended to it via Powershell?

I have backup files sitting in a directory. The objective I am trying to achieve is that each time I run this piece of Powershell against that directory, I want it to move the files into a folder that gets created and append today's date to it. I have tried this:
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
Move-Item -Path $_.FullName -Destination "C:\Users\Admin\Desktop\New folder\$($_.BaseName,(Get-Date).ToString("MMddyyyy"),$_.Extension)"
}
All this does is moves the backup files into "New folder" and append the date to the files themselves. I'm wanting it to create a new folder with today's date appended within "New folder" and have the backup files sitting in there. Any help would be great.
For one the commas do not belong but each section of "code" needs their own subexpression. You are also sticking the date in between the base filename and the file extension, so it looks like you want to insert the date in the file name. Instead, you can adjust it to this.
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
Move-Item -Path $_.FullName -Destination "C:\Users\Admin\Desktop\New folder$((Get-Date).ToString("MMddyyyy"))\"
}
Unless you're renaming the file, you don't need to specify it in the path.
Important Note that if that folder does not exist, you will need to create it first. Otherwise you'll end up with an extensionless file with that name instead. You could test for the path first, create if it doesn't exist, then move.
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
$newfolder = "C:\Users\Admin\Desktop\New folder$((Get-Date).ToString("MMddyyyy"))\"
if(-not(Test-Path $newfolder)){
$null = New-Item -Path $newfolder -ItemType Directory
}
Move-Item -Path $_.FullName -Destination $newfolder
}
The $null is to hide the output that New-Item creates by default.
A suggestion for improvement would be to use Join-Path for building the new folder path

Powershell Comparing two folders then copying it into another file

I'm trying to compare two folders and copy the the files that exists in one but not the other into a whole separate folder.
This is what I have so far
$fso = Get-ChildItem -Recurse -path C:\Users\akalkandelen\Desktop\old
$fsoBU = Get-ChildItem -Recurse -path C:\Users\akalkandelen\Desktop\new
foreach($item in Compare-Object -ReferenceObject $fso -DifferenceObject $fsoBU -PassThru){
Copy-Item -Path $item.FullName -Destination C:\Users\akalkandelen\Desktop\release
}
The problem is that directory structure of the files copied into Release has to match. So if a file within a folder within another folder it has to maintain that structure. If i use -Recurse than it adds all the sub-folders and files into the root folder as well.

PowerShell Script to Delete Everything on a drive except hidden and select directories and anything below them

Okay so I am trying to keep a drive, specifically D, completely clear of anything on a server except for select directories and their children
This is what I have so far:
Get-ChildItem -Path "D:\" -Exclude "DirApple", "DirBanana", "Dir Cherry", "Script", "TEST" | foreach ($_) {
"CLEANING :" + $_.fullname
Remove-Item $_.fullname -Force -Recurse
"CLEANED... :" + $_.fullname
}
This works great if my path is D:\TEST\ (I replicated everything in D under D test including what I wanted removed), but if my path is D:\ it does not work at all
-Exclude for Get-ChildItem only excludes filenames, not directory names. For this reason try using Get-Item instead for this problem. When combined with a WildCard for the path, this will give you the desired result.
Get-Item -Path "D:\*" -Exclude "DirApple", "DirBanana", "Dir Cherry", "Script", "TEST" | foreach ($_) {
"CLEANING :" + $_.fullname
Remove-Item $_.fullname -Force -Recurse
"CLEANED... :" + $_.fullname
}
Why do I have to do this?
The -Exclude param for Get-ChildItem is meant to exclude only Files, not directories themselves, as seen in the help:
> help dir -Parameter Exclude
-Exclude <String[]>
Omits the specified items. The value of this parameter qualifies the Path parameter.
Enter a path element or pattern, such as "*.txt".
Really just a case of not using the very best tool for the job, though you were close!
Why'd I need to add a * to the path?
If you look at the help for -Exclude for Get-Item, you'll note that (emphasis mine):
The Exclude parameter is effective only when the command includes
the contents of an item
such as C:\Windows*, where the wildcard character specifies the contents of the
C:\Windows directory.
This is why we had to add a WildCard to the Path.

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