PowerShell Invoke-WebRequest,如何自动使用原文件名?

问题描述 投票:0回答:5

如何使用 Invoke-WebRequest 下载文件但自动使文件名与通过浏览器下载的文件名相同?如果不手动指定文件名,我还没有找到使

-OutFile
工作的方法。我对这涉及其他几行代码很好。

一个好的解决方案将:

  • 即使文件名不在请求 URL 中也能正常工作。例如,下载 Visual Studio x64 远程调试工具的 URL 是
    http://go.microsoft.com/fwlink/?LinkId=393217
    但它下载文件
    rtools_setup_x64.exe
    .
  • 在写入磁盘之前不要将整个文件保存到内存中,除非这是 Invoke-WebRequest 已经使用 -OutFile 参数(?)所做的事情

谢谢!

powershell
5个回答
13
投票

对于给定的示例,您将需要获取重定向的 URL,其中包括要下载的文件名。您可以使用以下功能来执行此操作:

Function Get-RedirectedUrl {

    Param (
        [Parameter(Mandatory=$true)]
        [String]$URL
    )

    $request = [System.Net.WebRequest]::Create($url)
    $request.AllowAutoRedirect=$false
    $response=$request.GetResponse()

    If ($response.StatusCode -eq "Found")
    {
        $response.GetResponseHeader("Location")
    }
}

然后是从响应 URL 的末尾解析文件名的问题(System.IO.Path 中的 GetFileName 将执行此操作):

$FileName = [System.IO.Path]::GetFileName((Get-RedirectedUrl "http://go.microsoft.com/fwlink/?LinkId=393217"))

那将离开

$FileName = rtools_setup_x64.exe
,你应该可以从那里下载你的文件。


7
投票

试试这个方法(可能不总是有效,因为文件名可能不在响应头中)

  1. 调用 Invoke-WebRequest 获取结果。然后您可以检查结果以查看标头中的内容。
  2. 从响应标头中获取文件名(这可能在 Headers.Location 或其他地方。当我运行查询以查找正在排除故障的 URL 时,我在 Headers["Content-Disposition"] 中找到了它,并且看起来像
    inline; filename="zzzz.docx"
  3. 根据名称新建一个文件,并将内容写入该文件

这里是代码示例:

$result = Invoke-WebRequest -Method GET -Uri $url -Headers $headers

$contentDisposition = $result.Headers.'Content-Disposition'
$fileName = $contentDisposition.Split("=")[1].Replace("`"","")

$path = Join-Path $yourfoldername $fileName

$file = [System.IO.FileStream]::new($path, [System.IO.FileMode]::Create)
$file.write($result.Content, 0, $result.RawContentLength)
$file.close()

6
投票

感谢 Ryan 我有一个半可用的功能:

Function Get-Url {
  param ( [parameter(position=0)]$uri )
  invoke-webrequest -uri "$uri" -outfile $(split-path -path "$uri" -leaf)
}

我已经能够下载的图形文件和xml文件。当我尝试下载此网页并使用 Edge 打开它时,它有时会起作用。


1
投票

我根据许多来源将其放在一起;有很多方法可以解析

Content-Disposition
标头,因此请使用适合您的方法。

初次通话:

$Response = Invoke-WebRequest $Url -Verbose

解析标题:

$FileName = $Response.Headers.'Content-Disposition'.Split('=',2)[-1]
替代方案:
# Older PowerShell versions need to load this manually:
if ($PSVersionTable.PSVersion.Major -le 5) {
  Add-Type -AssemblyName System.Net.Http
}

$FileName = [Net.Http.Headers.ContentDispositionHeaderValue]::Parse(
  $Response.Headers.'Content-Disposition').FileName

写文件:

[IO.File]::WriteAllBytes($FileName, $Response.Content)

清理:

Remove-Variable Response -Force
[GC]::Collect()

-8
投票

powershell.exe Invoke-WebRequest -Uri serverIP/file.exe -OutFile C:\Users ile.exe

© www.soinside.com 2019 - 2024. All rights reserved.