I am trying to create a powershell to compare FILE SIZE from multiple subfolders
Today's files Folder Structure:
- TodaysFolder as a ROOT FOLDER
- TodaysFolder/Business/FolderA/ csv files
- TodaysFolder/Business/FolderB/ csv files
I want to compare today's csv file Size from multiple files / subfolders based on yesterday's data
- Reference Folder Structure:
- ArchiveFolder/YesterdayDate/Business/FolderA/ CSV files
- ArchiveFolder/YesterdayDate/Business FolderA/ CSV files
Also I plan to implement a condition if file size is <= 5 %, PASS If file size is > = 10 % size, FAIL
I will post the current code in a few, but just trying to get some ideas and guidance for this project.
$TodayPath = "\\TodaysFolder\Business/FolderA\"
$TodayFiles = get-childitem $TodayPath -Exclude Archive -Verbose |
? {! $_.PSIsContainer} |
Select-Object Name, @{Name='File Size'; Expression={([string]([int]($_.Length / 1KB))) " KB"}}
$archiveFolder = (get-date).AddDays(-1).ToString('yyyyMMdd')
$archiveFolderPath = "\ArchiveFolder\YesterdayDate\Business\FolderA"
$ArchiveFiles = get-childitem $archiveFolderPath -Exclude Archive -Verbose |
? {! $_.PSIsContainer} |
Select-Object Name, @{Name='File Size'; Expression={([string]([int]($_.Length / 1KB))) " KB"}}
write-host $todayPath -ForegroundColor green
$TodayFiles
write-host "---------------------------" -ForegroundColor Red
write-host $archiveFolderPath -ForegroundColor yellow
$ArchiveFiles
Thanks
CodePudding user response:
Use Group-Object
to group your file lists by shared file name and process each group in a ForEach-Object
command, where you can compare file sizes.
Note:
The exact requirements regarding pass / fail based on the percentage of file-size changes aren't clear at this point and neither is whether the calculations should be based on size of today's file or the corresponding archive file.
The code below assumes that today's files as the basis; see the source-code comments for how to change that.
The pass / fail logic is limited to passing size-change ratios less than or equal to
.05
(5%
).A custom object summarizing the comparison is output; it outputs rounded numbers for the sizes and percentages, but you can easily convert that to formatted strings, as shown in the question.
# Determine $TodayPath and $ArchivePath
# ...
# Note the use -Filter *.csv to limit processing to CSV files.
# Also, since 'Archive' presumably refers to a *directory* to
# exclude, -Exclude Archive is then not necessary.
# There is no need to select a subset of properties with Select-Object
# at this point.
$todayFiles = Get-ChildItem $todayPath -Filter *.csv
$archiveFiles = Get-ChildItem $archiveFolderPath -Filter *.csv
# Group the two lists by shared file name, and process each group.
[array] $todayFiles $archiveFiles | Group-Object Name | ForEach-Object {
if ($_.Count -eq 1) {
# File at hand exists only in *one* location - either only in today
# location or only in the archive location.
Write-Warning "File has no counterpart: $($_.Group[0].FullName)"
return
}
# Calculate the size change.
$refIndex = 0 # Base calculation on today's files; change to 1 for archive files
$otherIndex = (0, 1)[$refIndex -eq 0]
$refSize = $_.Group[$refIndex].Length
$sizeDelta = $_.Group[$otherIndex].Length - $refSize
$sizeDeltaRatio = $sizeDelta / $refSize
# Construct and output a custom object with the properties of interest.
[pscustomobject] @{
Name = $_.Group[0].Name
SizeInKb = [Math]::Round($refSize / 1kb, 2)
SizeDeltaPercentage = [Math]::Round($sizeDeltaRatio * 100, 2)
Pass = $sizeDeltaRatio -le .05
}
}