PowerShell move most recent file from each folder - powershell

I need some assistance with powershell - I would like to search within all subfolders of a particular folder, and copy the latest file from each subfolder to a new folder every day at 9.00 AM. So, I want to search within folder A's subfolder a, b and c to pick out the latest file in a, b and c each, and move all three files into outside folder B (a single folder). I am new to PowerShell - any help is appreciated. I've basically tried to use this but it creates a backup: Copy most recent file from folder to destination
Clear-Host
$ChildFolders = #('In_a', 'In_b', 'In_c')
for($i = 0; $i -lt $ChildFolders.Count; $i++){
$FolderPath = "C:\FolderA\" + $ChildFolders[$i]
$DestinationPath = "C:\FolderB\" [$i]
gci -Path $FolderPath -File | Sort-Object -Property LastWriteTime -Descending | Select FullName -First 1 | %($_){
$_.FullName
Copy-Item $_.FullName -Destination $DestinationPath
}

Gets subfolders
Gets all files in subfolders
Sorts files by Creation Date into a array
Gets first Entry
Moves file to Destination directory
*It will overwrite files with the same name in the destination folder
Function Get-LatestFiles($SourceFolder,$Destination){
$Subfolders = Get-ChildItem $SourceFolder -Directory
[System.Collections.ArrayList]$SubFoldersExpanded = new-object System.Collections.ArrayList
Foreach($SubFolder in $SubFolders){
$SubFolderExpanded = $Subfolder | %{(Get-ChildItem $_.FullName -File -Depth 1 | Sort-Object -Property CreationTime -Descending)}
if($SubFolderExpanded.Count -gt 0){
$SubFolderExpanded[0] | %{Move-Item $_.FullName -Destination $Destination -force}
}
}
}
Get-LatestFiles -SourceFolder C:\test -Destination C:\test01

Related

compare 2 folders and copy the difference in the 3rd folder with the same folder structure recursively using Powershell

Here what I'm trying to do and this is my second post on the same issue, I'm trying to compare 2 folders and copy the difference in the 3rd folder with the same folder structure recursively.
Here is the Powershell script which I receive from an another post (how to copy updated files to new folder and create directory as source if not exist?). This code does everything I need but I have one problem, with the -passthru arguement, it take the file which ever is new in the "folder 2" as well. What I need is what ever files are different in Folder1 from Folder2 alone to be copied over to Folder3. I tried and could not make it work. Any help will be great.
$newdir = "M:\Technical\foldercompare\folder1"
$olddir = "M:\Technical\foldercompare\folder2"
$diffdir = "M:\Technical\foldercompare\folder3"
#Get the list of files in oldFolder
$oldfiles = Get-ChildItem -Recurse -path $olddir | Where-Object {-not ($_.PSIsContainer)}
#get the list of files in new folder
$newfiles = Get-ChildItem -Recurse -path $newdir | Where-Object {-not ($_.PSIsContainer)}
Compare-Object $oldfiles $newfiles -Property LastWriteTime,Length -Passthru | sort LastWriteTime | foreach {
$fl = (($_.Fullname).ToString().Replace("$olddir","$diffdir")).Replace("$newdir","$diffdir")
$dir = Split-Path $fl
If (!(Test-Path $dir)){
mkdir $dir
}
copy-item $_.Fullname $fl
}

Get Count of a Zip folder + match size Powershell

Trying to get Count of a zip folder that has for example 30 CSV files
The test folder has 30 csv files
$directoryInfo = Get-ChildItem "$TEST\*.csv" | Measure-Object
$directoryInfo.count
All 30 csv files will be compressed into a zip folder = TESTZIP1.zip located inside of TEST folder.
If I try to run the following to measure how many files are inside of the compressed folder, I get 0 as answer
$backUP = Get-ChildItem "$zipfiletest\TESTZIP1.zip\*.csv" | Measure-Object
$backUP.count
Goal: able to Count() how many files are inside of zip folder, and if zip folder has the same amount of files as TEST folder, sends an email.
If you want to count the files inside your zip-file, you can do it like this:
$ZipFile = [System.IO.Compression.ZipFile]::Open("$zipfiletest\TESTZIP1.zip",[System.IO.Compression.ZipArchiveMode]::Read)
$ZipFile.Entries.count
$ZipFile.Dispose()
If you want to check anything else inside the zip file, you can easily explore the other parameters of the $ZipFile variable
$fileToCheck = Get-Item -Path (Join-Path -Path "C:\Users\" -ChildPath test.zip) - ErrorAction SilentlyContinue
$ZipFiles = Get-ChildItem -Path $fileToCheck -Recurse -Filter '*.zip'
$Shell = New-Object -ComObject Shell.Application
$Results = foreach( $fileToCheck in $ZipFiles ){
$DATCount = $Shell.NameSpace($fileToCheck.FullName).Items() |
Where-Object { $_.Name -match '\.dat$' } |
Measure-Object |
Select-Object -ExpandProperty count

Move files, check for duplicates and rename incrementally if present

I have a script that looks at the source folder and then the destination folder and decides if the sub-folders are present. If not, it creates the corresponding folder. Once that is done, it moves all of the files in the sub folders to the destination. Problem - There are duplicate files that need can't be overwritten. I need a way to check for duplicates and if found, increment the source file name by -1. There may be incremented files already.
My current script works flawlessly to create needed sub-folders and move files but I loose any previous files.
$SFolder = "C:\Temp\Test\Source\"
$DFolder = "C:\Temp\Test\Destination\"
$folders = Get-ChildItem -Path $SFolder -Directory
foreach ($folder in $folders) {
Get-ChildItem -File "$sfolder\$folder" |
Where-Object -FilterScript {$_.LastWriteTime -lt [datetime]::Now.AddMinutes(-5)} |
Sort-Object -Property LastWriteTime |
Group-Object -Property {$_.LastWriteTime.ToString("yyyy")} |
ForEach-Object {
if (!(Test-Path -Path "$dfolder\$folder" -PathType Container -ErrorAction SilentlyContinue)) {
New-Item -ItemType Directory -Force -Path "$dfolder\$folder"
}
$_.group|move-item -Destination "$dfolder\$folder" -PassThru
}
}
The script as written works great. Here is what I need. I start with the following:
Source test1\05013018-22503-652469-1 (no file extension)
test1\05013018-22503-652469-2
Destination test2\05013018-22503-652469-1
test2\05013018-22503-652469-1-1
test2\05013018-22503-652469-1-2
I want the following result after running the script:
Source test1\
Destination test2\05013018-22503-652469-1
test2\05013018-22503-652469-1-1
test2\05013018-22503-652469-1-2
test2\05013018-22503-652469-1-3
test1\05013018-22503-652469-2

System.IO.Compression.ZipFile Multiple Directories

I can get this to work if I set up an array for my $destination but this creates a seperate .zip for each directory selected.
How can I select every directory and zip them under a single destination instead of multiple destination files? Here is my code:
$type = "*.txt"
$destination = "LogsBackup.zip"
Add-Type -Assembly "System.IO.Compression.FileSystem" ;
$_sources = dir c:\Logs\$type -Recurse | Select Directory -Unique |
Out-GridView -OutputMode Multiple |
Select #{Name="Path";Expression={$_.Directory -As [string]}}
for ($i = 0; $i -lt $_sources.Length; $i++)
{
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory( $_sources[$i].Path , $destination)
}
I want to keep my Out-GridView option the way it is so if it's a single directory or multiple I can select them and store them as an array.
The -update parameter will make sure that your existing archive is updated with new entries that you select from out-gridview.
$destination = "C:\logs\LogsBackup.zip"
#Create a single archive
Get-ChildItem -Path C:\logs -Filter *.txt -Recurse |
Select #{Name="Path";Expression={$_.DirectoryName}} -Unique |
Out-GridView -PassThru | Compress-Archive -CompressionLevel Optimal -DestinationPath $destination -Update

Copy most recent file from folder to destination

I need some assistance with powershell . My experience is very limited as I'm a sql server dba. What I am currently doing is migrating databases across from 2000 to 2008. I want to automate the .bak copy from source to destination so I don't need to go into each folder and copy and then paste. So let me give the picture. The source directory has folders a b c d. I want the script to read from each folder or ideally specify the folder names and get the most recent
.Bak full backup by date and copy to a destination. The destination will have the same folders so folder a's backup copied to destination folder a will be great. Afterwards I want to do the same but change my search from full backup search to differential. Any help is appreciated.
This is how I would address it. The variables for folderpath and destination path are the root folders and the variable for childfolders list out each folder to search.
Clear-Host
$ChildFolders = #('A', 'B')
for($i = 0; $i -lt $ChildFolders.Count; $i++){
$FolderPath = "D:\BackupSource\" + $ChildFolders[$i]
$DestinationPath = "D:\BackupDestination\" + $ChildFolders[$i]
gci -Path $FolderPath -File | Sort-Object -Property LastWriteTime -Descending | Select FullName -First 1 | %($_){
$_.FullName
Copy-Item $_.FullName -Destination $DestinationPath
}
}
Given this structure, meaning all folders exist.
├───destination
│ ├───A
│ └───B
└───source
├───A
└───B
You can do the following:
$folders = #('A', 'B')
$source = 'source'
$destination = 'destination'
$filter = '*.bak'
$folders | foreach {
$source_path = [io.path]::combine($source, $_)
$destination_path = [io.path]::combine($destination, $_)
gci $source_path -File -Filter $filter | sort -Property LastWriteTime -Descending |
Select -first 1 | copy -Destination $destination_path
}
It gets all files matching your filter, sorts them in descending order by LastWriteTime, picks the newest and copies it to your destination.