2017-11-27 2 views
0

Ich arbeite an PowerShell-Skript, das Server-Dienste überprüfen wird. Ich bekomme immer ein "Kann nicht in ein Null-Array indizieren."Warum wird mein Array als null gelesen? Was vermisse ich?

Der Fehler verweist, wenn die zweite Anweisung "if ($ select_string_result.Line [$ select_string_result.Line.Length-1] eq '1')"

Der Objekttyp von "$ select_string_result" angezeigt wird, wie Array und die TXT-Datei enthält Daten, aber das Skript wird nicht verarbeitet.

Die „Line“ Eigenschaft des Array-Datensätze als null und die „Länge“ aufgezeichnet wird, wie 0.

$filepathserver = 'Path' 
$filepathlocal = 'Path' 

function Get-Timestamp 
{ 
    return Get-Date -Format "MM/dd/yyyy hh:mm:ss tt" 
} 

function refresh-data 
{ 
    # Pulls Services and Services Status 
    $orionData = Get-SwisData $swis "SELECT ComponentID, StatusDescription FROM Orion.APM.Component" 

    # Sends output to a txt file 
    $orionData | Out-File "$filepathlocal\All_App_Services.txt" 
} 

function check-status($select_string_result) 
{ 
    if ($select_string_result.Line -isnot [system.array]) 
    { 
     if ($select_string_result.Line[$select_string_result.Line.Length-1] -eq '1') 
     { 
      return 100 
     } 
     else 
     { 
      return 0 
     } 
    } 
    else 
    { 
     $sum = 0.0 
     $add = 100.0/$select_string_result.Length 

     foreach ($match in $select_string_result) 
     { 
      if ($match.Line[$match.Line.Length-1] -eq '1') 
      { 
       $sum += $add 
      } 
     } 
     if ($sum -lt 100) {$sum = 0} # this line collapses the values in to either 0 or 100 
     $sum = [int][Math]::Ceiling($sum) 
     return $sum 
    } 
} 

function main 
{ 
    refresh-data 
    # Filters for Application specific Services 
    $f = @("94944 ", "94945 ", "94951 ", "94946 ", "94942 ", "94948 ", "94949 ", "94950 ", "94943 ", "94947 ", "94952 ", "94953 ") 

    $AppServices = Get-Content "Path" | Select-String $f 
    $AppServices | Set-Content "Path" 

    #Removes leading spaces from array 
    (Get-Content "$filepathlocal\File.txt") -replace "Up","1" | % {$_.trim()} | Out-File "$filepathlocal\File.txt" 

    $AppServices = Get-Content "$filepathlocal\File.txt" 
    $AppServices.GetType() 

    # Writes status of each group to .txt file 
    $logfile= "$filepathserver\ServicesStatus.txt" 
    $t = Get-Timestamp 
    $v = check-status $AppServices 
    $s = "$t|Application-Services|$v" 
    $s | Out-File $logfile -Append -Encoding "UTF8" 
    $s 
} 

main 
+0

eine viel schönere, kurz- oder Powershell-idiomatische Funktion bekommen Können Sie erklären, was die erste 'if' Aussage tut? 'if ($ select_string_result.Line -isnot [system.array]) ' scheint zu sagen, dass das Ding, in das man zu indizieren versucht, kein Array ist. Das könnte die Ursache Ihres Problems sein. – Patrick87

+0

Es prüft, ob ein Array übergeben wird, wenn es nicht zur else-Anweisung weitergeht und am Ende jeder Zeile in der Textdatei eine mathematische Berechnung durchführt. Da die zweite if-Anweisung aufgerufen wird, wird die Variable als Array betrachtet. Oder ich nehme an, dass es ist. Ich rufe auch eine "variable.GetType", die die Variable als ein Array meldet. – user3347022

Antwort

1

$select_string_result.Line zu $null löst, da das Array von Strings, die Sie von Get-Content nicht bekommen eine hat Line Eigenschaft, so dass die if Aussage sollte aussehen wie:

if($select_string_result[$select_string_result.Length - 1] -eq '1') { ... } 

Powershell können Sie auch mit nur -1 den letzten Index adressieren, al Brüllen uns die Erklärung zu vereinfachen, wie:

if($select_string_result[-1] -eq '1') { ... } 

aber sagt, dass anstatt zu versuchen, ob der Parameter an eine Funktion übergeben zu überprüfen, ein Array ist oder nicht, würden Sie die Parameter ein Array in dem ersten erklären platzieren und dann eine foreach Schleife über sie verwenden:

function check-status([string[]]$select_string_result) 
{ 
    $sum = 0.0 
    $add = 100.0/$select_string_result.Length 

    foreach ($match in $select_string_result) 
    { 
     if ($match[-1] -eq '1') 
     { 
      $sum += $add 
     } 
    } 
    if ($sum -lt 100) {$sum = 0} # this line collapses the values in to either 0 or 100 
    $sum = [int][Math]::Ceiling($sum) 
    return $sum 
} 

viel schöner, viel weniger Code.

Statt nun in die String-Index versucht, würde ich vorschlagen, den -like Wildcard Operator oder den -match Regex-Operator zu überprüfen, ob jeder String mit 1 endet:

if ($match -like '*1') 
{ 
    $sum += $add 
} 

Da $sum ist immer genau 100 oder anderweitig zu 0 zurückgesetzt wird, kann der Anruf an [Math]::Ceiling() ist redundant und entfernt werden:

function check-status([string[]]$select_string_result) 
{ 
    $sum = 0.0 
    $add = 100.0/$select_string_result.Length 

    foreach ($match in $select_string_result) 
    { 
     if ($match -like '*1') 
     { 
      $sum += $add 
     } 
    } 
    if ($sum -lt 100) {$sum = 0} # this line collapses the values in to either 0 or 100 
    return $sum 
} 

Wenn Sie sich die implementierte Funktion genau ansehen, werden Sie feststellen, dass der einzige Fall, in dem 100 zurückgegeben wird, ist, wenn alle Strings in $select_string_result enden in 1.

Wir können einfach mit den -like Bediener direkt auf unserer Eingangsanordnung für diesen Test, wird es als Filter Betreiber handeln:

function check-status([string[]]$select_string_result) 
{ 
    if(@($select_string_result -like '*1').Count -eq $select_string_result.Count) 
    { 
     $sum = 100 
    } 
    else 
    { 
     $sum = 0 
    } 
    return $sum 
} 

nun eine andere Art und Weise zu behaupten, dass alle Strings im Array enden in 1, ist einfach zu testen, ob keine String tut nicht Ende in 1:

function check-status([string[]]$select_string_result) 
{ 
    if(@($select_string_result -notlike '*1')) 
    { 
     $sum = 0 
    } 
    else 
    { 
     $sum = 100 
    } 
    return $sum 
} 

Jetzt ein ll müssen wir es tun sind, leuchten ein wenig, wie Änderung check zu einem angemesseneren Verb und wir haben :-)

function Measure-StatusValue 
{ 
    param(
     [ValidateNotNullOrEmpty()] 
     [string[]]$StatusStrings 
    ) 

    if(@($StatusStrings -notlike '*1')) 
    { 
     return 0 
    } 

    return 100 
} 
Verwandte Themen