Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Behaviour for return from Function

I've a simple CSV file. It contains Header and some values. Generally it works fine if there are more then 2 entries in the CSV file. If there is only 1 entry (and Header) it behaves very unexpected to me.

function ImportServersToProcess($csv) {
    begin {
        [System.Collections.ArrayList] $aServers = @()
    } 

    process {
        $ImportedData = Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD'
        ForEach ($item in $ImportedData){
            [System.Collections.Hashtable] $hServer = @{}

            $hServer.Hostname = $($item.Hostname)
            $hServer.ServiceIP = $($item.ServiceIP)
            $hServer.AdminIP = $($item.AdminIP)
            $hServer.IBRIP = $($item.IBRIP)
            $hServer.HW = $($item.HW)
            $hServer.VMHW = $($item.VMHW)
            $hServer.OS = $($item.OS)
            $hServer.CPUs = $($item.CPUs)
            $hServer.RAM = $($item.RAM)
            $hServer.DriveSizeC = $($item.DriveSizeC)
            $hServer.DriveSizeD = $($item.DriveSizeD)

            if ($hServer.Hostname -eq "Hostname") { continue } # Ignore 1st line/headers
            $aServers.Add($hServer) | Out-Null # OutNull is used to prevent additonal add to array of unexpected object (also suprising output)
        }
        Write-Host "Test0 - " $aServers.Count
        $aServers #| Out-Null
        Write-Host "TEST1 - " $aServers.Count
    }
    end {
    }
}

CSV looks like this:

Hostname;ServiceIP;AdminIP;IBRIP;HW;VMHW;OS;CPUs;RAM;DriveSizeC;DriveSizeD
ash000126;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300
ash000127;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300

Then I run the script using:

[System.Collections.ArrayList] $aServersToProcess = ImportServersToProcess($csvPath)
[int] $count = $($aServersToProcess.Count)
Write-Host -ForegroundColor Red "[*] There are $count servers to be checked. Starting up [*]"

Output on screen is:

Test0 -  2
TEST1 -  2
[*] There are 2 servers to be checked. Starting up [*]

Which is good. 2 servers in CSV. 2 Counts.

Now if I remove 1 server from CSV and CSV now looks like this:

Hostname;ServiceIP;AdminIP;IBRIP;HW;VMHW;OS;CPUs;RAM;DriveSizeC;DriveSizeD
ash000126;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300

Be aware there are no empty lines etc.

The return of the script is...

Test0 -  1
TEST1 -  1
[*] There are 11 servers to be checked. Starting up [*]

Where does 11 come from?

If I modify the script and add $aServers.Count behind $aServers

Write-Host "Test0 - " $aServers.Count        
$aServers 
$aServers.Count
Write-Host "TEST1 - " $aServers.Count

The output is this:

Test0 -  1
TEST1 -  1
[*] There are 2 servers to be checked. Starting up [*]
like image 228
MadBoy Avatar asked Dec 05 '25 03:12

MadBoy


1 Answers

The 11 is coming from the number of headers in the CSV. This is an issue where you are getting a single object, vs. a collection with more than one entry in the csv.

I'm thinking the best solution here is going to be to typecast $ImportedData as an array, so that if there is only one element it becomes a collection, not an object.

$ImportedData = @(Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD')

That is one simple way to accomplish this. Another way is:

[Collections.Generic.List[Object]]$ImportedData = Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD'

Edit: As it turns out, it looks like the issue is actually in your return, and when there is only one object in the output, it is being received as a single hashtable, not an array of hashtables. Use a comma in your return statement to force the return to go through as a collection:

,$aServers #| Out-Null

Just saw someone beat me to this in the comments.

like image 164
omrsafetyo Avatar answered Dec 07 '25 19:12

omrsafetyo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!