1
votes

I want to develope a script that will log the size of the folders in a given directory, their name's, and the date when they were logged. I want the script to export in the following CSV format:

Date;A;b;c;durga;New Folder;New Folder (2)
0125-1416;0.00;0.05;1;1; 0.00
0125-1417;0.00;0.05;0.00;0.00
0125-1419;0.00;0.05;0.00;0.00;20;30

Finally, i want the script to be intelligent enough to determine, based off of this log file, that there have been folders either added or removed. So if my root directory, C:\scripts has folders A, B, and C. I want the script to know if i delete A or add D the next time it runs and account for that in my CSV file.

The script is to be ran every so often (daily?) and basically append a new row to the ever increasing in size CSV file called 'log.txt'.

So far, I have some code that recurses through my folders and sums up their individual sizes, saves the name of the parent folder, it's size, and date and wedges all this information into a new object which is then tossed into an array index. I'm lost when trying to get a bunch of similarrly formatted objects to look like my desired CSV output. There's got to be a better approach for getting a CSV file out of this!!

Here's my 'get size of folders in a given directory' bit of code:

cd C:\scripts
$a = @()
get-childitem | where {$_.PSIsContainer} | foreach   {
$size = (Get-ChildItem $_ -recurse | where {!$_.PSIsContainer} | Measure-Object -Sum Length).Sum
$date = Get-Date -UFormat %Y%m%d-%H%M
$size1 = "{0:n2}" -f ($size / 1MB) 
$obj = new-object psobject
add-member -inp $obj noteproperty date $date
add-member -inp $obj noteproperty path $_.Name
add-member -inp $obj noteproperty size $size1 
$a += $obj 
}

I'm new to Powershell so this is where i'm getting tripped up: I have the sizes of my folders, I don't know how to extract my objects in $a, format them all pretty (like the example CSV i posted up towards the beginning of my post), get em saved as a CSV, have the script be intelligent enough to read the CSV the next time the script is ran and account for changes when it records the next line of the CSV file.

Is there a better way to do this? This is my first post after a year of super-lurking so please be gentel... lol.

Thank you!

2

2 Answers

0
votes

I gave it a try. I replaced your get-date format to match the output, because they didn't match in your sample. This creates one column for each folder. Columns are never deleted, just added. So if a new folder is added, a new column will appear in all records with values only in the records where it existed. If a folder is deleted, previous records will have a null value in that column.

cd C:\scripts
$filename = "log.csv"
$out = @()

$date = Get-Date -Format MMdd-HHmm

#Create new record
$rec = New-Object psobject -Property @{
    Date = $date
}

Get-ChildItem | where {$_.PSIsContainer} | foreach {
    $size = (Get-ChildItem $_.FullName -recurse | where {!$_.PSIsContainer} | Measure-Object -Sum Length).Sum
    $rec | Add-Member -MemberType NoteProperty -Name $_.Name -Value ("{0:n2}" -f ($size / 1MB))
}


#Check if file exists and get columns
if (Test-Path $filename -PathType Leaf) {
    $in = Import-Csv $filename
    $incol = $in | Get-Member -MemberType NoteProperty | % { $_.Name }
    $reccol = $rec | Get-Member -MemberType NoteProperty | % { $_.Name }

    #Add missing columns to exisiting records
    Compare $incol $reccol | ? { $_.SideIndicator -eq "=>" } | % { $in | Add-Member -MemberType NoteProperty -Name $_.InputObject -Value $null }
    #Add missing columns to new record
    Compare $reccol $incol | ? { $_.SideIndicator -eq "=>" } | % { $rec | Add-Member -MemberType NoteProperty -Name $_.InputObject -Value $null }

    $out += $in
}

$out += $rec

$out | Export-Csv $filename -NoTypeInformation
1
votes

You can use the Export-csv commandlet to output your data as a csv file. You just need to pipe your array values into it:

$a | Export-Csv -NoTypeInformation -path log.txt

It also looks like you want to use a semi-colon as a seperator instead of a comma, you could do that too:

$a | Export-Csv -NoTypeInformation -path log.txt -Delimiter ";"

To then read the contents of your csv, use the import-csv commandlet and store the results in a variable.

$b = import-csv -Path .\log.txt -Delimiter ";"