你是否需要从网络上下载文件,但讨厌不断点击链接?如果你的工作经常需要从网络上下载文件,你可能希望自动化这个任务。为什么不使用 PowerShell 来下载文件,就像使用 PowerShell wget 的替代方法一样呢?
Windows PowerShell 和 PowerShell 都具备文件下载功能。使用 PowerShell 下载文件只需要知道要使用哪些 cmdlet 和 .NET 类以及如何使用它们。
在本文中,你将学习使用 PowerShell 从网络上下载文件的各种方法。
先决条件
由于这是一篇“边做边学”的文章,有一些先决条件,以确保你能够按照示例进行操作。以下是基本要求。
- A computer that is running on Windows 10 or higher. This computer is where you will run the scripts/commands featured in this article.
- Windows PowerShell 5.1 或 PowerShell 7.1(推荐)。
- Windows 10 已经包含了 Windows PowerShell 5.1。
- A web site that hosts the files to download.
- 对于非身份验证的文件下载,可以考虑使用免费的 Tele2 Speedtest 网站。
- 如果你想进行带有授权的文件下载测试,可能需要构建自己的 HTTP 文件服务器。一个免费的 HTTP 文件服务器的示例是 HFS by Rejetto。
使用 PowerShell 从 URL 下载文件的四种方法
有四种方法可以使用 PowerShell 下载文件,这些方法不依赖于第三方工具。它们分别是:
Invoke-WebRequest
Invoke-RestMethod
Start-BitsTransfer
- .NET WebClient类。
无论您使用这四种方法中的哪一种,使它们工作的逻辑和组件都是相同的。必须有一个指向文件位置的源URL和保存下载文件的目标路径。如果Web服务器要求,您还需要输入凭据。
接下来的章节将展示这四种方法的每一种。最后,您可以自行决定在使用PowerShell下载文件时采用哪种方式。
使用Invoke-WebRequest作为PowerShell的wget替代方法
在PowerShell中下载文件的第一种方法是使用Invoke-WebRequest
cmdlet。也许是本文中最常用的cmdlet,Invoke-WebRequest
可以下载HTTP、HTTPS和FTP链接。
无论源位置是否需要用户登录,Invoke-WebRequest
cmdlet都可以处理带有凭据的请求。
为了下载一个文件,下面的语法显示了实现所需结果的最小参数。
例如,下面的代码从一个网站下载名为10MB.zip的文件。然后将下载的文件保存到C:\dload\10MB.zip。您可以将下面的代码复制并粘贴到您的PowerShell会话中进行测试。
下面的演示展示了在PowerShell中运行上述代码后的预期结果。如你所见,文件下载成功。

如果源文件要求进行身份验证才能访问怎么办?例如,下面的代码从一个需要用户登录的私有网站下载文件。
然而,由于未经授权访问,下载失败了。

如果需要进行身份验证,你应该使用-Credential
参数为请求添加凭据。下面代码中的第一行会提示你输入凭据(用户名和密码),并将其存储到$credential
变量中。
下面的演示展示了当你在PowerShell中运行上述代码时会看到的结果。如你所见,Get-Credential
命令提示了一个PowerShell凭据请求。这次,使用凭据和Invoke-WebRequest
成功进行了下载。

相关: 使用PowerShell的Get-Credential命令和所有与凭据相关的事项
在使用Invoke-WebRequest时,要注意解析错误
A crucial thing to remember when using Invoke-WebRequest
in Windows PowerShell is that, by default, this cmdlet uses the Internet Explorer engine to parse data. The error below may happen when using Invoke-WebRequest
on computers without the Internet Explorer in it.
你需要重新发送命令,但这次要包括-UseBasicParsing
开关。
在Windows PowerShell中,可能会收到错误消息:无法解析响应内容,因为Internet Explorer引擎不可用,或者Internet Explorer的首次启动配置未完成。请指定UseBasicParsing参数并重试。
从PowerShell Core 6.0开始,Invoke-WebRequest cmdlet只使用基本解析。因此,-UseBasicParsing参数不再必要。
使用Invoke-RestMethod
Invoke-RestMethod cmdlet更适合向RESTful web服务发送HTTP或HTTPS请求。此cmdlet更适用于与REST API(如Microsoft Graph API)交互的请求。
当涉及直接从Web下载文件时,Invoke-RestMethod是一个很好的选择。不要被误导以为有什么不同。在从直接的Web链接下载文件时,使用Invoke-RestMethod和Invoke-WebRequest没有太大区别。
使用Invoke-RestMethod下载文件
要使用Invoke-RestMethod下载文件,请使用下面的语法。您会注意到,该命令使用与Invoke-WebRequest相同的参数。
在下面的示例代码中,文件从$source变量中的URL值下载,然后保存到$destination变量中定义的路径中。
如果源需要身份验证,您可以使用 -Credential
参数传递凭据。下面的示例会提示您输入凭据,并将其存储到变量 $credential
中,然后将 $credential
变量的值传递给 -Credential
参数。
另外,由于文件链接是一个HTTP源而不是HTTPS,这意味着您正在发送未加密的身份验证信息。通常情况下,为了安全起见,应避免使用HTTP源。但如果您必须使用HTTP源,您需要在命令中添加 -AllowUnencryptedAuthentication
开关。
使用 Start-BitsTransfer
Start-BitsTransfer
是专门用于在客户端和服务器计算机之间传输文件的。这个PowerShell cmdlet 依赖于 Windows 操作系统本身的 Background Intelligent Transfer Service(BITS)。
由于 Start-BitsTransfer
需要 BITS 才能工作,这意味着这个 cmdlet 在非 Windows 计算机上不可用。但另一方面,Start-BitsTransfer
本身享受了 BITS 的好处。其中一些好处包括:
- 网络带宽和使用情况的感知。
- 中断处理(续传、自动续传、暂停等)
- 作为后台作业下载多个文件。
- 能够设置下载作业的优先级。
下载文件
在PowerShell中使用Start-BitsTransfer
下载文件的基本方法是指定源和目标。使用下面的脚本,您只需要根据您的要求更改$source
和$destination
的值。
从下面的演示中可以看到,文件被下载到路径c:\dload\100MB.zip。

假设未指定目标,则
Start-BitsTransfer
将文件下载并保存到当前工作目录。例如,如果您从C:\dload运行Start-BitsTransfer
,该文件将下载到同一目录。
对于需要身份验证的下载,Start-BitsTransfer
有一个-Credential
参数,接受一个PSCredential对象。
下载多个文件
为了演示下载多个文件,您需要创建一个包含两列的CSV文件。将文件命名为filelist.txt。第一列应包含源链接,而第二列必须包含目标路径。文件内容如下所示。
相关:使用Import-Csv在PowerShell中管理CSV文件
一旦CSV文件准备好,使用下面的命令开始文件下载。该命令使用Import-Csv
导入CSV文件,并将内容传递给Start-BitsTransfer
。
请参考下面的演示,了解上面的代码如何工作。如您所见,下载开始,并且您可以看到下载进度。在下载过程中,PowerShell提示符不可用。

假设您想要将下载过程作为后台作业启动。要这样做,您只需在Start-BitsTransfer
命令的末尾添加-Asynchronous
开关。
最初,每个作业的状态将显示为“connecting”(连接中)。下面的截图显示了每个文件下载的作业ID。

现在您已经开始了下载过程,您将想要检查下载是否已完成。要检查下载作业的状态,请使用Get-BitsTransfer
cmdlet。如下所示,下载作业的状态已更改为“Transferred”(已传输)。

使用WebClient类和HttpClient类(.NET框架)
PowerShell基于.NET,并且其本质使其能够利用.NET本身的功能。在PowerShell中,有两个.NET类可用于下载文件:WebClient和HttpClient。
如果您想以更多的开发和技术方式了解这两个.NET类,您可以从以下开始→ 何时使用WebClient vs. HttpClient vs. HttpWebRequest。在下一节中,您将学习如何在PowerShell中使用WebClient和HttpClient从网络下载文件。
使用System.Net.WebClient下载文件
要使用WebClient类,您需要将一个对象初始化为System.Net.WebClient
类型。在下面的示例中,$webClient
是新的System.Net.WebClient
对象。然后,使用DownloadFile()
方法开始从源下载文件。
请复制下面的代码并在您的PowerShell会话中运行以进行测试。请注意,除非出现错误,否则您将在屏幕上看不到任何进度或输出。但是,PowerShell提示符将被锁定,直到下载完成。
如果源文件需要身份验证才能下载,您可以使用下面的代码。第一行提示输入凭据,并将其存储在变量$credentials
中。然后,在文件下载请求中包含$credential
的值。
根据这个Microsoft文档:“我们不建议您在新的开发中使用WebClient类。相反,使用System.Net.Http.HttpClient类。”
看起来WebClient类已经过时了,Microsoft推荐的新类是HttpClient类。不过,不用担心。下一节将介绍如何在PowerShell中使用HttpClient类下载网络文件。
使用System.Net.Http.HttpClient下载文件
与WebClient类一样,您需要首先创建System.Net.Http.HttpClient
。使用下面的代码从$source
下载文件到$destination
。请参考每行代码上面的注释,了解每行代码的作用。
以下代码是实时的,您可以在 PowerShell 会话中运行它进行测试。
在需要身份验证的文件下载情况下,您需要将凭据添加到 HttpClient 对象中。要将凭据包含到文件下载请求中,请创建一个新的 System.Net.Http.HttpClientHandler
对象以存储凭据。
您可以复制以下代码并在 PowerShell 中运行进行测试。或者您也可以将其作为 PowerShell 脚本运行。在此示例中,代码保存为 download-file.ps1。
下面的演示展示了运行PowerShell脚本下载文件的结果。
开始时,目录中只有脚本文件。会提示输入用户名和密码。然后,脚本开始下载文件。下载完成后,你可以看到新文件已经在目标目录中。

结论
Windows PowerShell和PowerShell Core都具备内置的文件下载功能,可作为PowerShell wget的替代品!无论是下载受密码保护的资源、单个文件还是多个文件,PowerShell都为你提供了解决方案。
本文介绍的文件下载方法适用于Windows PowerShell和PowerShell Core。这意味着这些方法适用于Windows和非Windows系统,但不包括Start-BitsTransfer
。
由于PowerShell不仅仅是一个命令提示符,你可以将所学内容转化为脚本。这对你来说意味着自动化的机会。不再需要手动复制URL、点击链接和等待下载。
Source:
https://adamtheautomator.com/powershell-download-file/