Home > other >  Compare size of multiple subdirectory before and after a break in a Powershell script
Compare size of multiple subdirectory before and after a break in a Powershell script

Time:03-16

I'm a beginner with Powershell, also forgive my English which isn't the best.

I have a directory with several subdirectories like this

Directory

My goal is to target directory that are updated while the script is running. So I made this script

$path = "C:\Users\s611284\Desktop\archive"

#Check that the directories have the correct name and calculate their size

Get-ChildItem -Force $path -ErrorAction SilentlyContinue -Directory | foreach {
     
  $Size = (Get-ChildItem $_.fullname -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum/ 1Kb

  $FolderName = $_.BaseName -match '1B(\d{6})_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{6})' -or $_.BaseName -match '1B(\d{6})_SML 10_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{5})' 

  $Folder = $_.BaseName

  if ($FolderName -eq "true") {
    write-host(" name $Folder is correct, $Size Kb")
  }
  else {
    write-host( "name $Folder is incorrect")
  }
}  

#Break 

Start-Sleep -Seconds 30

write-host( "end of break")
 

#directory size calculation after the break

Get-ChildItem -Force $path -ErrorAction SilentlyContinue -Directory | foreach {
     
  $Size1 = (Get-ChildItem $_.fullname -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum/ 1Kb

  $FolderName1 = $_.BaseName -match '1B(\d{6})_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{6})' -or $_.BaseName -match '1B(\d{6})_SML 10_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{5})' 

  $Folder1 = $_.BaseName

  if ($FolderName1 -eq "true") {
    write-host("name $Folder1 is correct, $Size1 Kb")
  }
  else {
    write-host( "name $Folder1 is incorrect")
  }
}

All of this is working great

So now I want to compare the size of the subdirectories before and after the break, to know which have been updated

I tried

if ( $FolderSize -eq $FolderSize1 )
{
    Write-Output $True
}

Else
{ 
  Write-Output $False
}

at the end of my second block but it isn't working..

I also tried Compare-object but I don't think this command will help in my case

I hope you guys will understand my post and help me Thanks !

CodePudding user response:

If I understood correctly, you're looking to filter those folders where it's Size has changed after 30 seconds, if that's the case, you could use a function so that you don't need to repeat your code. You can make your function return a hash table where the Keys are the folder's absolute path and the Values are their calculated size, once you have both results (before 30 seconds and after 30 seconds) you can run a comparison against both hash tables outputting a new object with the folder's Absolute Path, Size Before and Size After only for those folders where their calculated size has changed.

function GetFolderSize {
    [cmdletbinding()]
    param($path)
    
    $map = @{}
    Get-ChildItem $path -Directory -Force | ForEach-Object {
        $Size = (Get-ChildItem $_.Fullname -Recurse | Measure-Object -Property Length -Sum).Sum / 1Kb
        $FolderName = $_.BaseName -match '1B(\d{6})_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{6})' -or $_.BaseName -match '1B(\d{6})_SML 10_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{5})'
        if ($FolderName) {
            $map[$_.FullName] = $size
        }
    }
    if($map) { $map }
}

$path = "C:\Users\s611284\Desktop\archive"

$before = GetFolderSize $path -ErrorAction SilentlyContinue
Start-Sleep -Seconds 30
$after = GetFolderSize $path -ErrorAction SilentlyContinue

foreach($key in $after.PSBase.Keys) {
    if($before[$key] -ne $after[$key]) {
        # this is a folder with a different size than before
        [PSCustomObject]@{
            FullName   = $key
            SizeBefore = $before[$key]
            SizeAfter  = $after[$key]
        }
    }
}

CodePudding user response:

Not to take away from Santiago's helpful answer, but to provide an alternate solution, here's my take:

$path  =  "C:\Users\s611284\Desktop\archive"
$count = 0 
$hashMap = @{}
While ($count -lt 2) {
    Get-ChildItem -Path $path -Directory | 
        ForEach-Object -Begin {
            $count  
            $toMatch = "1B(\d{6})_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{6})|1B(\d{6})_SML 10_LEAP 1A version aout2021_(\d{4})-(\d{2})-(\d{2})T(\d{2})h(\d{2})m(\d{2})s_S(\d{5})" 
        } -Process {
            $folderMatch = $_.BaseName -match $toMatch
                if ($folderMatch) {
                    $size = (Get-ChildItem -Path $_.FullName -Recurse -EA 0 | Measure-Object -Property "Length" -Sum).Sum / 1kb
                    if (-not$hashMap.ContainsKey($_.BaseName))  {
                        $hashMap.Add($_.BaseName,$size)
                    }
                    if ($count -ge 2) {
                        if ($hashMap[$_.BaseName] -ne $size) {
                            $_.BaseName   " "   "is a different size" 
                        }
                    }
                }
        } -End {
            if ($count -ne 2) {
                Start-Sleep -Seconds 30
            }
        }
}

Personally, I hate the re-use of code and feel like something can always be done about it if you find yourself repeating code (copy/paste).

My question to you is:

  1. Aren't those folder names pretty unique?
  2. Could you not substitute it for a Wild Card Expression?
    • i.e.: $_.BaseName -like '*1A version aout2021*'
    • All in the name of "cleanliness" code. lol
  • Related