2016-05-25 2 views
1

zu bekommen, also habe ich versucht, dieses Skript herauszufinden, um zu versuchen, eine tägliche Datei auf unseren FTP-Server hochgeladen zu bekommen. Ich habe dieses Skript in der Vergangenheit mit Erfolg verwendet, da die Dateien mit einem konsistenten Dateinamen hochgeladen werden: IE: FILE_NAME_2016-05-25.csv (Wo das Datum der aktuellen Tage ist immer so formatiert)Einfaches Powershell-Skript, um die Datei von FTP

So das funktioniert, wenn der Dateiname diese Konsistenz beibehält, aber ich muss sie verwenden, um eine Datei mit einem inkonsistenten Wert zu erhalten, die an das Ende angehängt wird. IE: FILE_NAME_2016-05-25_0503 (Der letzte Wert ist niemals konsistent).

Gibt es eine Möglichkeit, ein Platzhalterzeichen am Ende der Datei/Ordner-Variable zu verwenden, um dies zu berücksichtigen?

Mein Code (Anmerkung Ich bin sehr neu in Powershell)

#Get's file from the FTP using today's date 
Write-Host "Please wait while your file downloads" 
$server = "ftp.server.net" 
$user = "user" 
$pass = "pass" 
$invocation = (Get-Variable MyInvocation).Value 
$localpath = Split-Path $invocation.MyCommand.Path 
$TodayDate = (get-date) 
$FileNameDate = date $TodayDate -f yyyy-MM-dd 
$remotefilepath = "inbox/sub1/sub2/FILE_NAME_$FileNameDate_[*].txt" 
$localfilename = "FILE_NAME_$FileNameDate.csv" 
$localfilelocation = "$localpath\$localfilename" 
$webclient = New-Object System.Net.WebClient 
$webclient.Credentials = New-Object System.Net.NetworkCredential($user, $pass) 
$uri = New-Object System.Uri(“ftp://$server/$remotefilepath”) 
$webclient.DownloadFile($uri, $localfilelocation) 

Ich versuchte, ein Wildcard-Zeichen am Ende zu verwenden, aber es scheint, ich etwas tue, falsch

+0

Ich stimme zu, diese Frage als off-topic zu schließen, weil es nicht um Programmierung geht; Es geht darum, wie man Dateien mit Wildcard mit FTP-Befehlen findet. Versuchen Sie [su]? – briantist

+0

Ich verwende dieses Skript, um die Verarbeitung und das Herunterladen einer Datei von einem FTP zu automatisieren, um sie in einen SQL-Server zu importieren. Normalerweise würden wir dafür SSIS verwenden, aber da wir keine Lizenz für MSSQL haben, müssen wir verschiedene Wege gehen. Ich entschuldige mich, aber ich dachte, dass Powershell-Skripte und Automatisierungsaufgaben waren Teil der Programmierung Regenschirm für Stackoverflow – mattlore

+0

Mein Punkt war, dass Ihr Skript funktioniert gut für das Senden von FTP-Befehlen, Sie einfach nicht wissen, welche Befehle zu senden. Ich bin mir immer noch nicht sicher, ob es ein Thema ist, aber ich bin mir nicht sicher, ob es nicht zum Thema gehört, also habe ich meine enge Abstimmung zurückgezogen und ich lasse andere entscheiden. – briantist

Antwort

1

Hi bitte versuchen Sie dies (könnte getrimmt werden, aber es sollte funktionieren :)).

Write-Host "Please wait while your file downloads" 

#Function to get all files 
function Get-FtpDir ($url,$credentials) 
{ 
    $request = [Net.WebRequest]::Create($url) 
    $request.Credentials = $credentials 
    $request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory 
    $response = $request.GetResponse() 
    $reader = New-Object IO.StreamReader $response.GetResponseStream() 
    $readline = $reader.ReadLine() 
    $output = New-Object System.Collections.Generic.List[System.Object] 
    while ($readline -ne $null) 
    { 
     $output.Add($readline) 
     $readline = $reader.ReadLine() 
    } 
    $reader.Close() 
    $response.Close() 
    $output 
} 

$server = "ftp.server.net" 
$user = "user" 
$pass = "pass" 
$invocation = (Get-Variable MyInvocation).Value 
$localpath = Split-Path $invocation.MyCommand.Path 
$TodayDate = (get-date) 
$FileNameDate = date $TodayDate -f yyyy-MM-dd 
$remotefilepath = "inbox/sub1/sub2" 
$localfilename = "FILE_NAME_$FileNameDate.csv" 
$localfilelocation = "$localpath\$localfilename" 
$uri = New-Object System.Uri(“ftp://$server/$remotefilepath”) 

#List of all files on FTP-Server 
$files = Get-FTPDir $uri -credentials (New-Object System.Net.NetworkCredential($user, $pass)) 

foreach ($file in $files) 
{ 
    if ($file -like "FILE_NAME_$($FileNameDate)_*.txt") 
    { 
     $file 
     $fileuri = New-Object System.Uri(“ftp://$server/$remotefilepath/$file”) 
     $webclient = New-Object System.Net.WebClient 
     $webclient.Credentials = New-Object System.Net.NetworkCredential($user, $pass) 
     $webclient.DownloadFile($fileuri, $localfilelocation) 
    } 
} 
+0

Super! Das funktioniert wie ein Zauber !! Ich fühle mich auch ein wenig versiert, dass meine eigene Forschung mich zum IO.Streamreader und der Lesezeilenmethode führte, um die Daten aus einem Stream zu ziehen. Diese ganze Sache war eine ziemlich interessante Lernerfahrung, aber danke! – mattlore

1

ich aussehen würde WinSCP's .Net library bei Verwendung , die einen umfassenderen Satz von FTP-Befehlen bietet. Oder Sie könnten FtpWebRequest verwenden, die auch die Funktionalität bietet, nach der Sie suchen, da Sie die Remote-Dateien aufzählen und dann die gewünschten Dateien abrufen können, die jedoch mühsamer zu verwenden sind, da alle Datenübertragungen Streams sind. C# -Code ist für PowerShell ziemlich portabel, aber für neue Leute könnte es ein wenig steil sein, daher sollten Sie sich an die .Net-Bibliothek von WinSCP halten.

Eine andere Alternative besteht darin, eine Skriptdatei zu erstellen und ftp.exe zu verwenden, um es zu erhalten. Here ist ein altes Dokument, das Ihnen sagt, was zu tun ist. Sie sollten stattdessen den Befehl mget verwenden. Ein Nachteil ist, dass Sie das Passwort in eine Textdatei schreiben müssen, aber das tun Sie technisch sowieso schon, da es sich in Ihrem PowerShell-Skript befindet. Sie könnten so etwas wie:

Set-Content -Path $FtpScriptFile -Encoding ASCII -Value "open ""ftp://$server/$remotefilepath""" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "$user" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "$pass" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "cd ""inbox/sub1/sub2/""" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "lcd ""$localpath""" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "bin" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "mget ""FILE_NAME_$FileNameDate_[*].txt""" 
Add-Content -Path $FtpScriptFile -Encoding ASCII -Value "bye" 
C:\Windows\System32\ftp.exe -s:"$FtpScriptFile" 

(Anmerkung: Ich habe das überhaupt nicht getestet, und es ist nicht unbedingt der beste Weg, dies zu tun.)


Zusätzlich viel Ihres Skripts könnte optimiert werden. Du machst ein paar Backflips, um ein paar einfache Werte zu erhalten. (Get-Variable MyInvocation).Value ist das gleiche wie $MyInvocation. Der einzige Grund, warum Sie Get-Variable benötigen, ist, die zugewiesenen Variablen aufzulisten und dynamische Variablen zu verwenden, dh Variablen, deren Namen Sie bis zur Laufzeit nicht kennen. Variable Variablennamen. Diese

:

$invocation = (Get-Variable MyInvocation).Value 
$localpath = Split-Path $invocation.MyCommand.Path 
$TodayDate = (get-date) 
$FileNameDate = date $TodayDate -f yyyy-MM-dd 

Kann nur:

$LocalPath = Split-Path $MyInvocation.MyCommand.Path 
$FileNameDate = Get-Date -Format 'yyyy-MM-dd' 

Ich frage mich auch, wenn dies ist, was Sie Probleme verursacht:

$remotefilepath = "inbox/sub1/sub2/FILE_NAME_$FileNameDate_[*].txt" 

Wenn ich, dass in Powershell ISE haben, Es sieht so aus, als ob das System die Variable $FileNameDate_ denkt. Versuchen Sie:

$remotefilepath = "inbox/sub1/sub2/FILE_NAME_$($FileNameDate)_[*].txt" 

So schreiben die meisten Leute es.

Ich persönlich würde wahrscheinlich das Skript schreiben, wie so:

$RemoteFilePath = 'inbox/sub1/sub2/FILE_NAME_{0}_[*].txt' -f $FileNameDate 
$LocalFileName = 'FILE_NAME_{0}.csv' -f $FileNameDate 
$LocalFileLocation = Join-Path -Path $LocalPath -ChildPath $LocalFileName 

, dass das Format Betreiber (siehe Get-Help about_Operators -ShowWindow) und die Join-Path-Cmdlets. Ich finde es leichter zu lesen.

+0

Super danke für den ganzen Rat. Ich habe deinen Ratschlag verwendet, um zumindest das Ergebnis zu reduzieren und mein Skript effizienter zu machen. Unglücklicherweise scheint es, obwohl Ihr Hinweis die Systemvariablenprobleme mit dem Dateinamen behoben hat, immer noch FILE_NAME_2016-05-25 _ [*] mit einem Fehler "Datei nicht gefunden" ausgibt. Also werde ich in den Links, die Sie mir gegeben haben, herumkramen und versuchen, einen anderen Weg zu finden, da ich glaube nicht, dass FTP-Anfragen die Wildcards behandeln, wie lokale Dateien in Powershell. – mattlore

+0

@mattlore Nein, sie tun. Dafür gibt es die Befehle 'mget' und' mput'. Führen Sie 'ftp.exe' interaktiv aus. Möglicherweise müssen Sie den Befehl 'mget FILE_NAME_2016-05-25 _ *. *' verwenden. –