ForEach Output To file

Hi everyone, trying to get some guidance on a script i’m working on. I’m trying to calculate the size of folder by adding everything inside the folder, and i’m trying to do this for a list of remote machines, which means each folder path and server name is different

I have a CSV with three columns the heading for each of the columns are ServerName, FolderName, FolderPath. So far when i run the script I’m able to get the information I want but since its using Write-Host i cant out it to a file.

Here’s the script i’v created:

$CsvArray = Import-Csv .\Serverlist.csv

$(Foreach ($Database in $CsvArray) {Write-Host $Database.MailboxServer $Database.FolderName ((Get-ChildItem -Path $Database.FolderPath
 | Measure-Object Length -sum | select-object $Database.FolderName -ExpandProperty Sum)/1GB).ToString('0.00')} )

And my Output looks like this:

Server01       Diving 11.46
Server 02     Books   1.20

 

Anyone know how I can get it to output to a file with the headings as well?

Thanks.

You never really need write-host for anything other than write colorized text to the screen or certain formatting needs.

Output to the screen is the default. If you find yourself using write-Host or any of its aliases, stop, an rethink what you are doing.

If it is a fully automated process, where a user is not at the screen the writing to the screen is really moot, since you can use -Verbose to write additional stuff to the screen without using write-Host, or just use Start/Stop-Transcript to capture stuff.

If you are ever planning to output to a file, the that eliminates Write-Host for any associated data, since Write-Host will empty the buffer, thus nothing to send down the pipeline / stream.

You can just use any of the other data redirect methods or Write-Output, Out-File, or Export-CSv, etc., to get your file.

So, tweaking what you have here, maybe this is more prudent for you

$(Foreach ($Database in $CsvArray) 
{
    Write-Output $Database.MailboxServer $Database.FolderName ((Get-ChildItem -Path $Database.FolderPath `
    | Measure-Object Length -sum `
    | select-object $Database.FolderName -ExpandProperty Sum)/1GB).ToString('0.00') `
    | Export-Csv -Path "$TargetPath\DatabaseData.csv" -Append
})

Thanks postanote, but when i do that i get this output

#TYPE System.String
Length
9
6
5
9
5
4

 

Maybe this is what you are looking for.

Import-Csv .\Serverlist.csv |
    Select-Object -Property MalBoxServer,FolderName,@{E={((Get-ChildItem -Path $_.FolderPath |
    Measure-Object Length -sum | Select-Object -ExpandProperty Sum)/1GB).ToString('0.00')};L='Size'} |
    Export-Csv -Path "$TargetPath\DatabaseData.csv"

What does the csv look like? Yes, I would use select-object or [pscustomobject] to make the object properties, then pipe to export-csv.

[quote quote=127579]What does the csv look like? Yes, I would use select-object or [pscustomobject] to make the object properties, then pipe to export-csv.

[/quote]

The Csv being read looks like this

MailboxServer | FolderName | FolderPath

Server001 | Backup Folder | D:\Backups

 

And i’m trying to output like this

MailboxServer | FolderName | FolderPath | Size (GB)

Server001 Backup Folder D:\Backups 11.6

[quote quote=127536]Maybe this is what you are looking for.

PowerShell
5 lines
<textarea class="ace_text-input" style="opacity: 0; height: 18px; width: 6.59781px; left: 44px; top: 0px;" spellcheck="false" wrap="off"></textarea>
1
2
3
4
5
Import-Csv .\Serverlist.csv |
Select-Object -Property MalBoxServer,FolderName,@{E={((Get-ChildItem -Path $_.FolderPath |
Measure-Object Length -sum | Select-Object -ExpandProperty Sum)/1GB).ToString('0.00')};L='Size'} |
Export-Csv -Path "$TargetPath\DatabaseData.csv"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[/quote] Thanks kvprasoon, i can work with this :)

Are these ‘|’ really in the CSV file as the separator / delimiter, or did you just type this in this post?
Remember the ‘|’ has special meaning in PowerShell.

If that is the case, then on your import, you have deal with that, any spaces, line feeds etc.

You don’t show any code that you are addressing that at all. So… stepping through this …

$FilePath = 'D:\Documents\ServerList.csv'

Get-Content -Path $FilePath

<#
MailboxServer |   FolderName      | FolderPath

Server001         |    Backup Folder  |  D:\Backups
#>

Import-Csv -Path $FilePath

# Results 

MailboxServer |   FolderName      | FolderPath     
----------------------------------------------     
Server001         |    Backup Folder  |  D:\Backups



# Specifying the delimiter '|'
($ServerList = Import-Csv -Path $FilePath -Delimiter '|')

# Results 

MailboxServer  FolderName      FolderPath
-------------- -----------     ----------
Server001      Backup Folder   D:\Backups



# Using one of my lab machine folders, and tweaking your example to match my resource
$FilePath = 'D:\Documents\ServerList1.csv'
($ServerList = Import-Csv -Path $FilePath -Delimiter '|')

# Results

Server     FolderName  FolderPath
-------    ----------- ----------
localhost  Temp        D:\Temp 


$ServerList.FolderPath

# Results

D:\Temp


Clear-Host
ForEach ($TargetServer in $ServerList)
{
    Get-ChildItem -Path $TargetServer.FolderPath -Recurse -Directory | 
    Select-Object @{Name = 'ServerName';Expression = {$TargetServer.'Server '}},Name,FullName,
    @{Name = 'SizeMB';Expression = {"{0:N2}" -f (((Get-ChildItem $_.FullName -Recurse | Measure-Object -Property Length -Sum).Sum) / 1MB)}} `
    | Export-csv -Path 'D:\temp\ServerFolderSizeData.csv'
}

Import-Csv -Path 'D:\temp\ServerFolderSizeData.csv'

# Results


ServerName Name           FullName                               SizeMB
---------- ----           --------                               ------
localhost  abcpath0       D:\Temp\abcpath0                       0.01  
...  
localhost  Duplicates     D:\Temp\Duplicates                     88.98 
localhost  EmptyFolder    D:\Temp\EmptyFolder                    0.00  
...  
localhost  results        D:\Temp\results                        0.63
...