itnewbee
Goto Top

Powershell FTP Download + Move

Hallo zusammen! Ich wende mich jetzt einfach mal Vertrauensvoll an das Forum da ich leider überhaupt nicht weiterkomme...
Ich bin Andi und mach grad eine Umschulung zum FiSi und bin eben "ganz" neu in der Thematik.

Zu meinem Problem.

Jetzt bin ich in einem Praktikumsbetrieb und hab hier die Aufgabe bekommen Dateien von einem FTP Server per Powershell und Aufgabenplanung alle 30min. herunterzuladen und dann zu Archivieren. Diese Dateien (.csv) sollen aber während dem Herunterladen nicht mit .csv sondern .neu und in einem Lokalen Ordnern sagen wir C:\Test angelegt werden.
Erst wenn der Download abgeschlossen ist sollen diese in .csv umbenannt werden. Danach sollen die heruntergeladenen Dateien auf dem FTP Server in einen Archivordner verschoben werden.

Ich hoffe mir kann jemand weiterhelfen.

Vielen Dank im voraus!

Content-ID: 666665

Url: https://administrator.de/forum/powershell-ftp-download-move-666665.html

Ausgedruckt am: 27.12.2024 um 16:12 Uhr

117471
117471 12.05.2021 um 12:27:01 Uhr
Goto Top
Hallo,

klar - ich mach' mal eben deine Arbeit.

Tipp: Es geht bei so etwas darum, wie Du dich der Aufgabe näherst.

Das Ergebnis ist meistens zweitrangig.

Gruß,
Jörg
Doskias
Doskias 12.05.2021 um 12:27:12 Uhr
Goto Top
Hallo Andi,

wenn du überhaupt nicht weiterkommst, dann hast du doch schon sicher einen Ansatz, oder? Poste ihn doch einfach mal hier, damit wir sehen wie weit du bist und wo es hakt. Wobei ich gestehen muss, dass mich die "temporäre" Ablage etwas irritiert. Warum sollen die Daten temporär irgendwo anders abgelegt werden und wieso dann auch noch mit der Dateiendung neu anstatt csv. Das ist in meinen Augen total unnötig, Dateiendung macht in meinen Augen nur dann Sinn, wenn sie im gleichen Ordner wie die CSV liegen. Wenn sie aber schon in einem separaten Ordner liegen, ist das doppelt. Wo steckt da der Sinn drin?

Außerdem: Wie groß sind die CSV-Dateien. Im Regelfall sind CSV nicht mehrere GB groß, so dass der Download relativ schnell abgeschlossen sein sollte.

Gruß
Doskias
117471
117471 12.05.2021 um 12:36:02 Uhr
Goto Top
Hallo,

Zitat von @Doskias:

Das ist in meinen Augen total unnötig,

Wie gesagt - scheint eher 'ne Übungsaufgabe zu sein um zu gucken, wie die Herangehensweise ist.

Die erste Frage, die sich mir stellt ist, wie man den FTP-Client steuert und ob der FTP-Client von Windows (so es ihn noch gibt) das überhaupt kann. Und dann stellt sich die zweite Frage, ob man ernsthaft für jede Datei eine FTP-Session mit Authentifizierung usw. aufmacht - das dürfte einen gewissen Overhead ergeben face-smile

Interessant ist es schon, irgendwie^^

Gruß,
Jörg
148523
148523 12.05.2021 um 13:05:27 Uhr
Goto Top
Doskias
Doskias 12.05.2021 aktualisiert um 13:12:07 Uhr
Goto Top
Ich hab vor 3 bis 4 Jahren mal n Powersehell-Skript geschrieben, welche CSV-Dateien von einem FTP heruntergeladen hat, dann geprüft hat welche schon verarbeitet wurden (anhand des Namens und einer eigenen Log-Datei) und die neuen Dateien per SQL-Befehl dann in eine Datenbank importiert habe. Allerdings habe ich nach dem Motto "stumpf ist Trumpf" auch einfach alle Dateien vom FTP geladen und nicht nur die neuen. Das Ganze auf einem Windows 10 Client, später dann auf einem Windows Server (glaube 2016)

Ob das mit dem Umbenennen während des Downloads geht hab ich keine Ahnung, aber FTP-Server mit Powershell abfragen geht. Klickst du hier

Gruß
Doskias
148121
148121 12.05.2021 aktualisiert um 13:57:50 Uhr
Goto Top
FTP geht zwar auch mit .NET nativ, aber ich würde zum WinSCP .NET Assembly raten da ist das Error-Checking auch leichter und vor allem werden auch modernere Verfahren supportet.

$server = 'server.domain.tld'  
$username = 'USERNAME'  
$password =  'PASSWORT'  
$remotefolder = '/tmp/daten/'  
$remotearchive = '/tmp/archiv/'  
$localfolder = 'D:\download'  
$filefilter = '*.csv'  

Add-Type -Path "D:\Ordner\WinSCPnet.dll" # Pfad anpassen  

$options = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::ftp
    Hostname = $server
    Username = $username
    Password = $password
}
$session = New-Object WinSCP.Session
try{
    # open session
    $session.Open($options)
    # define transport options
    $transoptions = New-Object WinSCP.TransferOptions -Property @{Transfermode = [WinSCP.TransferMode]::Binary}
    
    write-host "Downloading files from '$remotefolder' to '$localfolder' ... " -F Green -NoNewline  
    $result = $session.GetFilesToDirectory($remotefolder,$localfolder,$filefilter,$false,$transoptions)
    write-host "Done" -f Green  
    $result.Check()
    if ($result.Transfers.Count -gt 0){
        write-host "Start moving remote files ..." -F Green  
        $result.Transfers | %{
            if (!$_.Error){
                $result = $session.MoveFile($_.Filename,$remotearchive)
                if ($result.Error){
                   write-host "Error moving file $($_.FileName): $($result.Error)" -F Red  
                }
            }else{
                write-host "Download of file $($_.FileName) failed : $($_.Error)" -F Red  
            }
        }
        write-host "Done" -F Green  
    }
}catch{
    write-error -Message $_.Exception.Message
}finally{
    # cleanup
    $session.Close()
    $session.Dispose()
}
Gruß w.
erikro
erikro 12.05.2021 um 15:58:45 Uhr
Goto Top
Moin,

Zitat von @117471:
klar - ich mach' mal eben deine Arbeit.

Nee, wir machen die Arbeit des Ausbilders. face-sad Warum glauben eigentlich so viele, dass Azubis billige Vollzeitkräfte sind?

my 2 cents

Erik
117471
117471 12.05.2021 um 16:08:35 Uhr
Goto Top
Hallo,

Zitat von @erikro:

Nee, wir machen die Arbeit des Ausbilders. face-sad

Meinste?

Ich halte den Prozess mit der Umbenennung usw. für ausgesprochen fragwürdig und kann mir kaum vorstellen, dass so etwas produktiv gehen soll.

So etwas denke ich mir aus, wenn ich möchte, dass sich mein Praktikant mit Powershell beschäftigt und mich kurz mal 2-3 Tage in Ruhe lässt. Deshalb meine vielleicht etwas zu direkte Antwort face-smile

Gruß,
Jörg
itnewbee
itnewbee 12.05.2021 um 22:15:35 Uhr
Goto Top
Hallo und guten Abend. Entschuldigt die späte Antwort aber ich war ziemlich eingespannt.

1. Ich will weder das jemand meine Arbeit macht noch komplette Lösungen zu schustert. Es reichen ja Denk anstöße. Im Internet bei Dr. Google findet man soviel das halt nicht direkt auf das passt was vom Kunden gewünscht ist. Daher hier meine Frage. FTP Download ok wie auch weiter oben schon steht. Das klappt aber das spezifische umschreiben ist halt der Knackpunkt.

2. Nein es handelt sich nicht nur um eine Aufgbe für einen "Azubi" als Test sondern es ist eine tats. EPIC die beim Kunden für den laufenden Betrieb umgesetzt werden soll. Ich bin grad im Moment allein der einzige Admin im Haus da der Hauptadmin im urlaub ist und ich nebenbei auch Kunden Termine habe und den telefonischen Support mache.

3. Fragen kann man ja als Neuling in dem Bereich, hoff ich denk ich? Und wie sagt der Dozent gern Google hilft weiter...

Zum Fall selber nochmal der sieht tats. so aus: Kunde betreibt einen Webshop dort werden ja bekanntlich Bestellungen aufgegeben. Diese werden auf einem FTP Server als 2 CSV Dateien abgespeichert. Nun hat der Kunde einen Server dort läuft ein eigenentwikeltes Programm auf SQL Basis das praktisch diese beiden Datein aus einem lokalen Ordner nimmt wenn vorher vom FTP geholt und verarbeitet. Wenn das erledigt ist werden diese von .CSV in .ARC umgeschrieben und in einen Archiv Ordner verschoben. Nun wollte der Projektleiter es aber so haben das wenn die Daten gedownloaded werden "wie auch bei Datein aus dem Internet", die Endung solange der Download noch nicht abgeschlossen ist als .neu gekennzeichnet werden und wenn fertig dann in .csv umbenannt werden. Das soll als Sicherung laufen falls bereits eine CSV vorhanden ist und vom Programm gerade verabreitet wird, was ja eigentlich nur paar Sek. dauert aber mann weis ja nie und sich die dann nicht in die Quere kommen. Auch soll nach erfolgreichem Download die Datei auf dem FTP Server in einen Archivordner verschoben werden.

Das mit WinSCP und einbinden in PS hab ich mir auch schon angesehen.

Danke nochmal und schönen Feiertag morgen.
erikro
erikro 13.05.2021 aktualisiert um 12:52:23 Uhr
Goto Top
Moin,

Zitat von @itnewbee:

Hallo und guten Abend. Entschuldigt die späte Antwort aber ich war ziemlich eingespannt.

Kein Problem, wir wissen alle, wie das ist.

1. Ich will weder das jemand meine Arbeit macht noch komplette Lösungen zu schustert. Es reichen ja Denk anstöße. Im Internet bei Dr. Google findet man soviel das halt nicht direkt auf das passt was vom Kunden gewünscht ist. Daher hier meine Frage. FTP Download ok wie auch weiter oben schon steht. Das klappt aber das spezifische umschreiben ist halt der Knackpunkt.

Es ist Feiertag und das Wetter ist so schlecht wie im November. face-sad Dann mache ich mal die Arbeit Deines Ausbilders. face-wink

Mir sind drei grundsätzliche Methoden bekannt, wie man mit der PS FTP bedienen kann:

Mit dem Modul PSFTP:
https://www.syspanda.com/index.php/2019/05/31/interacting-ftp-sftp-using ...

Vorteil: Solche Module machen einem das Leben viel einfacher. Man muss sich nicht mit den Methoden rumschlagen.
Nachteil: Das Modul muss vorhanden sein. Da es sich um kein Standardmodul handelt, muss es erst heruntergeladen werden. Du kannst also nicht sicher sein, ob das beim Kunden so läuft. Sprich, Du musst Dich absprechen, ob das Modul auf der Zielmaschine installiert werden kann/darf.

Mit dem .NET-Objekt:
https://www.computerweekly.com/de/tipp/Upload-und-Download-von-Dateien-p ...

oder dem System-Objekt:
https://www.thomasmaurer.ch/2010/11/powershell-ftp-upload-and-download/

Vorteil: Geht immer.
Nachteil: Da vor allem bei den System-Objekten die Kette der Objektgenerationen und -methoden sehr lang werden kann, wird das gerne mal unübersichtlich. Und man muss letztlich alles "zu Fuß" konfigurieren.

2. Nein es handelt sich nicht nur um eine Aufgbe für einen "Azubi" als Test sondern es ist eine tats. EPIC die beim Kunden für den laufenden Betrieb umgesetzt werden soll. Ich bin grad im Moment allein der einzige Admin im Haus da der Hauptadmin im urlaub ist und ich nebenbei auch Kunden Termine habe und den telefonischen Support mache.

Der Azubi ist der einzige vor Ort? Ist das in der Ausbildungsordnung überhaupt erlaubt? Aber das kennt man ja von der FiSi-Ausbildung: Hier ist Dein Computer. Google kennst Du ja. Dann mach mal. face-sad

3. Fragen kann man ja als Neuling in dem Bereich, hoff ich denk ich? Und wie sagt der Dozent gern Google hilft weiter...

Wenn das das einzige ist, was er sagt, dann ist er kein Dozent. face-wink Klar kannst du fragen. Schön wäre halt bei solchen Fragen, wenn Du das, was du schon hast, hier postest und konkret fragst, wo Du nicht weiterkommst. Herauszufinden, wie man FTP mit der PS macht, ist nun wirklich keine Kunst. face-wink

Zum Fall selber nochmal der sieht tats. so aus: Kunde betreibt einen Webshop dort werden ja bekanntlich Bestellungen aufgegeben. Diese werden auf einem FTP Server als 2 CSV Dateien abgespeichert. Nun hat der Kunde einen Server dort läuft ein eigenentwikeltes Programm auf SQL Basis das praktisch diese beiden Datein aus einem lokalen Ordner nimmt wenn vorher vom FTP geholt und verarbeitet. Wenn das erledigt ist werden diese von .CSV in .ARC umgeschrieben und in einen Archiv Ordner verschoben. Nun wollte der Projektleiter es aber so haben das wenn die Daten gedownloaded werden "wie auch bei Datein aus dem Internet", die Endung solange der Download noch nicht abgeschlossen ist als .neu gekennzeichnet werden und wenn fertig dann in .csv umbenannt werden.

Klar, dass er das will. Er will verhindern, dass der Automatismus die Datei schon versucht zu holen, wenn sie noch nicht fertig heruntergeladen ist. Aber ist das notwendig? Ich bin mir jetzt nicht sicher. Aber ich meine, dass die partielle Datei auch bei dem Verfahren erst einmal anders heißt und erst am Ende automatisch umbenannt wird. Das würde ich mal testen. Eigentlich bin ich mir da sicher, dass dem so ist.

Das soll als Sicherung laufen falls bereits eine CSV vorhanden ist und vom Programm gerade verabreitet wird, was ja eigentlich nur paar Sek. dauert aber mann weis ja nie und sich die dann nicht in die Quere kommen.

Was für ein Quatsch. Das muss das selbst entwickelte Programm abfangen. Denn der Fall kann ja auch eintreten, wenn die Datei fertig heruntergeladen wurde. Spätestens dann heißt sie so. Also muss im Programm ein Semaphor gesetzt werden, der verhindert, dass der Prozess zweimal gestartet wird.

Da frage ich mich dann gleich, warum die selbstgestrickte Software nicht gleich den ganzen Vorgang enthält. Warum lagert man den Download in ein Powershellskript aus? Aber wenn Du das fragst, dann wird man den Azubi für neunmalklug halten. face-wink

Auch soll nach erfolgreichem Download die Datei auf dem FTP Server in einen Archivordner verschoben werden.

Na das ist banal.

Das mit WinSCP und einbinden in PS hab ich mir auch schon angesehen.

Das wäre dann vierte Methode, wie man das machen kann mit den gleichen Vor- und Nachteilen, die alle Module haben.

Liebe Grüße

Erik
itnewbee
itnewbee 14.05.2021 um 14:43:55 Uhr
Goto Top
Vielen Dank für die super Unterstützung. Ich habs jetzt soweit mit WinSCP und Powershell gelöst. Es funktioniert alles super bis auf die eingebaute "foreach" schleife. Hier sollte die vorherige gedownloadete .txt_neu so geändert werden das der Suffix wieder gelöscht wird. Aber egal was ich versuche "wahrscheinlich denke ich zu kompliziert" gehts nicht.

$server = 'muster.server.de'  
$username = 'mustermann'  
$password =  'musterpw'  
$remotefolder = "/source/export/"  
$remotearchive = "/source/export/archiv/"  
$localfolder = "C:\test\Konfiguration\Transfer\"  
$filefilter = '*.txt'  


Add-Type -Path "C:\Setup\WinSCP\WinSCPnet.dll"  

$options = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::ftp
    Hostname = $server
    Username = $username
    Password = $password
}

$session = New-Object WinSCP.Session

try{
    # connect
    $session.Open($options)

    $suffix = "_neu"  

    # define transport options
    $transoptions = New-Object WinSCP.TransferOptions -Property @{Transfermode = [WinSCP.TransferMode]::Binary}
    $transoptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::off

    write-host "Downloading files from '$remotefolder' to '$localfolder' ... " -F Green -NoNewline  
    $result = $session.GetFiles(($remotefolder+$filefilter),($localfolder + "*.*" + $suffix),$False,$transoptions)  

    **foreach ($transfer in $result.Transfers){
               # Remove suffix
               $finalName = $transfer.Destination.SubString(0, $transfer.Destination.Length - $suffix.Length)
               Write-Host "Renaming uploaded file $($transfer.Destination) to $finalName"  
               # Rename uploaded file to its final name
               $session.MoveFile($transfer.Destination, $finalName)
        }**

    write-host "Done" -f Green  

    $result.Check()

    if ($result.Transfers.Count -gt 0){
        write-host "Start moving remote files ..." -F Green  
        $result.Transfers | %{
            if (!$_.Error){
                $result = $session.MoveFile($_.Filename,$remotearchive)
                if ($result.Error){
                   write-host "Error moving file $($_.FileName): $($result.Error)" -F Red  
                }
            }else{
                write-host "Download of file $($_.FileName) failed : $($_.Error)" -F Red  
            }
        }
        write-host "Done" -F Green  
    }

}catch{
    write-error -Message $_.Exception.Message
}finally{
    # cleanup
    $session.Dispose()
}
itnewbee
itnewbee 14.05.2021 um 15:29:13 Uhr
Goto Top
Hab eben weiter noch selber rausgefunden das es in der foreach nicht $transfer.Destination heißen soll sondern:
foreach ($transfer in $result.Transfers){
               $finalName = $transfer.Filename.SubString(0, $transfer.Filename.Length - $suffix.Length)
               $session.MoveFile($transfer.Filename, $finalName)}
Aber wenn ich das einsetze dann schreibt er mir meine test.txt auf dem FTP um und zwar in test ".txt" wird dort gelöscht. Es soll aber nur im Download Ordner die Dateiendung _neu entfernt werden.