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-Key: 271492

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

Printed on: April 23, 2024 at 09:04 o'clock

Mitglied: 114757
114757 May 08, 2015 updated at 15:51:31 (UTC)
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
Member: colinardo
colinardo May 08, 2015 updated at 16:59:27 (UTC)
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
Member: cyborg19
cyborg19 May 08, 2015 at 17:17:49 (UTC)
Goto Top
Kannte ich nicht, sieht auch sehr interessant aus, werde ich Mal genauer anschauen, Danke face-smile
Member: cyborg19
cyborg19 May 08, 2015 at 17:19:22 (UTC)
Goto Top
vielen Dank, ich werde mir das noch genauer anschauen.
Member: cyborg19
cyborg19 Jun 05, 2015 updated at 11:50:51 (UTC)
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!
Mitglied: 114757
Solution 114757 Jun 05, 2015, updated at Jun 19, 2015 at 19:23:57 (UTC)
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.