VBS Script zum kopieren mehrerer Dateien die in einem TXT File gelistet sind
Hallo zusammen,
ich habe ein kleines VBScript erstellt, welches mir von allen unseren Servern bzw. Shares eine Auswertung erstellt wo Dateien eines bestimmten Filetyps liegen.
habe nun ein Textfile mit ca. 50.000 Einträgen
Alle Dateien die in diesem File gelistet sind
\\Servername\Share\Ordner\Unterordner\.....\Dateityp.egal
\\Servername\Share\Ordner\Unterordner2\......\Datei.egal
usw....
Jetzt sollte ich folgende Schritte vornehmen: (per VBS Script)
Script A
Alle Dateien aus dem Txt File vom Quellpfad an ein Ziel kopieren.
-> Erzeugung log File bei den Files, die nicht kopiert / gefunden wurden (weil z.B. der User das File zwischenzeitlich umbenannt, gelöscht, ... hat)
(Manuelle Nacharbeit der Files aus dem LogFile)
Script B
Alle Dateien aus dem Txt File löschen
Lässt sich das realisieren?
Vielen Dank
Grüße
Marcel
ich habe ein kleines VBScript erstellt, welches mir von allen unseren Servern bzw. Shares eine Auswertung erstellt wo Dateien eines bestimmten Filetyps liegen.
habe nun ein Textfile mit ca. 50.000 Einträgen
Alle Dateien die in diesem File gelistet sind
\\Servername\Share\Ordner\Unterordner\.....\Dateityp.egal
\\Servername\Share\Ordner\Unterordner2\......\Datei.egal
usw....
Jetzt sollte ich folgende Schritte vornehmen: (per VBS Script)
Script A
Alle Dateien aus dem Txt File vom Quellpfad an ein Ziel kopieren.
-> Erzeugung log File bei den Files, die nicht kopiert / gefunden wurden (weil z.B. der User das File zwischenzeitlich umbenannt, gelöscht, ... hat)
(Manuelle Nacharbeit der Files aus dem LogFile)
Script B
Alle Dateien aus dem Txt File löschen
Lässt sich das realisieren?
Vielen Dank
Grüße
Marcel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 162359
Url: https://administrator.de/forum/vbs-script-zum-kopieren-mehrerer-dateien-die-in-einem-txt-file-gelistet-sind-162359.html
Ausgedruckt am: 09.04.2025 um 04:04 Uhr
19 Kommentare
Neuester Kommentar
Hi,
ich würde es persönlich mit VB.NET realisieren, das Express ist ja kostenlos.
Da hast du einen Debugger und kannst programmieren.
Und so unterschiedlich ist der Code auch nicht.
Dazu kommt noch du hast schon fertige Dateireader etc.pp. auch das Kopieren läßt sich einfacher schreiben.
Ich erzeuge dann immer Konsolenanwendungen mit Parametern, die ich dann im Taskmanager starten kann.
Gruß Alex
ich würde es persönlich mit VB.NET realisieren, das Express ist ja kostenlos.
Da hast du einen Debugger und kannst programmieren.
Und so unterschiedlich ist der Code auch nicht.
Dazu kommt noch du hast schon fertige Dateireader etc.pp. auch das Kopieren läßt sich einfacher schreiben.
Ich erzeuge dann immer Konsolenanwendungen mit Parametern, die ich dann im Taskmanager starten kann.
Gruß Alex
Moin rotlux,
ich will dir da nix Fertiges zusammenschrubbeln, weil ich gar nicht das Gefühl habe, du bekommst es nicht alleine hin.
Aber als Hinweis:
Du deklarierst zwar in einer der ersten Zeilen dein FileSystemObject fso,
weil du das ja auch für den ganzen Quatsch nur ein einziges mal brauchst.
Das finde ich gut.
Allerdings machst du dann doch jedes gatesverdammte Mal in der aufgerufenen DeinFIleCopy()-Unterroutine
Was in etwa so ökologisch sinnvoll ist wie die FDP.
Da würde ich noch einen Moment drüber nachdenken an deiner Stelle.
Also nich' jezz' über die FDP, mein ich.
Grüße
Biber
ich will dir da nix Fertiges zusammenschrubbeln, weil ich gar nicht das Gefühl habe, du bekommst es nicht alleine hin.
Aber als Hinweis:
Du deklarierst zwar in einer der ersten Zeilen dein FileSystemObject fso,
weil du das ja auch für den ganzen Quatsch nur ein einziges mal brauchst.
Das finde ich gut.
Allerdings machst du dann doch jedes gatesverdammte Mal in der aufgerufenen DeinFIleCopy()-Unterroutine
- ein CreateObject(FileSystemObject )
- ein DestroyObject(FileSystemObject) bzw. set fso = nottingham
Was in etwa so ökologisch sinnvoll ist wie die FDP.
Da würde ich noch einen Moment drüber nachdenken an deiner Stelle.
Also nich' jezz' über die FDP, mein ich.
Grüße
Biber

Hallo rotlux!
Ja, was möchtest Du den löschen und was hast Du bezüglich Biber's Anmerkungen nun alles geändert?
Gruß Dieter
Ja, was möchtest Du den löschen und was hast Du bezüglich Biber's Anmerkungen nun alles geändert?
Gruß Dieter
Moin didi1954,
das müssten doch nach der obigen Beschreibung alle Dateien sein,
Oder darf er für dies VBS-Geraffel nicht vorher mit FindStr eine neue LogDatei C = "ChruppWech.log" erzeugen?
Grüße
Biber
das müssten doch nach der obigen Beschreibung alle Dateien sein,
- die in der LogDatei A = "AllezuKopierenden.log" stehen
- und die NICHT in der ggf. manuelle nachbearbeiteten LogDatei B = "Broblemfälle.log"
Oder darf er für dies VBS-Geraffel nicht vorher mit FindStr eine neue LogDatei C = "ChruppWech.log" erzeugen?
Grüße
Biber

Hallo Biber!
Tja, habe ich wohl irgendwie ein Verständnisproblem
Sollens jetzt die erfolgreich kopierten Dateien in Quelle sein? Wenn ja, dann wäre ja ein Move möglich oder
sollens die erfolgreich kopierten Dateipfade in der ZuKopierenDatei sein? Oder die jetzt in der LogFile stehen?
Wie auch immer, dann wäre es doch wesentlich einfacher, die Datei innerhalb des Kopiervorgangs (FileExists True/False) einfach neu zu schreiben?
Gruß Dieter
Tja, habe ich wohl irgendwie ein Verständnisproblem
Sollens jetzt die erfolgreich kopierten Dateien in Quelle sein? Wenn ja, dann wäre ja ein Move möglich oder
sollens die erfolgreich kopierten Dateipfade in der ZuKopierenDatei sein? Oder die jetzt in der LogFile stehen?
Wie auch immer, dann wäre es doch wesentlich einfacher, die Datei innerhalb des Kopiervorgangs (FileExists True/False) einfach neu zu schreiben?
Gruß Dieter

Hallo rotlux!
Erstmal zur Information:
Wenn Du im Haupt-Code Dim-Variablen deklarierst, dann behalten diese im gesamten Skript ihre Gültigkeit, sofern in Sub's oder Functionen nicht der gleiche Variablen-Name nocheinmal per Dim-Anweisung verwendet wird. Biber hat Dir ja schon zu erklären versucht, dass es vollkommen unnötig ist, ein Object (Fso,Shell...) bei jedem Aufruf erneut einer Variablen zuzuweisen. Einmal im Haupt-Code reicht völlig aus.
Hier mal ein Beispiel, wie es funktionieren könnte/sollte (Konstanten entsprechen anpassen):
Zum Ablauf:
Die Datei "ToCopy.txt" wird zu Begin auf einen Schlag in ein Array eingelesen und anschließend überschrieben. D.h. am Ende beinhaltet diese Datei nur noch Pfade, die auch existieren. In der Log-Datei werden zum einen, die nicht existierenden Pfade gelistet und zum anderen Pfade von Dateien, die nicht kopiert werden konnten (Run-Exit-Fehler).
Desweiteren habe ich mal 2 Copy-Subs verwendet/getestet, einmal mit XCopy und einmal mit RoboCopy. Da ja jede Datei einzeln kopiert wird, sollte XCopy eigentlich ausreichen, aber die Entscheidung überlasse ich natürlich Dir.
Von der Datei ToCopy solltest Du vor dem Testen erst noch eine Sicherungskopie anlegen.
Gruß Dieter
[edit] Code geändert [/edit]
Erstmal zur Information:
Wenn Du im Haupt-Code Dim-Variablen deklarierst, dann behalten diese im gesamten Skript ihre Gültigkeit, sofern in Sub's oder Functionen nicht der gleiche Variablen-Name nocheinmal per Dim-Anweisung verwendet wird. Biber hat Dir ja schon zu erklären versucht, dass es vollkommen unnötig ist, ein Object (Fso,Shell...) bei jedem Aufruf erneut einer Variablen zuzuweisen. Einmal im Haupt-Code reicht völlig aus.
Hier mal ein Beispiel, wie es funktionieren könnte/sollte (Konstanten entsprechen anpassen):
Option Explicit
Const strLogPath = "C:\temp\vbtest\test\logfile.txt"
Const strTextPath = "C:\temp\vbtest\test\tocopy.txt"
Const strDestPath = "C:\temp\vbtest\test\ziel"
Dim objFso, objShell, objLogFile, objTextFile, arrFileList, strFile
Set objShell = CreateObject("WScript.Shell")
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFso.CreateTextFile(strLogPath)
Set objTextFile = objFso.OpenTextFile(strTextPath)
'Alle Textzeilen aus ToCopy-File in Array einlesen
arrFileList = Split(objTextFile.ReadAll, vbCrLf)
'ToCopy-File neu erstellen
Set objTextFile = objFso.CreateTextFile(strTextPath)
'Erstellt am in Log-File schreiben
objLogFile.WriteLine "Erstellt am " & Now & vbCrLf
'Dateipfade einlesen/auswerten/kopieren
For Each strFile In arrFileList
If strFile <> "" Then 'Test Leerzeile
If objFso.FileExists(strFile) Then 'Test ob Datei existiert
objTextFile.WriteLine strFile
Call CopyFile1(strFile)
Else
objLogFile.WriteLine "Datei nicht gefunden:" & vbCrLf & vbTab & strFile
End If
End If
Next
objTextFile.Close: objLogFile.Close
Sub CopyFile1(ByRef strSourceFile)
Dim strDestFolder, strCmd, intPos
'Position des '\' im Quell-Ordnerpfad in Abhängigkeit von 'X:\' oder '\\' festlegen
If Mid(strSourceFile, 2, 1) = ":" Then intPos = 3 Else intPos = 2
'Ziel-Ordnerpfad fetlegen
strDestFolder = objFso.GetParentFolderName(strDestPath & Mid(strSourceFile, intPos)) & "\"
'Kopierbefehl zusammenstellen
strCmd = "xcopy """ & strSourceFile & """ """ & strDestFolder & """"
'Kopierbefehl ohne Dos-Fenster absetzen und auf Exit warten
If objShell.Run(strCmd, 0, True) <> 0 Then 'Exit <> 0 Copy-Fehler
objLogFile.WriteLine "Datei konnte nicht kopiert werden:" & vbCrLf & vbTab & strSourceFile
End If
End Sub
Sub CopyFile2(ByRef strSourceFile)
Dim strSrcFolder, strDstFolder, strSrcFile, strCmd, intPos
'Position des '\' im Quell-Ordnerpfad in Abhängigkeit von 'X:\' oder '\\' festlegen
If Mid(strSourceFile, 2, 1) = ":" Then intPos = 3 Else intPos = 2
'Quell- und Ziel-Parameter fetlegen
strSrcFolder = objFso.GetParentFolderName(strSourceFile)
strDstFolder = objFso.GetParentFolderName(strDestPath & Mid(strSourceFile, intPos))
strSrcFile = objFso.GetFileName(strSourceFile)
strCmd = "robocopy """ & strSrcFolder & """ """ & strDstFolder & """ """ & strSrcFile & """"
If objShell.Run(strCmd, 0, True) <> 1 Then 'Exit <> 1 Copy-Fehler
objLogFile.WriteLine "Datei konnte nicht kopiert werden:" & vbCrLf & vbTab & strSourceFile
End If
End Sub
Zum Ablauf:
Die Datei "ToCopy.txt" wird zu Begin auf einen Schlag in ein Array eingelesen und anschließend überschrieben. D.h. am Ende beinhaltet diese Datei nur noch Pfade, die auch existieren. In der Log-Datei werden zum einen, die nicht existierenden Pfade gelistet und zum anderen Pfade von Dateien, die nicht kopiert werden konnten (Run-Exit-Fehler).
Desweiteren habe ich mal 2 Copy-Subs verwendet/getestet, einmal mit XCopy und einmal mit RoboCopy. Da ja jede Datei einzeln kopiert wird, sollte XCopy eigentlich ausreichen, aber die Entscheidung überlasse ich natürlich Dir.
Von der Datei ToCopy solltest Du vor dem Testen erst noch eine Sicherungskopie anlegen.
Gruß Dieter
[edit] Code geändert [/edit]
Moin rotlux,
auch von mir noch eine Ergänzung.
Ganz besonders das FileSystemObject mit seinen vielen, vielen tonnenweise dokumentierten Baukasten-Methoden,
die dann auch nur das altbekannte COPY/DEL/MOVE/MD/RD mit anderen Vokabeln ausdrücken
-> diese Spielwiese ist allerbest zum pflegeleichten Einstieg ins VBSkripting.
Sowas wie CERN früher für Hacker war oder die Jugendfeuerwehr für kleine Machos.
Und nachdem dir ja didi1954 schon ein paar Steinchen, so ca. 98 von 100, aus dem Weg geräumt hat
-> versuch dich doch mal daran, diese merkwürdig draufgepappt anmutende "XCopy"- oder gar "RoboCopy"-Krücke mit den FSO-Methoden hinzubekommen.
Denn a) das schaffst du das b) sieht es mit "RoboCopy"-Aufruf definitiv aus wie gewollt und nicht getraut und c) steht immer im Notfall Hilfe bereit in diesem Forum.
Grüße
Biber
auch von mir noch eine Ergänzung.
Ganz besonders das FileSystemObject mit seinen vielen, vielen tonnenweise dokumentierten Baukasten-Methoden,
die dann auch nur das altbekannte COPY/DEL/MOVE/MD/RD mit anderen Vokabeln ausdrücken
-> diese Spielwiese ist allerbest zum pflegeleichten Einstieg ins VBSkripting.
Sowas wie CERN früher für Hacker war oder die Jugendfeuerwehr für kleine Machos.
Und nachdem dir ja didi1954 schon ein paar Steinchen, so ca. 98 von 100, aus dem Weg geräumt hat
-> versuch dich doch mal daran, diese merkwürdig draufgepappt anmutende "XCopy"- oder gar "RoboCopy"-Krücke mit den FSO-Methoden hinzubekommen.
Denn a) das schaffst du das b) sieht es mit "RoboCopy"-Aufruf definitiv aus wie gewollt und nicht getraut und c) steht immer im Notfall Hilfe bereit in diesem Forum.
Grüße
Biber

Hallo rotlux!
Von Deinem Beispiel ausgehend für Quelle:
und Ziel:
sollte ja aus dem Quell-Pfad nur der Teil ab \User\... übernommen werden.
Von daher bin ich davon ausgegangen, das alle Quell-Pfade einen Bezugs-Ordner 'share' enthalten. Es muss ja einen Bezugspunkt geben, woher soll man sonst wissen, ab welchem Ordner in Quelle der restliche Pfad nach Ziel übernommen werden soll?
Wenn also nicht alle Pfade den Bezugs-Ordner 'share' enthalten, dann kann man so machen, dass erst der Teil nach einer konstanten Anzahl von '\'-Zeichen (z.B. ab dem 4. '\') übernommen werden soll, wobei dann allerdings festgelegt werden muss, ob alle Pfade nun mit 'X:\..\..' oder mit '\\..\..' beginnen?
Gruß Dieter
Von Deinem Beispiel ausgehend für Quelle:
\\server1\share\user1\unterordner\meinetolledatei.doc |
\\server1\share\user2\privat\meinetolledatei.doc |
\\zielpfad\user1\unterordner\meinetolledatei.doc |
\\zielpfad\user2\privat\meinetolledatei.doc |
Von daher bin ich davon ausgegangen, das alle Quell-Pfade einen Bezugs-Ordner 'share' enthalten. Es muss ja einen Bezugspunkt geben, woher soll man sonst wissen, ab welchem Ordner in Quelle der restliche Pfad nach Ziel übernommen werden soll?
Wenn also nicht alle Pfade den Bezugs-Ordner 'share' enthalten, dann kann man so machen, dass erst der Teil nach einer konstanten Anzahl von '\'-Zeichen (z.B. ab dem 4. '\') übernommen werden soll, wobei dann allerdings festgelegt werden muss, ob alle Pfade nun mit 'X:\..\..' oder mit '\\..\..' beginnen?
Gruß Dieter

Hallo rotlux!
eigentlich könnte das Script als Ziel immer eine Konstante haben z.B.:
Ziel hat bereits ne Konstante (siehe Const in Codezeile 5) und stellt ja auch kein Problem da
Und von Quelle jetzt doch den kompletten Pfad
Letzten Code oben geändert. Der Quell-Pfad darf der Einfachheit halber mit 'X:\' oder '\\' beginnen. So ist es auch einfacher zu testen
Gruß Dieter
eigentlich könnte das Script als Ziel immer eine Konstante haben z.B.:
Const strDestPath = "C:\temp\vbtest\test\ziel" |
Und von Quelle jetzt doch den kompletten Pfad
Letzten Code oben geändert. Der Quell-Pfad darf der Einfachheit halber mit 'X:\' oder '\\' beginnen. So ist es auch einfacher zu testen
Gruß Dieter

Hallo rotlux!
Und ergänzend zu bastla's Kommentar - wie Biber sagen würde
- den WG-mortadellafarbenen Gelöst-Haken nicht vergessen!
Gruß Dieter
Und ergänzend zu bastla's Kommentar - wie Biber sagen würde
Gruß Dieter