TraPS
TraPS

Reputation: 35

Updating PSObject hash table in loop

Here is a part code of uploading data by FTP

foreach ($line in $FTPServer)
    {
        Start-Transcript -Path $results            
        Write-Host -Object "ftp url: $line"
        If (Test-Connection $line -Count 1)
        {

            Set-FTPConnection -Credentials $FTPCredential -Server $line -Session MySession -UsePassive -ErrorAction SilentlyContinue
            $Session = Get-FTPConnection -Session MySession
            if($session.UsePassive -eq "True"){$connect="OK"}
            else{$connect="!!!-FAIL-!!!"}

            foreach ($item in (Get-ChildItem .\Upload))
                {
                    Write-Host -Object "Uploading $item..."
                    $Send= Add-FTPItem -Session $Session -Path $FTPPlace -LocalPath .\Upload\$item -Overwrite -ErrorAction SilentlyContinue
                    if($Send.Name -eq $item.Name){$Rec="OK"}
                    else{$Rec="!!!-FAIL-!!!"}
                    $array = $line, $item, $connect, $Rec
                    $FailTable=New-Object -TypeName PSObject -Property ([ordered]@{"FTP Server"=$array[0]; "File"=$array[1];"Connected"=$array[2];"Uploaded"=$array[3]})

                    $FailTable|Out-File -Append '.\stats.txt'
                }
        Stop-Transcript
        } Else {"$line">> .\DownServers.txt}
    }

$Failtable is a hash-table that stores ip of FTP server ($line), name of uploaded file ($item), status if connected ($connect) and upload status ($Rec). The hash-table is piped to file .\stats.txt The problem is in every iteration to .\stats.txt are saved headers like that:

FTP Server  File                    Connected Uploaded    
----------  ----                    --------- --------    
192.168.1.1 ConfigurationDivide.xml OK        !!!-FAIL-!!!



FTP Server  File     Connected Uploaded    
----------  ----     --------- --------    
192.168.1.1 test.txt OK        !!!-FAIL-!!!

So I need that to be one under another and autosized like that:

FTP Server  File                    Connected Uploaded    
----------  ----                    --------- --------    
192.168.1.1 ConfigurationDivide.xml OK        !!!-FAIL-!!!    
192.168.1.1 test.txt                OK        !!!-FAIL-!!!

I tryed to put hash-table declaration $FailTable=New-Object -TypeName PSObject -Property ([ordered]@{"FTP Server"=$array[0]; "File"=$array[1];"Connected"=$array[2];"Uploaded"=$array[3]}) before loops and then- in the loops add values ($line, $item,...), but there aren't in hashtable .add method.

Upvotes: 1

Views: 1226

Answers (2)

Phil
Phil

Reputation: 336

You need to have FailTable created outside the loop, you are creating and appending an entire new PSCustomObject each loop to the file.

try implementing this:

$FailTable = @()
#Example loop
for($i =0;$i -lt 5; $i++){
        #Inside the loop add new object to the array
        $failTable += @{"FTPServer"=$i;"File"=$i;"Connected"=$i;"Uploaded"=$i}
}
 #foreach hashmap in the array cast to a PSCustomObject (which gives you the headers you want)
 #and then Select-Object The order you want them in.
$FailTable.foreach{[PSCustomObject]$_} | Select-Object "FTPServer", "File","Connected", "Uploaded" | Out-file test.txt

Edit:

PowerShell v2+ compatible version:

$FailTable = @()
$objTable = @()
#Example loop
for($i =0;$i -lt 5; $i++){
        #Inside the loop add new object to the array
        $failTable += @{"FTPServer"=$i;"File"=$i;"Connected"=$i;"Uploaded"=$i}
}
 #foreach hashmap in the array cast to a PSCustomObject (which gives you the headers you want)
 #and then Select-Object The order you want them in.
foreach($fail in $FailTable){
    $objTable += New-Object -TypeName PSCustomObject -Property $fail

}
$objTable | Select-Object "FTPServer", "File","Connected", "Uploaded" | Out-file test.txt

Upvotes: 0

Michał Gąsior
Michał Gąsior

Reputation: 41

Ok, different answer :)

Try this:

$FailTable = @()

$spam = New-Object PSObject
$spam | Add-Member -type NoteProperty -Name 'FTP Server' -Value ""
$spam | Add-Member -type NoteProperty -Name 'File' -Value ""
$spam | Add-Member -type NoteProperty -Name 'Connected' -Value ""
$spam | Add-Member -type NoteProperty -Name 'Uploaded' -Value ""

$FailTable += $spam
$FailTable | Out-File -Append '.\stats.txt'

foreach ($line in $FTPServer)
{
    Start-Transcript -Path $results
    Write-Host -Object "ftp url: $line"
    If (Test-Connection $line -Count 1)
    {

        Set-FTPConnection -Credentials $FTPCredential -Server $line -Session MySession -UsePassive -ErrorAction SilentlyContinue
        $Session = Get-FTPConnection -Session MySession
        if($session.UsePassive -eq "True"){$connect="OK"}
        else{$connect="!!!-FAIL-!!!"}

        foreach ($item in (Get-ChildItem .\Upload))
            {
                Write-Host -Object "Uploading $item..."
                $Send= Add-FTPItem -Session $Session -Path $FTPPlace -LocalPath .\Upload\$item -Overwrite -ErrorAction SilentlyContinue
                if($Send.Name -eq $item.Name){$Rec="OK"}
                else{$Rec="!!!-FAIL-!!!"}

                $spam = New-Object PSObject
                $spam | Add-Member -type NoteProperty -Name 'FTP Server' -Value $line
                $spam | Add-Member -type NoteProperty -Name 'File' -Value $item
                $spam | Add-Member -type NoteProperty -Name 'Connected' -Value $connect
                $spam | Add-Member -type NoteProperty -Name 'Uploaded' -Value $Rec

                $FailTable += $spam
                $FailTable | Select-Object -Last 1 | Format-Table -HideTableHeaders | Out-File -Append '.\stats.txt'
            }

    Stop-Transcript
    } Else {"$line">> .\DownServers.txt}
}

Upvotes: 1

Related Questions