bacchi
Goto Top

Änderungen der Adaptereinstellungen loggen

Wie logge ich bei Windows (7 bis 11) Änderungen der statischen IPv4-Adresse, Subnetzmaske, Gateway usw.?

Informierte Internetkreise meinen, der IP-Hilfsdienst loggt das (Quelle IpHlpSvc im Windows-Protokoll System). Bei mir erscheint da nix, vermutlich weil es nicht um IPv6 geht.

Nächste Idee war, die Registrierung zu überwachen. Der entsprechende Schlüssel befindet sich in:
HKLM\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\
Beim entsprechenden Unterschlüssel habe ich die Wertänderung überwacht. In den Meldungen (Windows-Protokoll Sicherheit) sieht man leider nur, dass etwas geändert wurde, aber nicht was.

Also müsste man weitergehen und eine Aufgabe anlegen, die auf dieses Überwachungsereignis hin auslöst. Damit ließe sich irgendwie ein Log zusammenskripten, aber...

Habe ich nicht etwas übersehen? Geht das vielleicht einfacher? Irgendwelche obskuren Optionen? Netsh?

FYI: Es geht um Labor-Laptops, die regelmäßig für verschiedene Messgeräte umkonfiguriert werden und öfter den Besitzer wechseln. Mit dem händischen Notieren der Änderungen klappt es bisher nur mäßig. Ein Log mit den letzten Einstellungen wäre daher hilfreich.

Content-Key: 2044047709

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

Printed on: May 5, 2024 at 01:05 o'clock

Member: em-pie
em-pie Mar 02, 2022 at 17:07:33 (UTC)
Goto Top
Moin,

prüfe mal, ob etwas im eventlog protokolliert wird:
Windows-Protokolle -> System -> Quelle: Iphlpsvc

Gruß
em pie
Mitglied: 1915348599
1915348599 Mar 02, 2022 at 20:12:31 (UTC)
Goto Top
WMI Event Subscriben mit
SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA "Win32_NetworkAdapter"  
Member: bacchi
bacchi Mar 04, 2022 at 10:37:50 (UTC)
Goto Top
@em-pie
Das Protokoll ist aktiviert und der Dienst läuft. Die Beschreibung des IP-Hilfsdienst in services.msc spricht von IPv6-Übergangstechnologien. Daher habe ich das nicht weiter verfolgt.


@1915348599
Danke für den Fingerzeig. Heißt das dann, ich muss auf alle Fälle ein Skript dazu schreiben? Ich bin jetzt mit Powershell gegangen, da brauche ich allerdings noch Nachhilfe.
# wmic nicconfig get description,settingid
$CLSID = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'  
$PFAD = 'HKLM:\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\'  
$NIC = Get-Item $PFAD$CLSID

$Q = 'SELECT * FROM __InstanceModificationEvent  
WITHIN 5 WHERE TargetInstance ISA "Win32_NetworkAdapter"'  

Register-WMIEvent -Query $Q -Action {
    Write-Host Neue Konfiguration
    Write-Host $NIC.getvalue('IpAddress')  
    Write-Host $NIC.getvalue('SubnetMask')  
    Write-Host $NIC.getvalue('DefaultGateway')  
}
Um herauszufinden, was sich geändert hat, gehe ich immer noch über die Registrierung, außerdem müsste ich für jeden Laptop die CLSID herausfinden. Kann ich nicht das Ereignisobjekt dafür benutzen, um herauszufinden, was sich geändert hat?
Mitglied: 1915348599
1915348599 Mar 04, 2022, updated at Mar 05, 2022 at 06:16:05 (UTC)
Goto Top
Zitat von @bacchi:
Um herauszufinden, was sich geändert hat, gehe ich immer noch über die Registrierung, außerdem müsste ich für jeden Laptop die CLSID herausfinden. Kann ich nicht das Ereignisobjekt dafür benutzen, um herauszufinden, was sich geändert hat?
Jepp, dafür hat das Event-Object zwei Instance-Objects eines für den vorherigen Zustand und einen für den aktuellen Zustand. Damit du an die Details kommst nimmst du dann besser die Klasse Win32_NetworkAdapterConfiguration darin bekommst du alle Details zum Adapter
Get-EventSubscriber | Unregister-Event
Register-WmiEvent -Query 'SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA "Win32_NetworkAdapterConfiguration"' -Action {  
    write-host "Alte Einstellungen:" -F Green  
    write-host ($event.SourceEventArgs.NewEvent.PreviousInstance | select  Caption,IPEnabled,DHCPEnabled,IPAddress,DefaultIPGateway,DNSServerSearchOrder | out-string)
    write-host "Aktuelle Einstellungen:" -F Green  
    write-host ($event.SourceEventArgs.NewEvent.TargetInstance | select  Caption,IPEnabled,DHCPEnabled,IPAddress,DefaultIPGateway,DNSServerSearchOrder | out-string)
} | out-null
Member: bacchi
bacchi Mar 07, 2022 at 17:53:23 (UTC)
Goto Top
@1915348599
Ich sehe, du hast dein Skript erneuert. : )

Damit nicht die ganze Zeit ein blaues Fenster herumgeschubst werden muss, habe ich mir heute permanente WMI-Abos angesehen. Das folgende Skript erkennt schon die Änderung an der Konfiguration, aber an dem Log-Eintrag muss ich noch feilen (Zeile 42). Ich habe bisher immer nur testweise die Subnetzmaske verändert, daher soll TargetInstance.IpSubnet ausgegeben werden. Im Log erscheint aber nur <error> stattdessen. Da muss ich noch ein bisschen Doku wälzen.

Das Skript ist an einem Blog-Eintrag von learn-powershell.net (14.08.2013) angelehnt und auf deine WQL-Anfrage angepasst (die grünen Überschriften habe ich auch geklaut).

# Permanentes WMI-Ereignis einrichten, um die Konfigurationsänderungen der
# Ethernet-Schnittstellen zu überwachen und in C:\nicconfig.log zu loggen.

if ($args -and $args -eq '-e') {  
	Write-Host "Entferne permanente WMI-Objekte..." -F Green  
	Get-WMIObject -Namespace root\Subscription `
		-Class __EventFilter -Filter "Name='NicFilter'" `  
	| Remove-WmiObject -Verbose
	Get-WMIObject -Namespace root\Subscription `
		-Class LogFileEventConsumer -Filter "Name='NicConsumer'" `  
	| Remove-WmiObject -Verbose
	Get-WMIObject -Namespace root\Subscription `
		-Class __FilterToConsumerBinding `
		-Filter "__Path LIKE '%NicFilter%'" `  
	| Remove-WmiObject -Verbose
	exit
}

# Allgemeine WMI-Parameter
$wmipar = @{
	Computername = $env:COMPUTERNAME
	ErrorAction = 'Stop'  
	NameSpace = 'root\subscription'  
}

Write-Host "Richte permanente WMI-Objekte ein... (mit -e wieder entfernen)" -F Green  
# Ereignis-Filter einrichten
$wmipar.Class = '__EventFilter'  
$wmipar.Arguments = @{
	Name = 'NicFilter'  
	EventNamespace = 'root\CIMV2'  
	QueryLanguage = 'WQL'  
	Query = "select * from __instanceModificationEvent within 5" +  
            "where targetInstance isa 'win32_NetworkAdapterConfiguration'"  
}
$flterg = Set-WmiInstance @wmipar # Filter-Ergebnis

# Ereignis-Verbraucher einrichten
$wmipar.Class = 'LogFileEventConsumer'  
$wmipar.Arguments = @{
	Name = 'NicConsumer'  
	Text = "$(Get-Date -Format o) %TargetInstance.IpSubnet%"  
	FileName = "C:\nicconf.log"  
}
$konerg = Set-WmiInstance @wmipar # Konsument-Ergebnis


$wmipar.Class = '__FilterToConsumerBinding'  
$wmipar.Arguments = @{
	Filter = $flterg
	Consumer = $konerg
}
$anberg = Set-WmiInstance @wmipar # Anbindungsergebnis
Member: bacchi
bacchi Mar 11, 2022 at 16:48:22 (UTC)
Goto Top
Zeile 42 sollte besser ersetzt werden mit:
Text = "Neue Konfiguration(%TIME_CREATED%):`r`n" +   
        "`tIP=%TargetInstance.IpAddress%`r`n" +   
        "`tNM=%TargetInstance.IpSubnet%`r`n" +  
        "`tGW=%TargetInstance.DefaultIpGateway%"  

Das ist immerhin benutzbar, aber noch nicht ideal. TIME_CREATED erzeugt im Log einen Uint64-Zeitstempel á la "132914898113574000" und ist vom Benutzer nicht als Zeit zu erkennen. Könnte ich das jetzt an Get-Date oder Irgendwas-VonFileTime füttern, wäre ich fertig, aber der Text-Parameter unterstützt keine Skript-Ersetzungen : ( Vermutlich muss ich den Konsumenten auf ActiveScripting ändern und eine Behandlungsroutine schreiben.

Zum Nachschlagen: InstanceModificationEvent (TIME_CREATED), Win32_NetworkAdapterConfiguration (TargetInstance.* ...), WMI String Templates
Member: bacchi
Solution bacchi Apr 14, 2022 at 18:02:03 (UTC)
Goto Top
Ich habe mich endlich an die letzten Schritte machen können. Leider kann ActiveScriptingEventConsumer nur VB- oder JScript ausführen. Mit CommandLineEventConsumer konnte ich bei Powershell bleiben. Hier also das vollständige Skript:

# Permanentes WMI-Ereignis einrichten, um die Konfigurationsänderungen der
# Ethernet-Schnittstellen zu überwachen und zu loggen.

#Requires -RunAsAdministrator

$LOGDATEI = "C:\nicconf.csv"  

if ($args -and $args -eq '-e') {  
	Write-Host "Entferne permanente WMI-Objekte..." -F Green  
	Get-WMIObject -Namespace root\Subscription `
		-Class __EventFilter -Filter "Name='NicFilter'" `  
	| Remove-WmiObject -Verbose
	Get-WMIObject -Namespace root\Subscription `
		-Class CommandLineEventConsumer -Filter "Name='NicConsumer'" `  
	| Remove-WmiObject -Verbose
	Get-WMIObject -Namespace root\Subscription `
		-Class __FilterToConsumerBinding `
		-Filter "__Path LIKE '%NicFilter%'" `  
	| Remove-WmiObject -Verbose
        Write-Host "$LOGDATEI noch sichern oder löschen." -F Green  
	exit
}

# Ggf. Log-Datei mit Kopfzeile anlegen
New-Item $LOGDATEI -ErrorAction SilentlyContinue `
    -Value "Zeitpunkt,IPv4-Adresse,IPv4-Subnetzmaske,IPv4-Standardgateway`r`n"  

# Allgemeine WMI-Parameter
$wmipar = @{
	Computername = $env:COMPUTERNAME
	ErrorAction = 'Stop'  
	NameSpace = 'root\subscription'  
}

Write-Host "Richte permanente WMI-Objekte ein... (mit -e wieder entfernen)" -F Green  
# Ereignis-Filter einrichten
$wmipar.Class = '__EventFilter'  
$wmipar.Arguments = @{
	Name = 'NicFilter'  
	EventNamespace = 'root\CIMV2'  
	QueryLanguage = 'WQL'  
	Query = "select * from __instanceModificationEvent within 5 " +  
            "where targetInstance isa 'win32_NetworkAdapterConfiguration'"  
}
$flterg = Set-WmiInstance @wmipar # Filter-Ergebnis

# Ereignis-Verbraucher einrichten
$wmipar.Class = 'CommandLineEventConsumer'  
$wmipar.Arguments = @{
	Name = 'NicConsumer'  
	CommandLineTemplate = "Powershell -Command `"" +  
            "function f(`$x) {(`$x -replace '[()]', '' -split ',')};" +  
            "(Get-Date -Format u) + ','" +  
            " + (f('%TargetInstance.IpAddress%')) + ','" +  
            " + (f('%TargetInstance.IpSubnet%')) + ','" +  
            " + (f('%TargetInstance.DefaultIpGateway%')) | Add-Content $LOGDATEI`""  
}
$konerg = Set-WmiInstance @wmipar # Konsument-Ergebnis

# Verbraucheranbindung einrichten
$wmipar.Class = '__FilterToConsumerBinding'  
$wmipar.Arguments = @{
	Filter = $flterg
	Consumer = $konerg
}
$anberg = Set-WmiInstance @wmipar # Anbindungsergebnis

Das Skript spuckt jetzt eine für Benutzer einigermaßen intuitiv verständliche CSV-Datei aus. Die große Qual war CommandLineTemplate (Zeilen 50-55), weil in dem Parameter verschiedene Zeichen jeweils mit \ und mit ` maskiert werden mussten. Wenn man eines davon falsch hatte, wanderte leider auch die Fehlermeldung irgendwohin in's Nirvana und man musste erstmal rätseln. Hier hat sich bewährt, sich das erzeugte WMI-Objekt anzusehen mit
Get-WmiObject -Namespace root\Subscription -Class CommandLineEventConsumer
und dann das angezeigte CommandLineTemplate in einer interaktiven Shell nachzubauen, um zumindest einen Fehler zu sehen.

Es war auch nicht ganz so einfach, die gewollten Daten zu bekommen. Alle abgefragten Eigenschaften der Zielinstanz von Win32_NetworkAdapterConfiguration sind ASCII-Darstellungen von Arrays, die ich mit der Hilfsfunktion f zerlege. Schön wäre, wenn man hier einfach %TargetInstance.IpAddress% angeben könnte, aber das hat bei mir zumindest nicht geklappt.

Das ist dann erstmal die endgültige Version. Verbesserungen werden trotzdem gerne entgegengenommen. Hoffentlich hilft es dem einen oder anderen.