2

My group is moving to a new network where we can't directly copy from our computer in Network A to the new machine in Network B. After years on this machine in Network A, I've got project files interspersed all over the disk. I need to build a script to copy the folders and files to a backup disk. No problem there, but the network tech guy requires the total byte count to be known before copying.

In CMD I've used dir /AD /S /B > C:\Users\r6540\Desktop\UserFiles.txt from C:\ to generate a huge list of directories, including a lot of junk that I've manually edited out.

e.g.

C:\Dev\SSIS
C:\Dev\SSIS\DatabaseCleanup
C:\Dev\SSIS\DatabaseMaintTests
C:\Dev\SSIS\EclipseKeys
C:\Dev\SSIS\TemplateProject

I've never used PowerShell, but it certainly looks like this task would be within its ability. I found this:

$startFolder = "C:\Scripts"

$colItems = (Get-ChildItem $startFolder | Measure-Object -property length -sum)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB"

$colItems = (Get-ChildItem $startFolder -recurse | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object)
foreach ($i in $colItems)
    {
        $subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum)
        $i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB"
    }

at Microsoft technet and also this, same page:

$objFSO = New-Object -com  Scripting.FileSystemObject
"{0:N2}" -f (($objFSO.GetFolder("C:\Scripts").Size) / 1MB) + " MB"

The output I'm looking for is the directory name, a tab, and the folder size (without the "MB" as shown above though) and CRLF as the EOL written to a text file.

e.g.

C:\Dev\SSIS 70.23
C:\Dev\SSIS\DatabaseCleanup 17.80
C:\Dev\SSIS\DatabaseMaintTests  22.91
C:\Dev\SSIS\EclipseKeys 1.22
C:\Dev\SSIS\TemplateProject 13.29

Anyone know PowerShell well enough to troop through UserFiles.txt and get the resulting text file output?

Form doesn't matter as much as function--so if you can come up with an alternate approach, I'd be glad to see it.

Thanks.

2
  • So does the output of your example satisfy your needs and you need a way to just use the text file as input and a separate file as output? Commented Jul 7, 2015 at 16:08
  • That's correct. The output file is basically just the input file with the tab and folder size inserted before EOL. Commented Jul 7, 2015 at 16:12

2 Answers 2

1

This is pretty straightforward in PowerShell:

$objFSO = New-Object -com  Scripting.FileSystemObject
Get-Content c:\input.txt |
    Foreach { "{0}`t{1:N2}" -f $_, (($objFSO.GetFolder($_).Size) / 1MB) } |
    Out-File c:\output.txt -enc ascii

This is assuming the FileSystemObject script you found works. :-)

Sign up to request clarification or add additional context in comments.

3 Comments

This works fine, except the separator is a space instead of a tab. Apparently the tabs washed out when I pasted the input file text. The output file becomes an input file for the database upload process, and the space causes an error. Know of a way we can stuff a tab character there?
You can stuff in a tab char using <backtick>t inside a double quoted string. See the updated answer.
Perfecto! This generates the exact file format needed. Thanks, Kevin!
0

Simple approach is to use the pipeline more efficiently

$inputFile = "C:\Users\r6540\Desktop\UserFiles.txt"
$outputFile = "C:\temp\output.txt"

Get-Content $inputFile | ForEach-Object{
    $sum = Get-ChildItem $_ -recurse -Force | Measure-Object -property length -sum | Select-Object -ExpandProperty Sum
    "{1}`t{0:N2}" -f ($sum / 1MB), $_
} | Set-Content $outputFile

So we take each line of the file and gather the size in MB using your posted logic. The send the output to file. But we can improve on that a little.

$inputFile = "C:\Users\r6540\Desktop\UserFiles.txt"
$outputFile = "C:\temp\output.txt"

$results = Get-Content $inputFile | ForEach-Object{
    $props = @{
        Folder = $_
        Sum = "{0:N2}" -f ((Get-ChildItem $_ -Recurse -Force | Measure-Object -property length -sum | Select-Object -ExpandProperty Sum) / 1MB)
    }

    New-Object -TypeName PSCustomObject -Property $props
}

$results | Export-CSV $outputFile -NoTypeInformation
"Total,{0}" -f ($results | Measure-Object Sum -sum | Select-Object -ExpandProperty Sum) | Add-Content $outputFile

Only difference here is that we make nice CSV output as well as a total being appended to the bottom since at the end of the day that might be nice to know as well (If I was the recipient of multiple copies from multiple users I would save me a few seconds of effort.) You could just keep a counter in the loop as well for this but this give you an opportunity to see PowerShell at work.

4 Comments

To get the true size using Get-ChildItem, use -Force to get it to list hidden files.
@KeithHill This is true.
The first script gets close, but the separator is " -- ", and I need a tab there, because the output file here becomes the input file for another process. Thanks for the total/CSV version too--very illustrative.
@JimtheFrayed replaced with tab

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.