killtec
Goto Top

PS Script - WinSCP und Datei kopieren

Hallo,
ich möchte gerne ein CMD Script umschreiben in Powershell und erweitern.

Mein CMD hat ein WinSCP aufruf gemacht, das lief bisher auch Fehlerfrei.
Nun möchte ich das umbauen in Powershell
CMD-Aufruf:
SET dati=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%-%TIME:~0,2%.%TIME:~3,2%
"C:\Program Files (x86)\WinSCP\winscp.exe" -filezilla Download /script="F:\Downloadscripte\download.txt" /log="F:\Downloadscripte\logs\%dati%.log  

Powershellaufruf:

$dat=(get-date -format "yyyyMMdd-hh.mm")  
$wscp_par="-filezilla ","Download /script=","F:\Downloadscripte\download.txt ","/log=F:\Downloadscripte\logs\",$dat,".log"  
& 'C:\Program Files (x86)\WinSCP\WinSCP.exe' $wscp_par  

Hier habe ich das Problem, dass die $dat nicht korrekt ausgegeben wird. winscp meldet den Fehler, dass keine Log in \logs geschrieben werden kann (logisch wenn kein weiterer Dateiname da ist).

Wenn das winscp durch ist, würde ich gerne Dateien von einem Verzeichnis ins andere kopieren, die nicht älter als einen Tag sind.
WinSCP macht einen kompletten FTP Verzeichnis Sync. Den FTP Inhalt kann ich nicht beeinflussen. Er beinhaltet leider auch ältere Dateien.

gci "F:\DLT\download\Firma\massdata" | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-2)} | % { copy-item $_.FullName "F:\DLT\automatisch\Firma\massdata"}  
gci "F:\DLT\download\Firma\drivercards" | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-2)} | % { copy-item $_.FullName "F:\DLT\automatisch\Firma\drivercards"}  
das funktioniert auch ohne Probleme.

Nun zu den Fragen:
1. Wie komme ich aus dem Fehler beim WinSCP raus dass er mir die log richtig schreibt?
2. Gibt es beim kopieren der neuen Dateien in den Ordnern einen schöneren Weg? Bei dem Punkt Firma habe ich 5 stück und jeweils zwei Unterordner. (Ich fürchte es gibt dafür einen einzeiler... :D )

Hoffe ich habe mich verständlich ausgedrückt.

Gruß

Content-ID: 6286810456

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

Ausgedruckt am: 23.11.2024 um 10:11 Uhr

Crusher79
Crusher79 09.03.2023 aktualisiert um 11:48:58 Uhr
Goto Top
Hallo, so auf die schnelle die Frage: Warum gehst du über Command-Line und bindest nicht die DLL ein?

https://winscp.net/eng/docs/library_powershell

Da bekommt man die Ergebnisse auch gleich im Objekt mit

foreach ($transfer in $transferResult.Transfers)

Und kann die dann selber an eine Log anhängen etc.


Wegen einfach Abgleich: https://winscp.net/eng/docs/library_session_synchronizedirectories

Du könntest auch hier einfach die Sync Mehtoden anwenden. Gibt auch da ein PS Beispiel. Wäre das nicht einfacher?

PS:
https://winscp.net/forum/viewtopic.php?t=24945

Da wird der Exclude nochmals erklärt. Mit Filemask kannst du Ordner ausschließen.

Beim Sync heisst es ja: Transfer options. Defaults to null, what is equivalent to new TransferOptions().

Du kannst also die Klasse der Transferoptionen einfach mit reinnehmen und die Sache rund machen.

https://winscp.net/eng/docs/library_transferoptions
killtec
killtec 09.03.2023 um 12:27:45 Uhr
Goto Top
Ich erkläre es mal anders:
Wir bekommen auf einem FTP-Server Daten zur Verfügung gestellt. Dieses FTP Verzeichnis synchronisiere ich mit einem lokalen Verzeichnis via winscp / Filezilla.
In dem Script des Sycns steht nur
synchronize local F:\DLT\download\ /
exit
als FTP Befehl.

Ich muss dazu sagen, ich habe mit FTP / WinSCP gescriptet noch nicht viel außer diesem gemacht.

Der Vorgang ist der, das das FTP Verzeichnis synchronisiert wird und dann über ein weiteres Programm automatisch in ein Portal geladen wird.
Dieses Programm verschiebt dann erfolgreich hoch geladene Daten in ein extra Verzeichnis. Der FTP Sync kopiert aber dann somit alles neu wieder mit. Daher der Umweg des Downloads in das 1. Verzeichnis. Kopieren nur das, was vom Vortag ist damit der auto uploader nur die aktuellsten Daten hat. Sonst blähen sich die Verzeichnisse ohne Ende auf.
Das Script läuft dann 1-2 mal am Tag.

Also der WinSCP ruft ja dann ein Filezilla Profil auf.
Bin auch offen dafür, wenn man das ganze verschlanken kann.

Dachte halt Schritt 1 alles vom Server laden
Schritt 2 dann nur das neue in ein separates Verzeichnis kopieren.

Gruß
killtec
killtec 09.03.2023 um 12:36:47 Uhr
Goto Top
Nachtrag: Noch schöner wäre es, wenn erfolgreich übertragene Dateien vom FTP gelöscht werden könnten.
Aber hier hab ich leider keinen Plan wie man das automatisieren kann.
Crusher79
Crusher79 09.03.2023 um 12:44:28 Uhr
Goto Top
Naja Logik kann dann helfen! face-wink

Durch den remote Hotfolder und das verschieben verlieren wir den Focus. Sync würde dann alles nochmal kopieren. Man kann die übertragenen Dateien an eine CSV anhängen und die zum Ausschließen nehmen. Oder aber man verschiebt die Dateien lokal ebenfalls - anhand des remote Backup Ordners - und hat die so dann außen vor.


Zitat von @killtec:

Nachtrag: Noch schöner wäre es, wenn erfolgreich übertragene Dateien vom FTP gelöscht werden könnten.
Aber hier hab ich leider keinen Plan wie man das automatisieren kann.

Das verstehe ich gerade nicht ganz. Du meinst die im Backup Ordner oder welche? Dachte die übertragenen müssen liegen bleiben, damit der Import über das Programm funktioiert. Dan weglöschen.... Die liegen dann ja eh nich mehr im primären Transfer-Ziel.

https://winscp.net/eng/docs/library_example_delete_after_successful_down ...

Erfolgskontrolle auch hier ganz einfach. Ist nur die andere Richtung. Alles mit Success wird gelöscht. Aber erklär nochmal, was gelöscht werden soll.

Transfer
lokal -> FTP
löschern aller ERFOLGREICH übertragenen Dateien LOKAL

Meinst du das so?
killtec
killtec 09.03.2023 aktualisiert um 13:24:04 Uhr
Goto Top
Ähm, versuche es mal anders da zu stellen.

1. Dateien liegen auf einem FTP-Server vor (wird von extern befüllt, oft bleiben alte Dateien da)
2. WinSCP synct Server mit lokalem Verzeichnis (Verzeichnis 1) Download vom FTP
3. Script kopiert neue Dateien vom Vortag in separates Verzeichnis (Verzeichnis 2)
4. Auto Uploader lädt Daten in Portal und verschiebt in Unterordner bei Fehler / Erfolg. (Verzeichnis2\Erfolg oder Verzeichnis2\Fehler)

Ähnlich als Bild:
vorgang

Kann es schlecht ausdrücken, hoffe aber das es jetzt klar ist. Im Kern geht es um Faherkarten und Fahrtenschreiber.
Wir bekommen die Daten bereit gestellt (OTA Auslesen) und können uns die Daten per FTP laden. Diese landen dann per Auto Uploader in einem Portal.
Portal und FTP sind Vorgegeben.

Gruß
Crusher79
Crusher79 09.03.2023 um 13:57:03 Uhr
Goto Top
Jo stimmt, dachte wir reden nur von lokal und FTP. Das die App auf den FTP Ordner zugreift. So wird es deutlicher. Ich war davon ausgegangen, dass der Hotfolder für die App auch auf dem FTP liegt face-wink Darum etwas komisch.

Und welche Datein auf den FTP sollen gelöscht werden? Nur die hochgeladenen? Oder gar alle? Da steig ich noch nicht ganz hinter!
killtec
killtec 09.03.2023 um 14:06:41 Uhr
Goto Top
Also prinzipiell lade ich alles vom FTP auf meinen lokalen Server. Da das löschen nicht immer klappt der Umweg über einen zweiten lokalen Ordner der mir dann vom 1. lokalen nur die neuen Daten in einen 2. lokalen schiebt. Auf den 2. greift der uploader zu. Damit dieser weiß was hoch geladen wurde, packt er das dann jeweils in Unterordner.

Die Dateien haben die Endung .ddd

Der "Umweg" über das winscp mit eine Filezilla Sitzung liegt daran, dass im Filezilla die FTP Zugangsdaten (Server, User + Pass) gespeichert sind.

Beim FTP habe ich schon mal die Daten gelöscht, am nächsten Tag waren die wieder da. Das bekommt man mit dem Anbieter auch irgendwie nicht 100% gelöst. Daher will ich den umweg über zwei lokale Ordner gehen.
Der 1. ist der FTP Inhalt.
In den 2. wird nur das rein kopiert was vom Vortag ist. In diesem Ordner arbeitet auch der Uploader Der verschiebt halt die Dateien entweder in sucess oder failed (je nach Erfolg).

Also ist der 1. nur die kopie vom FTP und der 2. der interessante für den Uploader. Wenn dort die Daten zu groß werden schmiert das Teil ab.

Hoffe das ist jetzt klarer face-smile
6247018886
6247018886 09.03.2023 um 14:35:36 Uhr
Goto Top
TK1987
TK1987 09.03.2023 aktualisiert um 14:44:00 Uhr
Goto Top
Moin,

Zitat von @killtec:
$wscp_par="-filezilla ","Download /script=","F:\Downloadscripte\download.txt ","/log=F:\Downloadscripte\logs\",$dat,".log"  
da sind mehrere Fehler drin. Zum einen hast du ein Leerzeichen hinter der download.txt, welches einen Fehler verursachen dürfte. Zudem kannst du bei der Log natürlich nicht einfach Pfad, Dateinamen und Erweiterung voneinander trennen.

Versuch es mal mit:
$wscp_par="-filezilla","Download","/script=""F:\Downloadscripte\download.txt""","/log=""F:\Downloadscripte\logs\$dat.log"""  

Gruß Thomas
Crusher79
Crusher79 09.03.2023 um 14:55:05 Uhr
Goto Top
Also CSV kann man hernehmen oder mit gci die Items aus Erfolg holen. $_.Basname o.ä. als vergleich, damit genau die nicht nochmal kopiert werden.

Nur irgendwann ist alles vollgemüllt. Mit CSV kann man auch mal die Referenzen in Erfolgreich weglöschen und hat - falls der FTP die Dateien der letzten 10 Jahre auspuckt - immer noch was zum Vergleich.

E-Mail ja, aber ggf. nur im Fehlerfall an euer Ticketsystem. Große Dateien anhängen ist auch unschön - File Liste sollte da reichen.

Syncen ist vlt. auch zu viel. Es reicht wenn nur die letzten 2-5 Tage geladen werden. Ist das sauber entweder sofort oder später den FTP leeren. Längerer Zeitraum als Puffer/ Fehlertoleranz. Dann die Dateien in den Hotfolder für die App schieben und parallel CSV als Logfile führen. Dient später auch als Exclusion für bereits kopierte Dateien.

Wenn dir das File-Limit bekannt ist, kannst du die Dateien auch vorher schon aussortieren. Zu Große Dateien bekommt die App da gar nicht erst zu sehen. Du weißt ja eh schon was sonst damit passiert.

Hab leider grad keine FTP hier. Sonst würd ich das mal durchknallen.

Brauchen wir filezilla überhaupt? Frage ist, hast du die Credentials oder müssen wir die aus Filezila holen? Sollte ja Base64 encodiert sein. Heisst sollte man auch auslesen können ... Dann wäre der Krams mit Filezilla mal komplett weg.
killtec
killtec 09.03.2023 um 14:57:58 Uhr
Goto Top
Zitat von @TK1987:

Moin,

Zitat von @killtec:
$wscp_par="-filezilla ","Download /script=","F:\Downloadscripte\download.txt ","/log=F:\Downloadscripte\logs\",$dat,".log"  
da sind mehrere Fehler drin. Zum einen hast du ein Leerzeichen hinter der download.txt, welches einen Fehler verursachen dürfte. Zudem kannst du bei der Log natürlich nicht einfach Pfad, Dateinamen und Erweiterung voneinander trennen.

Versuch es mal mit:
$wscp_par="-filezilla","Download","/script=""F:\Downloadscripte\download.txt""","/log=""F:\Downloadscripte\logs\$dat.log"""  

Gruß Thomas
Das ging schon mal,
hätte ich nur noch die "verschönerung" meiner Ordner Geschichte.
Crusher79
Crusher79 09.03.2023 um 14:58:29 Uhr
Goto Top
Zitat von @killtec:

Die Dateien haben die Endung .ddd


Fuhrpark und du wilslt euren Wagenmeister eine Freude machen? face-big-smile
6247018886
6247018886 09.03.2023 aktualisiert um 15:36:08 Uhr
Goto Top
Zitat von @killtec:
hätte ich nur noch die "verschönerung" meiner Ordner Geschichte.

$root = "F:\DLT"  
$companies = "Firma1","Firma2"  
$subfolders = "massdata","drivercards"  
foreach($company in $companies){
    foreach($subfolder in $subfolders){
        Get-ChildItem "$root\download\$company\$subfolder" -File -Filter *.ddd | ?{$_.LastWriteTime -gt (Get-Date).Date.AddDays(-2)} | copy-item -Destination (md "$root\automatisch\$company\$subfolder" -Force).Fullname  
    }
}
oder
$root = "F:\DLT"  
Get-ChildItem "$root\download\*\*" -Directory | %{Get-ChildItem $_.Fullname -File -Filter *.ddd | ?{$_.LastWriteTime -gt (Get-Date).Date.AddDays(-2)} | copy-item -Destination {(md "$root\automatisch\$($_.Directory.Parent.Name)\$($_.Directory.Name)" -Force).Fullname}}  
killtec
killtec 09.03.2023 aktualisiert um 15:09:59 Uhr
Goto Top
Zitat von @Crusher79:

Zitat von @killtec:

Die Dateien haben die Endung .ddd


Fuhrpark und du wilslt euren Wagenmeister eine Freude machen? face-big-smile

Geht in die Richtung... Ich bin nur der dem gesagt wurde: Mach mal :D

Fuhrpark stimmt. Es geht hier u.a. um VDO My-FIS...

Die Creds vom FTP habe ich.
Das mit Filezilla ist damals auf die schnelle entstanden. Soll jetzt halt schöner werden...
killtec
killtec 09.03.2023 um 15:15:57 Uhr
Goto Top
Aktuelle Version ist diese, die funktioniert:
$root = "F:\DLT"  
$companies = "Firma1","Firma2","Firma3"  
$subfolders = "massdata","drivercards"  
$dat=(get-date -format "yyyyMMdd-HH.mm")  
$wscp_par="-filezilla","Download","/script=F:\Downloadscripte\download.txt","/log=F:\Downloadscripte\logs\$dat.log"  
write-host "Vari: "+ $wscp_par  
&"C:\Program Files (x86)\WinSCP\WinSCP.exe" $wscp_par  
foreach($company in $companies){
    foreach($subfolder in $subfolders){
        Get-ChildItem "$root\download\$company\$subfolder" | ?{$_.LastWriteTime -gt (Get-Date).Date.AddDays(-2)} | copy-item -Destination "$root\automatisch\$company\$subfolder"  
    }
}
killtec
killtec 10.03.2023 um 08:59:18 Uhr
Goto Top
Ein kleines Problem habe ich noch...
da Script funktioniert soweit. Das log wird allerdings nur erstellt, wenn ich am System Angemeldet bin. Wird der Task / das Script automatisch ausgeführt und es ist keiner angemeldet, so erstellt er kein log.
Am Schluss des Scriptes habe ich noch ein send-mail stehen, somit weiß ich zumindest, dass das Script an sich ausgeführt wird.
Gibt es noch eine Möglichkeit das zu debuggen?
6247018886
6247018886 10.03.2023 aktualisiert um 09:28:49 Uhr
Goto Top
Ohne Anmeldung sind keine Netzlaufwerke verbunden. Benutze besser UNC Pfade.
Gibt es noch eine Möglichkeit das zu debuggen?
Start-Transcript
killtec
killtec 10.03.2023 um 09:30:40 Uhr
Goto Top
Es sind alles lokale Laufwerke...
start-transcript schaue ich mir an face-smile