作成 2010.01.05
更新 2011.11.27
更新 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