作成 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