2014-04-30 23 views
2

我已经搜索了类似的东西,并且我一直在FTP下载答案中运行。这是有用的信息,但最终证明难以翻译。我找到了一个PowerShell脚本,它的工作原理,但我想知道是否可以调整我的需求。我没有太多关于PowerShell脚本的经验,但我正在努力学习。使用Powershell以专有名称下载多个文件

需求是这样的。我需要无人值守地将一系列文件下载并安装到远程机器上。这些文件通过电子邮件通过tinyurls分发。我目前将这些文件放入.txt文件,然后让powershell脚本读取列表并下载每个文件。

该项目的要求,以及为什么我转向PowerShell(而不是其他实用程序),是这些都是非常专业的机器。唯一可用的工具是嵌入Windows 7中的工具。

我遇到的困难是: 这些文件在当时下载。我想在网络服务器允许的同时获得尽可能多的下载量。 (通常为6)

当前脚本基于tinyurl创建文件名。我需要Web服务器的实际文件名。

在此先感谢您的任何建议。

下面是我目前使用的脚本。

# Copyright (C) 2011 by David Wright ([email protected]) 
# All Rights Reserved. 

# Redistribution and use in source and binary forms, with or without 
# modification or permission, are permitted. 

# Additional information available at http://www.digitalwindfire.com. 

$folder = "d:\downloads\" 
$userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1" 
$web = New-Object System.Net.WebClient 
$web.Headers.Add("user-agent", $userAgent) 


Get-Content "d:\downloads\files.txt" | 
    Foreach-Object { 
     "Downloading " + $_ 
     try { 
      $target = join-path $folder ([io.path]::getfilename($_)) 
      $web.DownloadFile($_, $target) 
     } catch { 
      $_.Exception.Message 
     } 
} 

回答

2

如果你决定在文件名之前,你应该能够得到扩充的路径做web请求(否则你将不得不作出两个Web请求,一个得到扩展路径和一个下载文件)。

当我尝试这样做,我发现,由Invoke-WebRequest cmdlet返回的Microsoft.PowerShell.Commands.HtmlWebResponseObjectBaseResponse财产有ResponseUri属性,它是我们正在寻找的扩展路径。

如果得到正确的响应,只需使用扩展路径中的名称保存该文件,如下所示(此示例代码不会查看HTTP响应代码或类似内容,但希望一切顺利):

function Save-TinyUrlFile 
{ 
    PARAM (
     $TinyUrl, 
     $DestinationFolder 
    ) 

    $response = Invoke-WebRequest -Uri $TinyUrl 
    $filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString) 
    $filepath = [System.IO.Path]::Combine($DestinationFolder, $filename) 
    try 
    { 
     $filestream = [System.IO.File]::Create($filepath) 
     $response.RawContentStream.WriteTo($filestream) 
     $filestream.Close() 
    } 
    finally 
    { 
     if ($filestream) 
     { 
      $filestream.Dispose(); 
     } 
    } 
} 

这种方法可以使用类似下面给出被调用,该$HOME\Documents\Temp文件夹存在:

Save-TinyUrlFile -TinyUrl http://tinyurl.com/ojt3lgz -DestinationFolder $HOME\Documents\Temp 

在我的电脑,可以节省一个叫robots.txt文件,从GitHub的仓库拍摄,我补偿uter。

如果您想同时下载多个文件,可以让PowerShell为您做到这一点。使用PowerShell工作流程并行功能,或者简单地为每个网址启动一个Job。下面是关于如何使用PowerShell的示例:Jobs

Get-Content files.txt | Foreach { 
    Start-Job { 
     function Save-TinyUrlFile 
     { 
      PARAM (
       $TinyUrl, 
       $DestinationFolder 
      ) 

      $response = Invoke-WebRequest -Uri $TinyUrl 
      $filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString) 
      $filepath = [System.IO.Path]::Combine($DestinationFolder, $filename) 
      try 
      { 
       $filestream = [System.IO.File]::Create($filepath) 
       $response.RawContentStream.WriteTo($filestream) 
       $filestream.Close() 
      } 
      finally 
      { 
       if ($filestream) 
       { 
        $filestream.Dispose(); 
       } 
      } 
     } 

     Save-TinyUrlFile -TinyUrl $args[0] -DestinationFolder $args[1] 
    } -ArgumentList $_, "$HOME\documents\temp" 
} 
+0

Robert,非常感谢。这正是我所期待的。还有一个问题需要补充。有没有办法添加进度指示器?这些都是相当大的文件,我不希望有人认为该程序死亡。我已经尝试添加'$ buffer'和'$ count'参数,并且该脚本可以工作,但不会显示进度' – user3590927

+0

当您将每个下载作为单独的'Job'运行时,您将在不同的'运行空间'中运行它们,必须做一些工作才能让它显示进步。我想你可以编写进度信息输出到作业中,并让脚本持续地从输出流中读取作业并更新进度条。也许有更简单的方法?然而,如何做到这一点是一个完全独立的问题,所以我建议你写一个关于这个问题的新问题,如果你在自己的尝试中遇到问题。 –

+0

您可以使用'write-Progress'来执行此操作。见:http://blogs.technet.com/b/heyscriptingguy/archive/2011/01/29/add-a-progress-bar-to-your-powershell-script.aspx –

相关问题