spitzending
Goto Top

WinEvt-Logs auf SBS 2008 - System kann die angegebene Datei nicht finden

Guten Tag allerseits. Ich möchte auf einem SBS 2008 die Eventlogs von Windows an einen anderen Ort archivieren. Ich habe eine bestehende Batchdatei von http://www.dostips.com/DtTipsDateTime.php genommen und nach meinen Wünschen modifiziert, Quelltext siehe unten.

Ich durchlaufe den Ordner %windir%\System32\winevt\Logs, zippe alle Dateien älter als sieben Tage an einen anderen Ort und lösche das Original. Das klappt für die meisten *.evtx mit Ausnahme sämtlicher Archive-Security-*.evtx. Für jede dieser Dateien bekomme ich die Meldung "Das System kann die angegebene Datei nicht finden.", d.h. mein Skript kann kein ZIP-Archiv von diesen Protokollen erstellen. Diese Dateien sind sehr wohl vorhanden und zumeist sehr alt, so daß sie nicht mehr geöffnet sein sollten, weil längst mehrere neue Logs danach geschrieben wurden. Dafür spricht auch, daß ich bei anderen Dateien, die noch geöffnet sind, auch eine entsprechende Meldung erhalte: "WARNING: Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.", so z.B. für das PowerShell.evtx. Bei den Archive-Security-*.evtx muß also ein anderer Grund vorliegen, der aber aus der Fehlermeldung nicht hervorgeht.

Die Berechtigungen auf die Dateien habe ich geprüft und nur Gemeinsamkeiten gefunden: selbe Zugriffsgruppen, selbe Rechte (SYSTEM, Administratoren, EventLog jeweils mit Vollzugriff). Alle Dateien haben in ihren Zeitstempeln jeweils das gleiche Datum und die gleiche Uhrzeit (Erstellt, Geändert, Letzter Zugriff). Die relevanten weiteren Dateiattribute (Schreibgeschützt ...) sind auch gleich. Hat jemand einen Tipp für mich? Mit der Hoffnung auf Erleuchtung, was ich tun muß, um auch die Sicherheitslogs mit archivieren zu können, nachfolgend das Skript:

SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

cd /d "%windir%\System32\winevt\Logs"  

call:jdate tnow "%date%"  
for %%F in (*.*) do (
	call:ftime tfile "%%F"  
	set /a diff=tnow-tfile
	if !diff! LEQ 7 (
	echo.%%~nxF ist !diff! <= 7 Tage alt und wird deshalb nicht archiviert.
	) else (
	echo.%%~nxF ist !diff! Tage alt und wird als ZIP-Archiv nach D:\winevt\Logs\ archiviert.
	C:\Programme\7-Zip\7z.exe a -tzip D:\winevt\Logs\%%F.zip %%F
	del %%F
	echo %%F wurde nach "D:\winevt\Logs" archiviert. Das Original wurde geloescht.  
	)
)
echo %date% > D:\winevt\Logs\00-letztes-Archiv.txt
echo Die Archivierung ist abgeschlossen. Das Datum der letzten Archivierung wurde in der Datei "D:\winevt\Logs\00-letztes-Archiv.txt" gespeichert.  
ECHO.&PAUSE&GOTO:EOF


::-----------------------------------------------------------------------------------
::-- Functions start below here
::-----------------------------------------------------------------------------------


:ftime JD filename attr -- returns the file time in julian days
::                      -- JD    [out]    - valref file time in julian days
::                      -- attr  [in,opt] - time field to be used, creation/last-access/last-write, see 'dir /?', i.e. /tc, /ta, /tw, default is /tw  
:$created 20060101 :$changed 20090322 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL
set file=%~2
set attr=%~3
if not defined attr (call:jdate JD "- %~t2"  
) ELSE (for /f %%a in ('"dir %attr% /-c "%file%"|findstr "^^[0-9]""') do call:jdate JD "%%a")  
( ENDLOCAL & REM RETURN VALUES
    IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)  
)
EXIT /b


:jdate JD DateStr -- converts a date string to julian day number with respect to regional date format
::                -- JD      [out,opt] - julian days
::                -- DateStr [in,opt]  - date string, e.g. "03/31/2006" or "Fri 03/31/2006" or "31.3.2006"  
:$reference http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/a0c34d593e782e94/50ed3430b6446af8#50ed3430b6446af8
:$created 20060101 :$changed 20080219
:$source http://www.dostips.com
SETLOCAL
set DateStr=%~2&if "%~2"=="" set DateStr=%date%  
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('"echo.|date"') do (  
    for /f "tokens=1-3 delims=/.- " %%A in ("%DateStr:* =%") do (  
        set %%a=%%A&set %%b=%%B&set %%c=%%C))
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"  
set /a JD=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)  
EXIT /b

Content-Key: 157463

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

Printed on: April 20, 2024 at 04:04 o'clock

Mitglied: 60730
60730 Dec 22, 2010 at 16:09:35 (UTC)
Goto Top
moin,

bitte schreibe deinen Quelltext zwischen <code> und </code> -denn so haben nicht nur meine Augen ein Problem mit dem lesen..

Dann nehme ich diese Vbs, die im "Zielordner" der logs sein sollte.
Das mit Datum beschriftete security.evt solltest du so auch wunderbar zippen und danach in die Tonne treten können.

strComputer = "."         
Set objWMIService = GetObject("winmgmts:" _  
    & "{impersonationLevel=impersonate, (Backup, Security)}!\\" _  
        & strComputer & "\root\cimv2")  
Set colLogFiles = objWMIService.ExecQuery _
    ("Select * from Win32_NTEventLogFile where LogFileName='Security'")  
For Each objLogfile in colLogFiles
     OutputFile = "C:\script\eventlog\" & "Security "  
     OutputFile = OutputFile & Day(Now) & "-" & month(now) & "-" & year(now)  
     OutputFile = OutputFile & ".evt"  
    errBackupLog = objLogFile.BackupEventLog(OutputFile)
    If errBackupLog = 0 Or errBackupLog = 183 Then
         objLogFile.ClearEventLog()
    End If
Next
btw: Eigentlich schreibe ich ja keine kompletten Scripte mehr, aber das lag eh fertig im SchnippselOrdner.
btw²: Eh klar, dass das nur ein Admin machen darf....

Gruß
Member: Spitzending
Spitzending Dec 27, 2010 at 15:57:40 (UTC)
Goto Top
Danke für Dein Skript. Meins hatte ich zuerst in [code], [/code] gesetzt, kein Ergebnis gesehen und die Tags darum wieder entfernt. Künftig also in spitzen Klammern.

Dein Skript verstehe ich noch nicht vollständig. Da ich von VBS keine Ahnung habe, habe ich mir zeilenweise alles herausgesucht, bis ich schlüssige Erklärungen fand. Aus meiner Sicht nimmt Dein Skript zuerst die Rolle eines Backup-Admins an und liest alle Eventlogs, die mit 'Security' beginnen, nacheinander ein und schreibt sie in Dateien nach dem Muster c:\script\eventlog\Security-27-12-2010.evt. Wenn es kein .evtx gibt (Rückgabewert 0) oder die Zieldatei bereits exisitert (Rückgabewert 183), dann wird das entsprechende .evtx gelöscht. Ist das so richtig? Nur was passiert, wenn es mehrere Security-Logs vom gleichen Datum gibt? Dann ist die Zieldatei ja schon vorhanden. Und warum soll das Skript im Zielordner liegen und von dort aufgerufen werden, wenn die Dateien eh nach c:\script\eventlog geschrieben werden?

Ich habe Dein Skript in einem leeren Testordner abgelegt und von dort per Kommandozeile ausgeführt, doch beendet es sich gleich (offenbar ordentlich), so daß keine Dateien im Zielordner landen.

Für meine Lösung fehlen da außerdem noch ein paar Punkte. Deshalb wäre mir eine Lösung basierend auf meinem Skript oben lieber, weil ich dann nicht alles nochmal neu in einer anderen Sprache machen müßte, von der ich bisher keine Ahnung habe. Die ganze Arbeit würde von vorn beginnen. Vielleicht hat jemand einen plausiblen Grund, warum die Security-Logs als einzige nicht geöffnet werden können und wie ich das behebe. Zumindest hatte ich mit Deinem Skript da noch keinen Erfolg.