Functions/Invoke-Download.ps1

[CmdletBinding()]
param (
  [Parameter(Mandatory)]
  [uri[]]$Uri,

  [ValidateNotNullOrEmpty()]
  [string]$OutDir = './',

  [ValidateNotNullOrEmpty()]
  [string]$UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',

  [string]$Referer,

  [string[]]$HrefRegexArray,

  [int[][]]$HrefIndexesArray
)

if ($HrefRegexArray) {
  if ($Uri.Count -ge 2) {
    throw '複数URLからのスクレイピングには対応していません。'
  }

  $downloadUris = Get-Href -Uri $Uri[0] -HrefRegexArray $HrefRegexArray -HrefIndexesArray $HrefIndexesArray -UserAgent $UserAgent
}
else {
  $downloadUris = $Uri
}

if (!(Test-Path -LiteralPath $OutDir)) {
  mkdir $OutDir | Out-Null
}

$OutDir = Convert-Path -LiteralPath $OutDir

$outPathArray = @()

foreach ($downloadUri in $downloadUris) {
  $outName = Get-FileName -Uri $downloadUri -UserAgent $UserAgent -Referer $Referer
  $outPath = Join-Path $OutDir $outName

  $WebClient = New-Object System.Net.WebClient

  $WebClient.Proxy = $null

  $WebClient.Headers.Add('User-Agent', $UserAgent)
  if ($Referer) {
    $WebClient.Headers.Add('Referer', $Referer)
  }

  Write-Host ('URL {0} からファイル {1} をダウンロードします。' -f $downloadUri.AbsoluteUri, $outPath) -ForegroundColor Cyan

  $WebClient.DownloadFile($downloadUri, $outPath)

  $outPathArray += $outPath
}

if ($outPathArray) {
  return $outPathArray
}
else {
  throw '何もダウンロードされませんでした。'
}
<#
  .SYNOPSIS
  ダウンロードリンク(href)を取得するスクレイピング機能あり。ファイル名は自動で取得します。
  .DESCRIPTION
  ファイルをダウンロードします。
  .PARAMETER Uri
  ダウンロードURIもしくはそれが載っているページのURIを指定します。
  .PARAMETER OutDir
  ファイルの出力先ディレクトリを指定します。
  .PARAMETER UserAgent
  HTTPリクエストの為のユーザエージェントを指定します。
  .PARAMETER Referer
  HTTPリクエストの為のリファラを指定します。
  .PARAMETER HrefRegexArray
  -Uriで指定したページからダウンロードリンクであるhrefをスクレイピングする為の正規表現を指定します。
  スクレイピングしたURLで更にスクレイピングする場合は配列で指定します。
  .PARAMETER HrefIndexesArray
  正規表現と一致したhrefの内、何番目のものを取得するかを指定します。
    全てのリンクの場合は0
    最後のリンクの場合は-1
    最初のリンクの場合は1
  複数のhrefのインデックスを指定するには整数の配列で指定します。
  スクレイピングしたリンクで更にスクレイピングする場合は整数の配列の配列を指定します。
  ex. @(@(2),@(3,4))とすると、最初のスクレイピングでは-Uriのページで2番目のリンクを取得し、次のスクレイピングでは取得したリンクのページで3番目と4番目のリンクを取得します。
  .INPUTS
  なし
  .OUTPUTS
  System.String
    ダウンロードしたファイルのフルパスを返します。
  .EXAMPLE
  PS C:\>Invoke-Download -Uri 'https://www.gimp.org/downloads/' -OutDir $env:TMP -HrefRegexArray '//download\.gimp\.org/mirror/pub/gimp/.+/windows/gimp.+setup.*\.exe' -HrefIndexesArray 0
 
  この例では、GIMPのインストーラーを取得します。
  .LINK
#>