Alternative zu Windows PowerShell?

283

Ich weiß, dass ich die oben genannte Bibliothek (wget für Windows) herunterladen und installieren kann, aber meine Frage lautet:

Gibt es in Windows PowerShell eine native Alternative zu wget?

Ich muss wgetnur eine Datei von einer bestimmten URL mit HTTP GET abrufen. Zum Beispiel:

wget http://www.google.com/
jsalonen
quelle
Siehe auch superuser.com/questions/25538/...
jiggunjer

Antworten:

236

Hier ist ein einfacher Einzeiler für PS 3.0 und höher, der funktioniert und nicht viel PS-Aufwand mit sich bringt:

wget http://blog.stackexchange.com/ -OutFile out.html

Beachten Sie, dass:

  • wget ist ein Alias ​​für Invoke-WebRequest
  • Invoke-WebRequest gibt ein HtmlWebResponseObject zurück , das viele nützliche HTML -Analyseeigenschaften wie Links, Bilder, Formulare, Eingabefelder usw. enthält. In diesem Fall verwenden wir jedoch nur den unformatierten Inhalt
  • Der Dateiinhalt wird vor dem Schreiben auf die Festplatte im Speicher abgelegt, sodass dieser Ansatz nicht zum Herunterladen großer Dateien geeignet ist
  • Bei Windows Server Core-Installationen müssen Sie dies als schreiben

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html
    
  • Vor dem 20. September 2014 schlug ich vor

    (wget http://blog.stackexchange.com/).Content >out.html
    

    als Antwort. Dies funktioniert jedoch nicht in allen Fällen, da der >Operator (ein Alias ​​für Out-File) die Eingabe in Unicode konvertiert.

Wenn Sie Windows 7 verwenden, müssen Sie Version 4 oder höher des Windows Management Frameworks installieren.

Sie können feststellen , dass ein tun , $ProgressPreference = "silentlyContinue"bevor Invoke-WebRequestdeutlich Download - Geschwindigkeit mit großen Dateien zu verbessern; Diese Variable steuert, ob die Fortschritts-Benutzeroberfläche gerendert wird.

Warren Rumak
quelle
3
Dies ist nun die richtige Antwort, und ich habe versehentlich getestet, ob ich das eigentliche wget installiert habe. Es ist ärgerlich, dass der Dateiname nicht einfach abgerufen werden kann (Sie müssen ihn in der Ausgabeumleitung angeben), aber diese Option hat eine bessere Benutzeroberfläche als der echte wget (meiner Meinung nach), also gibt es das.
Matthew Scharley
13
Aber Windows 7 nur mit Powershell kommt 2.0 , und das Ergebnis wird „Der Begriff‚Invoke-WebRequest‘ist nicht als Name eines Cmdlets erkannt, ...“.
Peter Mortensen
16
Faire Warnung: Diese Methode speichert den gesamten Inhalt der Datei, bevor er in die Datei geschrieben wird. Dies ist keine gute Lösung zum Herunterladen großer Dateien.
im_nullable
2
@im_nullable, guter Anruf - das habe ich dem Beitrag hinzugefügt.
Warren Rumak
1
@dezza Ich habe die Antwort mit einem anderen Ansatz aktualisiert. Versuche es noch einmal.
Warren Rumak
181

Wenn Sie nur eine Datei abrufen müssen, können Sie die DownloadFile- Methode des WebClient- Objekts verwenden:

$client = New-Object System.Net.WebClient
$client.DownloadFile($url, $path)

Wo $urlist eine Zeichenfolge, die die URL der Datei darstellt und $pathden lokalen Pfad darstellt, in dem die Datei gespeichert wird?

Beachten Sie, dass $pathder Dateiname enthalten muss. Es kann nicht nur ein Verzeichnis sein.

Reisender Tech-Typ
quelle
32
Bisher war dies die beste vorgeschlagene Lösung. Da es so aussieht, als ob ich es in einem Zeilenformat umschreiben kann (new-object System.Net.WebClient).DownloadFile( '$url, $path), ist es die beste Korrespondenz, die wgetich bisher gesehen habe. Vielen Dank!
jsalonen
3
Als Randnotiz können Sie dies auch asynchron mit etwas wie (new-object System.Net.WebClient) .DownloadFileAsync (url, filePath)
James
Können wir einen bestimmten Text über den Webclient abrufen und auf einen Notizblock ausgeben? danke
Mowgli
6
Ja, dies funktioniert unter Windows 7 ( im Lieferumfang von PowerShell 2.0 enthalten ) sofort . Probe: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html")
Peter Mortensen
3
Um nur eine URL abzurufen und die Ergebnisse zu ignorieren (z. B. Teil eines IIS-Aufwärm-Skripts), verwenden Sie DownloadData:(new-object System.Net.WebClient).DownloadData($url) | Out-Null
BurnsBA,
86

Es gibt Invoke-WebRequestin der kommenden PowerShell-Version 3:

Invoke-WebRequest http://www.google.com/ -OutFile c:\google.html
user4514
quelle
9
die ganze Eleganz von dd...
gWaldo
1
@ gWaldo du machst Witze - das ist eine Freude zu benutzen (als jemand, der gerade PS lernt)
Jack Douglas
8
Ich meine nur, dass der -OutfileParameter irrelevant erscheint, wenn Sie nur eine Datei >(zum Überschreiben) oder >>(zum Anhängen) verwenden können.
gWaldo
5
@ gWaldo oder sogar den Dateinamen von der URL ableiten, genau wie wget:)
Peltier
5
Ab PS 4.0 wgetund curlstandardmäßig mit Invoke-WebRequest( iwr) gekennzeichnet: D
Bob
18

Es ist ein bisschen chaotisch, aber es gibt diesen Blog-Beitrag, der Anweisungen zum Herunterladen von Dateien enthält.

Alternativ (und dies ist eine, die ich empfehlen würde) können Sie BITS verwenden:

Import-Module BitsTransfer
Start-BitsTransfer -source "http://urlToDownload"

Es zeigt den Fortschritt an und lädt die Datei in das aktuelle Verzeichnis herunter.

Matthew Steeples
quelle
3
BITS ist auf die Unterstützung auf der Serverseite angewiesen. Falls verfügbar, funktioniert dies im Hintergrund, und Sie können Fortschrittsaktualisierungen mit anderen Cmdlets erhalten.
Richard
2
Ich habe versucht, google.com abzurufen , aber alles, was ich bekomme, ist Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)). Ich bin verwirrt: |
jsalonen
1
@jsalonen Ich denke, dass BITS nur Dateien anstatt Seiten herunterladen wird. Wie Richard sagt, ist es auf einige serverseitige Unterstützung angewiesen (obwohl ich nicht denke, dass es Microsoft-spezifisch ist).
Matthew Steeples
Ich verstehe und denke, ich habe den Sinn, BITS zu verwenden, aber es ist nicht das, wonach ich hier suche.
jsalonen
6

PowerShell V4 One-Liner:

(iwr http://blog.stackexchange.com/).Content >index.html`

oder

(iwr http://demo.mediacore.tv/files/31266.mp4).Content >video.mp4

Dies ist im Grunde der (großartige) V3-Einzeiler von Warren (danke dafür!) - mit nur einer kleinen Änderung, damit er in einer V4-PowerShell funktioniert.

Warrens Einzeiler - der einfach verwendet wird wgetund nicht verwendet wird iwr- sollte immer noch für V3 funktionieren (zumindest denke ich, habe ihn aber nicht getestet). Sowieso. Wenn Sie jedoch versuchen, es in einer V4- PowerShell auszuführen (wie ich es versucht habe), wird PowerShell nicht wgetals gültiges Cmdlet / Programm aufgelöst.

Für Interessenten, das ist - wie ich aus nahm Bob Kommentar in Antwort auf die akzeptierte Antwort (Danke, Mann!) - denn wie der Powershell - V4, wgetund curlist auf aliased Invoke-WebRequest, auf iwrstandardmäßig . Somit wgetkann nicht gelöst werden (wie auch curlhier nicht funktionieren kann) .

Blickfang
quelle
4

Hier ist eine PowerShell-Funktion, die kurze URLs auflöst, bevor die Datei heruntergeladen wird

function Get-FileFromUri {  
    param(  
        [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string]
        [Alias('Uri')]
        $Url,
        [parameter(Mandatory=$false, Position=1)]
        [string]
        [Alias('Folder')]
        $FolderPath
    )
    process {
        try {
            # resolve short URLs
            $req = [System.Net.HttpWebRequest]::Create($Url)
            $req.Method = "HEAD"
            $response = $req.GetResponse()
            $fUri = $response.ResponseUri
            $filename = [System.IO.Path]::GetFileName($fUri.LocalPath);
            $response.Close()
            # download file
            $destination = (Get-Item -Path ".\" -Verbose).FullName
            if ($FolderPath) { $destination = $FolderPath }
            if ($destination.EndsWith('\')) {
                $destination += $filename
            } else {
                $destination += '\' + $filename
            }
            $webclient = New-Object System.Net.webclient
            $webclient.downloadfile($fUri.AbsoluteUri, $destination)
            write-host -ForegroundColor DarkGreen "downloaded '$($fUri.AbsoluteUri)' to '$($destination)'"
        } catch {
            write-host -ForegroundColor DarkRed $_.Exception.Message
        }  
    }  
}  

Verwenden Sie dies, um die Datei in den aktuellen Ordner herunterzuladen:

Get-FileFromUri http://example.com/url/of/example/file  

Oder um die Datei in einen bestimmten Ordner herunterzuladen:

Get-FileFromUri http://example.com/url/of/example/file  C:\example-folder  
user25986
quelle
2

Die folgende Funktion erhält eine URL.

function Get-URLContent ($url, $path) {
  if (!$path) {
      $path = Join-Path $pwd.Path ([URI]$url).Segments[-1]
  }
  $wc = New-Object Net.WebClient
  $wc.UseDefaultCredentials = $true
  $wc.Proxy.Credentials = $wc.Credentials
  $wc.DownloadFile($url, $path)
}

Einige Kommentare:

  1. Die letzten 4 Zeilen werden nur benötigt, wenn Sie sich hinter einem authentifizierenden Proxy befinden. Für den einfachen Gebrauch (New-Object Net.WebClient).DownloadFile($url, $path)funktioniert gut.
  2. Der Pfad muss absolut sein, da der Download nicht in Ihrem aktuellen Verzeichnis erfolgt. Relative Pfade führen dazu, dass der Download irgendwo verloren geht.
  3. In diesem if (!$path) {...}Abschnitt wird der einfache Fall behandelt, in dem Sie die Datei nur unter Verwendung des in der URL angegebenen Namens in das aktuelle Verzeichnis herunterladen möchten.
Paul Moore
quelle
1

Verwenden Sie die Windows 10-Bash-Shell, die wget enthält, sobald die Windows-Funktion eingerichtet ist.

So installieren Sie die Ubuntu-Bash-Shell unter Windows:

YouTube: Bash unter Ubuntu unter Windows ausführen!

Windows-Subsystem für Linux-Dokumentation

Miloud Eloumri
quelle
1
Erwägen Sie, dieser Antwort einen zitierten Verweis hinzuzufügen, um zu bestätigen, was Sie für den Fall angeben, dass der Link jemals stirbt, damit der Inhalt der Antwort weiterhin verfügbar ist, der derzeit gemäß Ihrem Vorschlag nur über diesen Link verfügbar ist.
Pimp Juice IT
0

Wenn Ihr Windows neu genug ist (wie Version 1809 oder neuer), ist eine "echte" Locke verfügbar. curl hat die Kommandozeilenoption "-O" (Großbuchstabe O; Kleinbuchstabe macht das nicht!) Die Option "-O", alternativ "--remote-name" teilt curl mit, dass die gespeicherte Datei Gleicher Name wie der Dateinamen-Teil der URL.

Man muss dies als "curl.exe" starten, um es vom Alias ​​"curl" für "Invoke-WebRequest" zu unterscheiden. Im Übrigen funktioniert es in cmd.exe ohne Änderungen.

Verwenden Sie das gleiche Beispiel wie in einer anderen Antwort hier

curl.exe -O http://demo.mediacore.tv/files/31266.mp4

(Die Seite erlaubt mir nicht, dies als Kommentar hinzuzufügen, da ich dafür anscheinend mehr "Ansehen" brauche - damit es eine neue Antwort bekommt.)

Dweia
quelle
0

Invoke-WebRequest mit dem Parameter -outfile erwartet eine Zeichenfolge. Wenn Ihr Dateiname also mit einer Zahl beginnt und nicht in Anführungszeichen steht, wird keine Ausgabedatei erstellt.

z.B. Invoke-WebRequest -Uri "http://www.google.com/" -outfile "2.pdf"

Dateinamen, die mit einem Buchstaben beginnen, sind davon nicht betroffen.

Zimba
quelle
Diese Lösung wird in anderen Antworten erwähnt ( wgetist ein Alias ​​von Invoke-WebRequestund eine ähnliche wie oben)
Bertieb
Der Sinn der Antwort war es, die Note zu betonen. In keiner der Antworten wird aufgrund des Syntaxfehlers eine Datei erstellt.
Zimba
Das sollte wirklich ein Kommentar zu der anderen Antwort sein
Bertieb
Diese Antwort ist weder in anderen Antworten enthalten noch der obigen ähnlich.
Zimba
-1

Dies sollte funktionieren, damit Sie die nicht vom Browser initialisierten Dinge umgehen können. Beachten Sie den Parameter "-UseBasicParsing".

Invoke-WebRequest http://localhost -UseBasicParsing
Joe Healy
quelle
(1) Was ist "das ohne Browser initialisierte Zeug"? (2) Beachten Sie, dass die akzeptierte Antwort bereits erwähnt -UseBasicParsing.
Scott