Ordner und Dateinamen mit dazugehöriger Besitzerinformation auslesen und in csv Datei ausgeben
Hallo,
wie in einem anderen Beitrag von mir Besitzer von Ordnern UND Dateien mit vbs in excel ausgeben schon einmal erwähnt bzw. beschrieben, versuche ich mittels Batch Datei, aus einem Verzeichnis folgende Informationen auszulesen:
Kurz und Bündig: Lokal funktioniert es einwandfrei aber auf Windows Server 2003 nicht...
Bisher lief die "Anwendung" (--> Siehe Code unten) auf meiner lokalen Maschine (win XP) und ist daher etwas in Vergessenheit geraten. Und da dies jetzt wieder aktuell geworden ist, bin ich auf ein weiteres Problem gestoßen:
Derzeit liest die Anwendung nur lokal ein Gesamtes Verzeichnis mit den zusätzlichen Besitzerinformationen aus und gibt die Informationen in einer .csv Liste aus.
Nun wollte ich dieses auf Windows Server (2003 [Englisch]) ausführen und ein Verzeichnis auf dem Server auslesen, aber es wird, im warsten Sinne des Wortes, irgendwas ausgegeben.
Hier der Code
Ziel ist, dass die selben Informationen auch ausgegeben werden, wenn die "Anwendung" auf Win Server 2003 ausgeführt wird. Ich persönlich glaube, dass es an der Englischen Version liegt, weiß jedoch nicht, wie ich dies lösen könnte.
Ich hoffe, dass ich alles soweit verständlich beschrieben habe?! Solltet ihr weitere Infos benötigen, gebt mir einfach bescheid
Freue mich über jeden Lösungsvorschlag,
mfg
Pretznbaer
wie in einem anderen Beitrag von mir Besitzer von Ordnern UND Dateien mit vbs in excel ausgeben schon einmal erwähnt bzw. beschrieben, versuche ich mittels Batch Datei, aus einem Verzeichnis folgende Informationen auszulesen:
- Ordnernamen
- Dateinamen
- dazugehörigen Besitzerinformation
Kurz und Bündig: Lokal funktioniert es einwandfrei aber auf Windows Server 2003 nicht...
Bisher lief die "Anwendung" (--> Siehe Code unten) auf meiner lokalen Maschine (win XP) und ist daher etwas in Vergessenheit geraten. Und da dies jetzt wieder aktuell geworden ist, bin ich auf ein weiteres Problem gestoßen:
Derzeit liest die Anwendung nur lokal ein Gesamtes Verzeichnis mit den zusätzlichen Besitzerinformationen aus und gibt die Informationen in einer .csv Liste aus.
Nun wollte ich dieses auf Windows Server (2003 [Englisch]) ausführen und ein Verzeichnis auf dem Server auslesen, aber es wird, im warsten Sinne des Wortes, irgendwas ausgegeben.
Hier der Code
@echo off & setlocal
set "Ordner=D:\"
set "Liste=D:\%date:~-4% %date:~-7,2% %date:~-10,2% liste.csv"
del "%Liste%" 2>nul
for /r "%Ordner%" %%i in (.) do for /f "tokens=1,2,3,4,*" %%a in ('dir "%%i" /q ^|findstr "^[0-9].*"^|findstr /v ".*DIR.*\."') do echo %%a;%%b;%%c;%%d;%%~fi\%%e;>>"%Liste%"
Ziel ist, dass die selben Informationen auch ausgegeben werden, wenn die "Anwendung" auf Win Server 2003 ausgeführt wird. Ich persönlich glaube, dass es an der Englischen Version liegt, weiß jedoch nicht, wie ich dies lösen könnte.
Ich hoffe, dass ich alles soweit verständlich beschrieben habe?! Solltet ihr weitere Infos benötigen, gebt mir einfach bescheid
Freue mich über jeden Lösungsvorschlag,
mfg
Pretznbaer
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 202205
Url: https://administrator.de/contentid/202205
Ausgedruckt am: 29.11.2024 um 14:11 Uhr
4 Kommentare
Neuester Kommentar
Hallo Pretznbaer,
in Deinem Schnipsel müsste der Suchstring des zweiten
so
lauten, zumindest auf Windows 7.
Es gibt allerdings weiterhin zwei Probleme mit dem Code:
Als Lösung bietet sich VBScript an. Mit einem kleinen Inline-VBScript könnte man die Datumszerlegung so erledigen, dass sie auf allen Sprachversionen von Windows funktioniert und immer das gleiche Ergebnis liefert.
Für die Ermittlung des Besitzers einer Datei/eines Verzeichnisses bei der Erzeugung der CSV-Datei existiert eine sichere aber recht langsame Lösung über WMI.
Wie viele Dateien/Verzeichnisse sind (ungefähr) in dem zu verarbeitenden Verzeichnisbaum?
Gruß
Friemler
in Deinem Schnipsel müsste der Suchstring des zweiten
FINDSTR
-Befehls statt".*DIR.*\."
".*DIR.*\.$"
Es gibt allerdings weiterhin zwei Probleme mit dem Code:
- Falls als Besitzer bei einer Datei/einem Verzeichnis z.B. die Benutzergruppe
Vordefiniert\Administratoren
eingetragen ist, wird dieser Name bei der Darstellung durch denDIR
-Befehl wegen Überlänge abgeschnitten und zusätzlich mit dem Dateinamen verschmolzen, da kein Freizeichen dazwischen geschrieben wird. Dadurch entsteht eine fehlerhafte Zeile in der CSV-Datei. - Die Extraktion der einzelnen Bestandteile des Datums zur Erzeugung des Namens der Ausgabedatei wird bei einem englischen bzw. amerikanischen Windows so nicht funktionieren, da in beiden Lokalisierungen ein anderes Datumsformat benutzt wird, d.h. die Position von Tag, Monat und Jahr in einem englischen/amerikanischen Datumsstring stimmen nicht mit den Positionen in einem deutschen Datumsstring überein.
Als Lösung bietet sich VBScript an. Mit einem kleinen Inline-VBScript könnte man die Datumszerlegung so erledigen, dass sie auf allen Sprachversionen von Windows funktioniert und immer das gleiche Ergebnis liefert.
Für die Ermittlung des Besitzers einer Datei/eines Verzeichnisses bei der Erzeugung der CSV-Datei existiert eine sichere aber recht langsame Lösung über WMI.
Wie viele Dateien/Verzeichnisse sind (ungefähr) in dem zu verarbeitenden Verzeichnisbaum?
Gruß
Friemler
Hallo Pretznbaer,
beim Durchforsten meiner Festplatte mit Deinem Batchschnipsel sind Dateien aufgetaucht, deren Besitzer nicht ein Benutzer sondern z.B. die Benutzergruppe Administratoren ist, deren vollständiger Name auf einem deutschen Windows
Wenn es nur 150 Dateien sind, spielt die Ausführungsgeschwindigkeit keine große Rolle, da sollte die robuste WMI-Lösung genügen.
Aber erstmal der Code für das Batchfile, von dem aus das VBScript aufgerufen wird, das die eigentliche Arbeit erledigt:
In Zeile 17 des Scripts wird der Name und Pfad des VBScripts gesetzt, das die Daten der Dateien und Verzeichnisse im zu verarbeitenden Verzeichnisbaum ermittelt. Hier wird der Name
Um komplett zu sein: Hier noch die etwas unsichere aber viel schnellere Alternative über das
Gruß
Friemler
beim Durchforsten meiner Festplatte mit Deinem Batchschnipsel sind Dateien aufgetaucht, deren Besitzer nicht ein Benutzer sondern z.B. die Benutzergruppe Administratoren ist, deren vollständiger Name auf einem deutschen Windows
Vordefiniert\Administratoren
lautet. Da DIR /Q die Daten zu einer Datei in einer Tabellenstruktur mit fester Spaltenbreite anzeigt, blieb davon nur Vordefiniert\Administra
übrig. Direkt neben der Spalte für den Besitzer wird ja der Dateiname angezeigt, in diesem Fall aber ohne separierendes Leerzeichen. Die FOR-Schleife hat als Besitzer somit Vordefiniert\AdministraXXXXXXXX
ermittelt (XXXXX steht für den Teil des Dateinamens bis zum ersten Freizeichen). => Die CSV-Datei enthielt einen falschen Eintrag.Wenn es nur 150 Dateien sind, spielt die Ausführungsgeschwindigkeit keine große Rolle, da sollte die robuste WMI-Lösung genügen.
Aber erstmal der Code für das Batchfile, von dem aus das VBScript aufgerufen wird, das die eigentliche Arbeit erledigt:
@echo off & setlocal
::Das Verzeichnis, in dem das Script gespeichert ist, zum aktuellen Verzeichnis machen
pushd "%~dp0"
::Aktuelles Datum bestimmen und in die Variable DateStamp schreiben
call :GetDate DateStamp
::Basisverzeichnis
set "Ordner=D:\"
::Zieldatei
set "Liste=D:\%DateStamp% Liste.csv"
::Pfad+Name des VBScripts, das die Datei- und Verzeichnisdaten ermittelt
set "VBSGetTreeInfo=GetTreeInfo.vbs"
::Evtl. bereits existierende Zieldatei löschen
del "%Liste%" 2>NUL
::VBScript ausführen, dabei das Basisverzeichnis als Parameter übergeben
::Die Ausgabe des VBScripts in die Zieldatei umleiten
cscript /nologo "%VBSGetTreeInfo%" "%Ordner%" > "%Liste%"
::Das Verzeichnis, das beim Scriptstart das aktuelle Verzeichnis war,
::wieder zum aktuellen Verzeichnis machen
popd
::Script Ende
exit /b
::Unterprogramm, das mit Hilfe eines temporären VBScripts
::das aktuelle Datum bestimmt und im Format DD-MM-YYYY zurückgibt
:GetDate
::Pfad für temporäres Script
set "VBSGetDate=%TEMP%\GetDate.vbs"
::Temporäres VBScript schreiben
> "%VBSGetDate%" echo dtToday = Date()
>>"%VBSGetDate%" echo WScript.Echo Year(dtToday) ^& "-" ^& Right("0" ^& Month(dtToday), 2) ^& "-" ^& Right("0" ^& Day(dtToday), 2)
::Temporäres VBScript ausführen und das Ergebnis in der Variablen speichern,
::deren Name als 1. Parameter übergeben wurde
for /f "delims=" %%d in ('cscript /nologo "%VBSGetDate%"') do (
set "%~1=%%d"
)
::Temporäres VBScript löschen
del "%VBSGetDate%"
::Rücksprung
exit /b
In Zeile 17 des Scripts wird der Name und Pfad des VBScripts gesetzt, das die Daten der Dateien und Verzeichnisse im zu verarbeitenden Verzeichnisbaum ermittelt. Hier wird der Name
GetTreeInfo.vbs
verwendet. Das folgende Script muss unter diesem Namen gespeichert werden:Option Explicit
Const typeFolder = 0
Const typeFile = 1
Dim objFSO, objWMIService, intRetVal
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\root\cimv2")
If WScript.Arguments.Count > 0 Then
If objFSO.FolderExists(WScript.Arguments(0)) Then
TraverseFolderTree objFSO.GetFolder(WScript.Arguments(0))
intRetVal = 0
Else
WScript.StdErr.WriteLine "Fehler: Verzeichnis wurde nicht gefunden."
intRetVal = 2
End If
Else
WScript.StdErr.WriteLine "Fehler: Bitte geben Sie ein Verzeichnis an."
intRetVal = 1
End If
WScript.Quit intRetVal
Sub TraverseFolderTree(objFolder)
Dim colSubFolders, objSubFolder, colFiles, objFile
Set colSubFolders = objFolder.SubFolders
Set colFiles = objFolder.Files
For Each objSubFolder In colSubFolders
WScript.StdOut.WriteLine GetItemInfo(typeFolder, objSubFolder)
Next
For Each objFile In colFiles
WScript.StdOut.WriteLine GetItemInfo(typeFile, objFile)
Next
For Each objSubFolder In colSubFolders
TraverseFolderTree objSubFolder
Next
End Sub
Function GetItemInfo(intType, objItem)
Dim arrItemInfo(4), dtTimeStamp
dtTimeStamp = objItem.DateLastModified
arrItemInfo(0) = Right("0" & Day(dtTimeStamp), 2) & "." & Right("0" & Month(dtTimeStamp), 2) & "." & Year(dtTimeStamp)
arrItemInfo(1) = Right("0" & Hour(dtTimeStamp), 2) & ":" & Right("0" & Minute(dtTimeStamp), 2)
Select Case intType
Case typeFolder arrItemInfo(2) = "<DIR>"
Case typeFile arrItemInfo(2) = objItem.Size
End Select
arrItemInfo(3) = GetOwner(objItem.Path)
arrItemInfo(4) = objItem.Path
GetItemInfo = Join(arrItemInfo, ";")
End Function
Function GetOwner(strItemName)
Dim objFileSecuritySettings, objSecurityDescriptor
strItemName = Replace(strItemName, "\", "\\")
Set objFileSecuritySettings = objWMIService.Get("Win32_LogicalFileSecuritySetting=""" & strItemName & """")
objFileSecuritySettings.GetSecurityDescriptor objSecurityDescriptor
GetOwner = objSecurityDescriptor.Owner.Domain & "\" & objSecurityDescriptor.Owner.Name
End Function
Um komplett zu sein: Hier noch die etwas unsichere aber viel schnellere Alternative über das
Shell
COM-Objekt. Diese Version berücksichtigt keine versteckten Dateien. Außerdem muss verhindert werden, dass ZIP
- oder andere Archive als Verzeichnisse angesehen werden, deshalb die etwas aufwendigen Abfragen in den Zeilen 33, 39 und 45.Option Explicit
Const typeFolder = 0
Const typeFile = 1
Dim objFSO, objShell, intRetVal
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
If WScript.Arguments.Count > 0 Then
If objFSO.FolderExists(WScript.Arguments(0)) Then
TraverseFolderTree objShell.NameSpace(WScript.Arguments(0))
intRetVal = 0
Else
WScript.StdErr.WriteLine "Fehler: Verzeichnis wurde nicht gefunden."
intRetVal = 2
End If
Else
WScript.StdErr.WriteLine "Fehler: Bitte geben Sie ein Verzeichnis an."
intRetVal = 1
End If
WScript.Quit intRetVal
Sub TraverseFolderTree(objFolder)
Dim objItem
For Each objItem In objFolder.Items
If objItem.IsFolder And objItem.IsFileSystem And (objItem.Size = 0) Then
WScript.StdOut.WriteLine GetItemInfo(typeFolder, objItem)
End If
Next
For Each objItem In objFolder.Items
If ((Not objItem.IsFolder) And objItem.IsFileSystem) Or (objItem.IsFolder And objItem.IsFileSystem And (objItem.Size <> 0)) Then
WScript.StdOut.WriteLine GetItemInfo(typeFile, objItem)
End If
Next
For Each objItem In objFolder.Items
If objItem.IsFolder And objItem.IsFileSystem And (objItem.Size = 0) Then
TraverseFolderTree objItem.GetFolder
End If
Next
End Sub
Function GetItemInfo(intType, objItem)
Dim arrItemInfos(4), dtTimeStamp
dtTimeStamp = objItem.ModifyDate
arrItemInfos(0) = Right("0" & Day(dtTimeStamp), 2) & "." & Right("0" & Month(dtTimeStamp), 2) & "." & Year(dtTimeStamp)
arrItemInfos(1) = Right("0" & Hour(dtTimeStamp), 2) & ":" & Right("0" & Minute(dtTimeStamp), 2)
Select Case intType
Case typeFolder arrItemInfos(2) = "<DIR>"
Case typeFile arrItemInfos(2) = objItem.Size
End Select
arrItemInfos(3) = objItem.ExtendedProperty("Owner")
arrItemInfos(4) = objItem.Path
GetItemInfo = Join(arrItemInfos, ";")
End Function
Gruß
Friemler