Scott's Blog

学则不固, 知则不惑

0%

PowerShell 通过 Http, Https, Ftp 下载文件

利用 PowerShell 发起请求,不仅可以下载文件,还可以利用管道对文件进行解析,这一点比 CMD 命令行和 Linux 下的 wget 还要好用。

内网环境下

如果你工作的环境主要是通过 Server Message Block (SMB) 协议来传输文件,那么可以直接在 powershell 中使用 copy-item 命令:

1
Copy-Item -Source \\server\share\file -Destination C:\path\

如果你在公司的内网(域环境)下,那么这个命令挺适合你,如果你是要下载外网或者 Internet 上面的数据,事情就变得复杂一点了。

Internet

任意版本 powershell

如果你用的power shell 2.x 的版本,你需要使用 new-object 配合 System.Net.WebClient 来实现:

1
2
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile("https://www.wittyfans.com/file","C:\path\file")

powershell 版本3.x 以上

如果是 powershell 3.x, 可以用 Invoke-WebRequest命令。Invoke-WebRequest 和Linux其实还有一些关系。它比 wget 还要好用一些,因为它不仅可以下载,而且可以对文件进行解析。

使用:

1
Invoke-WebRequest -Uri "http://www.wittyfans.com" -OutFile "C:\path\file"
  • 默认会下载这个网页,所以如果你指定的下载路径只是一个文件夹,powershell会提示找不到路径,这时候你需要指定路径加文件名.
  • 如果你省略本地路径,则powershell会默认使用脚本所在目录的路径

举例:

下载sublime:

1
Invoke-WebRequest -uri "https://download.sublimetext.com/Sublime%20Text%20Build%203207%20x64%20Setup.exe" -OutFile "C:\Users\wittyfans\Desktop\sublime.exe"

Invoke-WebRequest 默认把下载的东西传输给管道,如果你需要保存文件,必须要指定 outfile 参数。而且你还可以在管道中后面去分析这个文件,如果你传输的是二进制文件,power shell会默认以文本的方式处理,这时候你就没办法分析了,不过你可以增加一个参数,只分析文本内容,你需要这样使用:

1
Invoke-WebRequest "http://www.wittyfans.com" | Select-Object -ExpandProperty Content | Out-File "file"

如果你想要保存所有管道中的文件:

1
Invoke-WebRequest "http://www.wittyfans.com" -OutFile "file" -PassThru | Select-Object -ExpandProperty Content

验证

如果你的下载需要验证身份,powershell不会提示你,除非你指定了用户名,此时powershell会提示你输入密码:

1
2
3
4
5
6
7
# 1
Invoke-WebRequest -Uri https://www.wittyfans.com/ -OutFile C:"\path\file" -Credential "yourUserName"

# 2
$Credentials = Get-Credential
Invoke-WebRequest -Uri "https://www.wittyfans.com" -OutFile "C:\path\file" -Credential $Credentials

你可以使用-UseDefaultCredentials 参数来使用当前用户的凭据,这样就可以省略 Credential 参数。

也可以使用弹窗来要求输入密码:

1
2
3
4
$client = new-object System.Net.WebClient
$client.Credentials = Get-Credential
$client.DownloadFile("http://i.imgur.com/JnphmRt.jpg","C:\Users\Fatima Wahab\Desktop\cat.jpg")

注意检查资源的路径是对的,如果你的路径是该网站的首页,那么就会出错。

为了确保安全,建议你使用 https 验证,如果只是基本的验证方式,你的密码可能会被抓包分析出来。

这种下载的验证方式之适用于那些服务器自己管理凭据的情况,现今很多的公司都是用 content management system (CMS) 来验证用户,这时候你就需要使用powershell填写一些表单再提交,用我写的一个函数来举个例子,这个函数只是验证身份,没有下载的动作:

1
2
3
4
5
6
7
8
9
10
11
12
13
Function login-in($userName,$userPassWord){
# 请求并保存session
$R=Invoke-WebRequest "the_url" -SessionVariable fb

# 填写表单信息
$Form = $R.Forms[0]
$Form.Fields["account"]=$userName
$Form.Fields["password"] = $userPassWord
$Form.Fields["signIn"] = "Sign+in"

# 提交
$R=Invoke-WebRequest -Uri ("the_url" + $Form.Action) -WebSession $FB -Method POST -Body $Form.Fields
}

如果想要安全一些,最好不要使用FTP的方式,建议用SFTP 或者 SCP,但 Invoke-WebRequest 不支持这些协议,你可以安装一些第三方的库来实现,现在已经有相关的库实现了。

Reference