2017-05-14 1 views
0

Ich habe ein Skript, das die Liste der Hotfixes von einer Reihe von Servern sammeln sollte. Die Namen/Adressen der Server können in einer Textdatei gefunden werden. Das Endergebnis sollte eine CSV sein, die die Hotfixes für jeden Server auflistet.Unter Code wiederholt den gleichen Hotfix für alle Server, obwohl das nicht installiert wurde

Das Problem mit dem folgenden Code ist, dass es den gleichen Hotfix für jeden Server auflistet, obwohl dieser Hotfix nicht auf jedem Server installiert ist. Was ist der Fehler in meinem Ansatz?

$Servers = Get-Content 'C:\temp\Servers.txt' 

$gg = foreach ($Server in $Servers) 
{ 
    Try { 
     $Hotfix = Get-Hotfix -computername $Server | Where {$_.hotfixid -eq 'KBXXXXXX' -or $_.hotfixid -eq 'KBXXXXXX' -or $_.hotfixid -eq 'KBXXXXXX'} -ErrorAction Stop 
    } 
    Catch { 
     #Write-host "Unable to reach the Server " $Server 
     $ErrorMessage = $_.Exception.Message; 
     Continue 
    } 
    $HotfixID = $Hotfix.HotFixID; 
    $NotFound = "NotFound"; 
    " " | Select-Object -Property @{N="Server_Name";E={$Server}}, @{N="HotFixID";E={ 
     if ($HotfixID -eq $null) { 
      Return $ErrorMessage 
     } 
     elseif ($HotfixID -ne $null -and $ErrorMessage -eq $null) { 
      Return $HotfixID 
     } 
     elseif ($HotfixID -eq $null -and $ErrorMessage -eq $null) { 
      Return $NotFound 
     }}} 
} 
$gg | Export-CSV -NoTypeInformation 'C:\Temp\Output.csv' 

Antwort

0

Ihr aktueller Code verfügt über mehrere verschiedene Eigenschaften, die Sie möglicherweise überprüfen möchten. So wie es ist, sollte es nicht dieselben Fehler auflisten. Es ist wahrscheinlich, dass es entweder nicht der Code ist, den Sie tatsächlich ausgeführt haben, oder dass Sie Code ausgeführt haben, bevor Sie etwas eingerichtet haben. Hier ist eine Liste von Fehlern mit diesem Code:

  • Mit Ihrem aktuellen Ansatz werden Sie einen Server überspringen, wenn ein Fehler auftritt Lesen der Liste der Hotfixes. In der Zwischenzeit versuchen Sie später, auf $ErrorMessage zu handeln, das für jeden erfolgreichen Server $null sein wird.

  • Ihre Select-Object für den HotFix ist unnötig kompliziert. Es hat zwei Fälle, die buchstäblich die gleichen sind, so dass Sie nie $NotFound zurückgegeben haben werden. Zusätzlich, während ein Ausdruck unterstützt wird, könnte/sollte eine klare Variablenzuordnung wie bei der Server_Name Eigenschaft der Klarheit halber bevorzugt werden.

  • Get-HotFix unterstützt einen -Id Switch, der ein Array von HotFixID akzeptiert (im Grunde der KB-Name), das die Leistung verbessern könnte. So könnten Sie einfach tun:

    $hotfixes = Get-HotFix -Id KB4012212,KB4012215,KBDoesNotExist -ComputerName $server -ErrorAction Stop 
    
  • Die zurückgegebenen Daten durch Get-HotFix umfassen eine Eigenschaft namens PSComputer, die die Quelle der Daten, um anzuzeigen scheint. Der Parameter zur Angabe eines Computernamens akzeptiert tatsächlich auch ein Array von Strings als Parameter. Als solche könnten Sie weiter den obigen Befehl verbessern sein: Das

    $hotfixes = Get-HotFix -Id KB4012212,KB4012215,KBDoesNotExist -ComputerName "server01.example.com","server02.example.com" -ErrorAction Stop 
    

    Mit Ihnen später nur brauchen würde Select-Object auf $hotfixes und konnte direkt Leitung zum Export-CSV Cmdlets auszuführen.

Ich habe die Infrastruktur nicht, es zu testen, aber eine endgültige Lösung könnte wie folgt aussehen:

$servers = Get-Content 'C:\temp\Servers.txt' 
$hotfixes = Get-HotFix -Id KB4012212,KB4012215,KBDoesNotExist -ComputerName "server01.example.com","server02.example.com" 
$hotfixes = $hotfixes | Select-Object -Property @{Name="Server_Name";Expression={$_.PSComputerName}}, @{Name="HotFixID"; Expression={$_.HotFixID}} 
$hotfixes | Export-CSV -NoTypeInformation 'C:\Temp\Output.csv' 

Ein Nachteil hier ist, dass es sich nicht um Fehler behandeln bei dem Versuch, die verbinden Server und enthält keine Server, die keine der angegebenen Hotfixes haben. Für diese Art von Informationen müssten Sie eine Schleife verwenden.

$servers = Get-Content 'C:\temp\s.txt' 
$servers | ForEach-Object{ 
    $server = $_ 
    $serverError = $null; 

    try{ 
     $hotfixes = Get-HotFix -Id KB4012212,KB4012215,KBDoesNotExist -ComputerName $server -ErrorAction Stop 
    }catch{ 
     $errorMessage = $_.Exception.Message 
     $serverError = " " | Select-Object -Property @{Name="Server_Name";Expression={$server}}, @{Name="HotFixID"; Expression={$errorMessage}} 

    } 

    if($serverError -ne $null){ 
     $serverError 
    }else{ 
     $hotfixes = $hotfixes | Select-Object -Property @{Name="Server_Name";Expression={$_.PSComputerName}}, @{Name="HotFixID"; Expression={$_.HotFixID}} 
     $hotfixes 
    } 
} | ConvertTo-CSV -NoTypeInformation 

Theoretisch dies weiter vereinfacht als $serverError werden könnte, wäre $null, die nicht eine Ausgangsleitung erzeugen sollte.

Die KBs werden nur aus einem Artikel kopiert. Keine Ahnung, ob sie existieren würden oder nicht, sie sind nur zur Veranschaulichung da.

Verwandte Themen