cyborg19
Goto Top

Dienste mit Powershell überprüfen

Hallo zusammen
Ich habe ein Script zusammen gebastelt, damit ich sehe welche Service nicht mehr laufen.

Nun gibt es noch einen Fall das ich in das Script aufnehmen möchte. Er soll mir das old.txt neu überschreiben, falls der Server nun neue Dienste hat.

Am besten überprüfe ich das anhand der Namen, denke ich. Falls es im neu.txt einen neuen Dienst hat den es im old.txt nicht gibt, soll er dass old.txt neu überschreiben.

Ich weis aber nicht wie ich das aus der jetzigem Script machen soll.
Zurzeit überschreibe ich das old.txt, falls das neue mehr Zeilen hat als das old.txt. Ich fände es aber mit dem namen schöner.

#Variabeln
$file_old = "c:\scripts\old.txt"  
$file_new = "c:\scripts\new.txt"  


#read out all services once
if(test-path $file_old){}else{
$services = Get-WmiObject Win32_Service |
Format-Table -AutoSize @(
    'Displayname'  
    @{ Expression = 'State'; Width = 9 }  
    @{ Expression = 'StartMode'; Width = 9 }  
    )
#save output in to a file
$services | out-file $file_old    
}


#Read the current state of the services
$services = Get-WmiObject Win32_Service |
Format-Table -AutoSize @(
    'Displayname'  
    @{ Expression = 'State'; Width = 9 }  
    @{ Expression = 'StartMode'; Width = 9 }  
    )
$services | out-file $file_new   



#Compare both files
$change = Compare-Object (get-content $file_old) (get-content $file_new) |
    where {$_.SideIndicator -eq "=>"} |  
    select -ExpandProperty inputObject 
if ($change -eq $Null){
}else{
write-host  ; throw "Error: Status has changed!"  
$change
}


#Compare how much line
$old = get-content c:\scripts\old.txt 
$new = get-content c:\scripts\new.txt 

$old.Length
$new.length

if ($old.length -ne $new.length){
Write-Host "Im neuen hat es mehr oder weniger Zeilen, die alte Datei wird neu eingelesen"  
$services = Get-WmiObject Win32_Service |
Format-Table -AutoSize @(
    'Displayname'  
    @{ Expression = 'State'; Width = 9 }  
    @{ Expression = 'StartMode'; Width = 9 }  
    )

$services | out-file $file_old   
}else{
write-host "ok"  
}

Content-ID: 271492

Url: https://administrator.de/contentid/271492

Ausgedruckt am: 15.11.2024 um 11:11 Uhr

114757
114757 08.05.2015 aktualisiert um 17:51:31 Uhr
Goto Top
Moin,
ich würde das besser so über Objekte und einer CSV-Datei machen(weil zuverlässiger), anstatt mit einer Plaintext formatierten Datei:
$file_compare = "c:\scripts\compare_services.csv"  
# aktuelle Services holen
$services = gwmi win32_service | select Displayname,State,StartMode | sort DisplayName

# wenn csv-datei noch nicht exisitiert exportiere die aktuellen Dienste in eine CSV
# ansonsten importiere die CSV als Objekt
if (!(Test-Path $file_compare)){
    $services | export-csv $file_compare -Delimiter ";" -NoType -Encoding UTF8  
    $old = $services
}else{
    $old = Import-CSV $file_compare -Delimiter ";"  
}

# Überprüfe auf Änderungen
$change = compare $old $services -Property DisplayName,State,StartMode | ?{$_.SideIndicator -eq '=>'}  
if ($change){
    write-host "Status has changed!" -ForegroundColor Yellow  
    $change
}

# Teste auf neue Dienste, und bei neuen Diensten exportiere die neue CSV-Datei
if(compare $old $services -Property DisplayName | ?{$_.SideIndicator -eq '=>'}){  
    $services | export-csv $file_compare -Delimiter ";" -NoType -Encoding UTF8  
}
Gruß jodel32
colinardo
colinardo 08.05.2015 aktualisiert um 18:59:27 Uhr
Goto Top
Hallo cyborg19,
und noch nachträglich zur allgemeinen Information falls das vielleicht mal von Interesse sein sollte: Man kann den Status bzw. Änderungen an den Diensten auch live über eine WMI-EventMonitoring überwachen:
Das sieht dann bspw. so aus:
if (Get-EventSubscriber -SourceIdentifier "servicemonitor" -EA SilentlyContinue){Unregister-Event "servicemonitor"}  
$action = {
    $new_state = $event.SourceEventArgs.NewEvent.TargetInstance
    $prev_state = $event.SourceEventArgs.NewEvent.PreviousInstance
    write-host "Der Dienst '$($new_state.DisplayName)' hat seinen Status geändert." -ForegroundColor Yellow  
    compare $new_state $prev_state -Property State,StartMode | out-host
}
Register-WmiEvent -Query "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Service'" -Action $action -SourceIdentifier "servicemonitor" | out-null  
write-host "Warte auf Änderungen an den Diensten ..." -ForegroundColor Green  
while($true){
    sleep(1)
}
Damit lassen sich auch die Events __InstanceCreationEvent und __InstanceDeletionEvent überwachen, d.h. neu erstellte oder gelöschte Dienste, oder Alternativ auch alle zusammen mit __InstanceOperationEvent.

Das nur mal so zur Anregung, falls du es noch nicht kennst und du deinen Horizont dahingehend erweitern willst face-wink

Grüße Uwe
cyborg19
cyborg19 08.05.2015 um 19:17:49 Uhr
Goto Top
Kannte ich nicht, sieht auch sehr interessant aus, werde ich Mal genauer anschauen, Danke face-smile
cyborg19
cyborg19 08.05.2015 um 19:19:22 Uhr
Goto Top
vielen Dank, ich werde mir das noch genauer anschauen.
cyborg19
cyborg19 05.06.2015 aktualisiert um 13:50:51 Uhr
Goto Top
Ich hätte noch eine Frage. Ich Benutzte nun das Script, welches jodel32 vorgeschlagen hat.
 
# Überprüfe auf Änderungen
$all = compare -includeEqual $old $services -Property DisplayName,State,StartMode -passThru | Where {$_.SideIndicator -eq "=>" -or $_.SideIndicator -eq "=="} |  
Format-Table -AutoSize 
$change = compare -includeEqual $old $services -Property DisplayName,State,StartMode | ?{$_.SideIndicator -eq '=>'}  

$all
if ($change){ 
    $change 
    write-host  ; throw "Error: Status has changed!"  
    
} 



Nun möchte ich gerne noch eine weitere Spalte hinzufügen.
Wenn == Ok
Wenn => error

Ausgabe:
Zugriff auf Eingabegeräte Running Manual == Ok
Erkennung interaktiver Dienste Stopped Manual => Error

Ich habe dies mit foreach versucht klappt aber nicht wirklich:
 
foreach ($row in $all){
write-host $row "ok"  
}


Zusätzlich zähle ich auch noch mit Count wie viele Fehler es hat.
Aber das funktioniert auch nicht da, der Wert 0 auch mit zählt und ich dann immer ein Fehler erhalte.
Ausgabe
x Services laufen nicht!
114757
Lösung 114757 05.06.2015, aktualisiert am 19.06.2015 um 21:23:57 Uhr
Goto Top
Mit calculated Properties kein Hexenwerk...
# Überprüfe auf Änderungen
$all = compare $old $services -Property DisplayName,State,StartMode -includeEqual -passThru | ?{$_.SideIndicator -match '==|=>' | select DisplayName,State,Startmode,@{n="MeinStatus";e={if($_.Sideindicator -eq "=="){"OK"}else{"FEHLER"}}}  
$change = $all | ?{$_.MeinStatus -eq "FEHLER"}  

$all | Format-Table -AutoSize

if ($change){ 
    write-host "$($change.count) Dienste haben ihren Status geändert!" -ForegroundColor Yellow  
    $change
} 
Bitte dann noch als gelöst markieren. Danke.