Search code examples
powershelldirectoryfilesystemobjectnon-recursive

How do I non-recursively gather folder sizes and their names? (Powershell)


Basically what I'm trying to do is gather users folder size from their network folder then export that to a .csv, directory structure looks something like this: network:\Department\user...User's-stuff

The script I have right now gets the department file name and the user's folder size, but not the user's name (folder name in the department). As for the TimeStamp, I'm not sure it's working correctly. It's meant to make a timestamp when it starts on the users in the next department so basically, all users in the same department will have the same timestamp.

This is what I have so far:

$root = "network"
$container= @()
$place = "C:\temp\"
$file = "DirectoryReport.csv"

Function Get-FolderSize
{

    BEGIN{$fso = New-Object -comobject Scripting.FileSystemObject}

    PROCESS
        {
        $prevDept = (Split-Path $path -leaf)

        $path = $input.fullname

        $folder = $fso.GetFolder($path)

        $Volume = $prevDept + "-users"

        $user = $folder.name #can't figure this part out...

        $size = $folder."size(MB)"

        if ( (Split-Path $path -leaf) -ne $prevDept)
        {
            $time = Get-Date -format M/d/yyy" "HH:mm #Probably wrong too..
        } 

        return $current = [PSCustomObject]@{'Path' = $path; 'Users' = $user; 'Size(MB)' = ($size /1MB ); 'Volume' = $Volume; 'TimeStamp' = $time;} 

        }

} 

$container += gci $root -Force -Directory -EA 0 | Get-FolderSize

$container

#Creating the .csv path

$placeCSV = $place + $file

#Checks if the file already exists
if ((test-path ($placeCSV)) -eq $true)
    {
       $file = "DirectoryReport" + [string](Get-Date -format MM.d.yyy.@h.mm.sstt) + ".csv" 
       rename-item -path $placeCSV -newname $file
       $placeCSV = $place + $file
    }

#Exports the CSV file to desired folder

$container | epcsv $placeCSV -NoTypeInformation -NoClobber

But in the CSV file the user and the timestamp are wrong. Thanks for any/all help


Solution

  • This really seems to be doing it the hard way. Why you wouldn't just use Get-ChildItem to do this almost makes this script seem a little masochistic to me, so I'm going to use that cmdlet instead of creating a comobject to do it.

    I am a little confused as to why you wouldn't want to recurse for size, but ok, we'll go that route. This will get you your folders sizes, in MB.

    #Get a listing of department folders
    $Depts = GCI $root -force -Directory
    
    #Loop through them
    ForEach($Dept in $Depts){
        $Users = @()
        $Timestamp = Get-Date -Format "M/d/yyy HH:mm"
    
        #Loop through each user for the current department
        GCI $Dept -Directory |%{
            $Users += [PSCustomObject]@{
                User=$_.Name
                Path=$_.FullName
                "Size(MB)"=(GCI $_|Measure-Object -Sum Length|Select Sum)/1MB
                Volume="$($Dept.Name)-Users"
                TimeStamp=$Timestamp
            }
        }
    }
    
    #Rename output file if it exists
    If(Test-Path "C:\Temp\DirectoryReport.csv"){
        Rename-Item "C:\Temp\DirectoryReport.csv" "DirectoryReport.$(Get-Date -format MM.d.yyy.@h.mm.sstt).csv"
    }
    
    #Output file
    $Users | Export-Csv "C:\Temp\DirectoryReport.csv" -NoTypeInformation
    

    If you want to get the total size for all files within each user's folder, including files within subfolders, change the "Size(MB)"=(GCI $_|Measure-Object -Sum Length|Select Sum)/1MB to be recursive by replacing it with "Size(MB)"=(GCI $_ -recurse|Measure-Object -Sum Length|Select Sum)/1MB and that should have you good to go.