Массив не выводит данные за пределы функции в PowerShell - PullRequest
2 голосов
/ 25 марта 2020

Вот код

$conn =  'saruspc01', '194.195.5.65'

 function lll {
    foreach($co in $conn)
    {
       $check = Test-Connection $co -Count 3 -ErrorAction SilentlyContinue
       $zugriffzeit = $check | select ResponseTime | Measure-Object ResponseTime -Average
       $avg = [system.math]::Round($zugriffzeit.Average)

        if($check -eq $null)
        {
            $pcre = Write-Output $co
            $pire = Write-Output 'False'
            $zure = 'Null'
        }
        else
        {
            $pcre = Write-Output $co
            $pire = Write-Output 'True'
            $zure = Write-Output "$avg ms"
            $zure = $zure.Replace(' ','')
        }
        $table += @( @{PCName=$pcre;    PingResult=$pire;    Zugriffszeit=$zure} )
        #$table | ForEach {[PSCustomObject]$_} | Format-Table -AutoSize
    }
}

Если я выполняю тот же код без функции, он работает. Мне нужна функция, хотя и хочу сделать это именно так. Как я могу это исправить?

1 Ответ

1 голос
/ 25 марта 2020

Большая проблема в том, что вы добавляете элементы в $table, но вы не return возвращаете таблицу пользователю. Итак, обо всем по порядку, измените конец своей функции так, чтобы она читалась следующим образом. (Я добавил комментарий #EndOfForEach, чтобы подчеркнуть, где необходимо внести изменения: go.

        $table += @( @{PCName=$pcre;    PingResult=$pire;    Zugriffszeit=$zure} )                
    }#EndOfForEach
    return $table
}

После того, как это изменение будет выполнено, ваша функция будет работать, но только когда вы ее так называете:

PS:\>lll
Name                           Value                                             
----                           -----                                             
PCName                         behemoth                                          
Zugriffszeit                   1ms                                               
PingResult                     True                                              
PCName                         notonline                                         
Zugriffszeit                   Null                                              
PingResult                     False                                             

На этом этапе я бы порекомендовал два изменения: во-первых, макет трудно читать, поэтому я бы преобразовал функцию для использования типа данных [psCustomObject] вместо этого, например, так:

function lll {
    $results = New-Object System.Collections.ArrayList
    #...

   $results.Add([psCustomObject]@{PCName=$pcre;    PingResult=$pire;    Zugriffszeit=$zure})| Out-Null
    }#EndOfForEach
    return $results
}

Для вывода, подобного следующему:

PS>lll

PCName    PingResult Zugriffszeit
------    ---------- ------------
behemoth  True       1ms         
notonline False      Null  

И если вы хотите поднять свою функцию на следующий уровень, вы будете хорошо настроены на то, чтобы изменить функцию, чтобы она принимала параметры вместо того, чтобы полагаться на для переменной $conn, которая уже установлена. Надеюсь, это поможет, дайте мне знать, если у вас есть какие-либо вопросы или я мог бы углубиться в область.

Почему $results не поддерживает значение?

PowerShell использует область видимости переменной, поэтому переменная $results, которую мы определяем в этой функции, будет существовать только до тех пор, пока функция работает . Чтобы сохранить результаты, присвойте их переменной, когда Вы вызываете функцию, как это.

* 1 027 *

Завершенный сценарий

function lll {
    $results = New-Object System.Collections.ArrayList
    foreach($co in $conn)
    {
       $check = Test-Connection $co -Count 3 -ErrorAction SilentlyContinue
       $zugriffzeit = $check | select ResponseTime | Measure-Object ResponseTime -Average
       $avg = [system.math]::Round($zugriffzeit.Average)

        if($check -eq $null)
        {
            $pcre = Write-Output $co
            $pire = Write-Output 'False'
            $zure = 'Null'
        }
        else
        {
            $pcre = Write-Output $co
            $pire = Write-Output 'True'
            $zure = Write-Output "$avg ms"
            $zure = $zure.Replace(' ','')
        }
        $results.Add([psCustomObject]@{PCName=$pcre;    PingResult=$pire;    Zugriffszeit=$zure})| Out-Null
    }#EndOfForEach
    return $results
}
...