作成 2010.01.05
更新 2011.11.27
PowerShell で wget もどき
Windows Server 2008 R2 Core Install でファイルをダウンロードする方法がなかったので。
Function Get-Bytes
{
param([string]$str)
if($str)
{
  $len = $str.length
  if($len -ne $null)
  {
    [byte[]] $data = @()
    for($i=0; $i -lt $len; $i++)
    {
      $data += [byte] [char] $str[$i]
    }
    return $data
  }
  return $null
}
else
{
  Write-Output "Get-Bytes <string>"
}
}

Function wget
{
param([string[]]$url)
if($url)
{
  $message = "/"
  $filename = "index.html"
  $hostname = ""
  $port = 80
  $buffer_size = 16384
  if($url[0] -match "^https?://([^:/]+):?([0-9]*)(/?.*)")
  {
    if($matches[1].length -gt 0)
    {
      $hostname = $matches[1]
    }
    else
    {
      Write-Output "Can't Get hostname."
      return $null
    }
    if($matches[2] -gt 0)
    {
      $port = [int] $matches[2]
    }
    if($matches[3].length -gt 0){
      $message = $matches[3]
      if($message -match "[^/\?;\*\\]+$")
      {
        $filename = $matches[0]
      }
    }
  }
  else
  {
    Write-Error "Can't Get"
    return $null
  }
  if($url[1].length -gt 0)
  {
    $filename = $url[1]
  }
  $filename = $filename.Replace("%20"," ")
  $tempname = $filename + ".tmp"
  $newline = [char] 13 + [char] 10
  $message = "GET " + $message + " HTTP/1.1" + $newline
  $message += "User-Agent: PowerShell/1" + $newline
  $message += "Accept: */*" + $newline
  $message += "Host: " + $hostname + $newline
  $message += "Connection: close" + $newline
  $message += $newline
  # $message

  $cl = New-Object System.Net.Sockets.TCPClient($hostname, $port)
  if($cl -ne $null)
  {
    $stream = $cl.GetStream()
    $mybytes = Get-Bytes $message
    $stream.Write($mybytes,0,$mybytes.length)
    $counter = 0
    while(!$stream.DataAvailable)
    {
      Start-Sleep -Milliseconds 200
      $counter++
      if($counter -gt 1500)
      {
        Write-Error "Timeout: 30 sec."
        break
      }
    }

    $head_data = ""
    while($stream.DataAvailable)
    {
      $head_data += [char] $stream.ReadByte()
      if(($head_data -match "\r\n\r\n$") -or ($head_data -match "\n\n$") -or ($head_data -match "\r\r$"))
      {
        break
      }
    }
    "------------- Header Begin -------------"
    $head_data.Trim()
    "------------- Header End   -------------"
    [Int64] $content_length = 2147483647
    if($head_data -match "[\r\n]Content-Length: ?([0-9]+)[\r\n]")
    {
      $content_length = $matches[1]
    }
    $location = ""
    if($head_data -match "[\r\n]Location: ?(\S+)[\s\r\n]")
    {
      $location = $matches[1]
    }
    
    if($content_length -lt 1)
    {
      if($location.length -gt 0)
      {
        Write-Output ("Get: " + $location)
        if($url[1].length -gt 0)
        {
          wget($location, $filename)
        }
        else
        {
          wget($location)
        }
      }
      else
      {
        Write-Warning "Nothing Content"
      }
      return $null
    }
    "File-Name: " + $filename

    [Byte[]] $body = New-Object byte[] $buffer_size
    [Int64] $total_size = 0
    $ProgressPreference = "Continue"
    Write-Progress "Download Status" ("" + $total_size + "/" + $content_length)
    while($total_size -lt $content_length)
    {
      $counter = 0
      while(!$stream.DataAvailable)
      {
        Start-Sleep -Milliseconds 200
        $counter++
        if($counter -gt 1500)
        {
          Write-Output "Timeout: 30 sec."
          $content_length = 0
          break
        }
      }

      $len = [int] $stream.read($body,0,$buffer_size)
      Add-Content -Encoding Byte -Path $tempname -Value $body[0..($len-1)]
      $total_size += $len
      Write-Progress "Download Status" ("" + $total_size + "/" + $content_length)
    }
    if(Test-Path $filename)
    {
      Remove-Item $filename
    }
    Rename-Item $tempname $filename
    $stream.Close()
    $cl.Close()
    return "Total Size: " + $total_size
  }
  else
  {
    Write-Error "接続に失敗しました"
  }
}
else
{
  Write-Output "wget <url_string> [, save_filename]"
}
}
タグ: PowerShell

©2004-2017 UPKEN IPv4