BenH's helpful answer provides an effective solution that performs the output formatting directly inside the FileSize function.
Alternatively, for more flexibility, consider refactoring your approach so as to separate the aspects of data gathering and output formatting:
First, modify your function:
- to accept the file containing the target paths as a parameter
- to output custom objects that have a
.Path property containing the file path at hand, .Size property containing the aggregate size as a number (type [double].
Function FileSize {
param(
[string] $PathsFile
)
foreach ($path in Get-Content $PathsFile) {
[pscustomobject] @{
Path = $path
Size = (Get-ChildItem -File $path -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum
}
}
}
The data-only output of the function then lets you decide later how to format the data and where to save it:
Using BenH's approach in a ForEach-Object call:
FileSize 'C:\path\path\path\path\paths2.txt' |
ForEach-Object { '{0} : {1:N2} GB' -f $_.Path, ($_.Size/1GB) }
You can simply append > out.txt, for instance, to save the output in a file; alternatively, piping to Out-File or Set-Content allows you to control the output file's character encoding with the -Encoding parameter.
To produce friendly tabular output for display, you can pipe to Format-Table using a calculated property:
FileSize 'C:\path\path\path\path\paths2.txt' |
Format-Table Path, @{ n='Size'; e={ '{0:N2} GB' -f ($_.Size/1GB) } }
Finally, for further programmatic processing, you can pipe FileSize output to export cmdlets such as Export-Csv and Export-CliXml or even conversion cmdlets such as ConvertTo-Json.