PowerShellでは、.NET Frameworkが提供する基本クラスライブラリを自由にスクリプトコードから利用できる。WebClientクラスを利用すれば、インターネット上のファイルをアクセスしたり、ダウンロードしたりできる。
対象ソフトウェア:PowerShell
PowerShellの注目すべき特徴の1つとして、.NET Frameworkで提供する標準的なクラスライブラリを自由に利用できるという点が挙げられる。これによって、PowerShellスクリプトではVisual BasicやC#と限りなく同等の操作を行うことが可能になるわけだ。
本稿では、.NET Frameworkが提供する基本クラスライブラリを利用して、あらかじめ指定したURLからファイルを一括ダウンロード、所定のフォルダに保存する方法について紹介する。ネットワーク経由でファイルを取得するWebClientクラス(System.Net名前空間)の基本的な使い方を、サンプルスクリプトを通じて理解してみよう。
PowerShellを利用するには、あらかじめシステムにユーザー自身がインストールしておく必要があります。具体的なインストール方法については「PowerShellをインストールする」を参照してください。
まずはテキストエディタを開き、以下のコードを入力する。なお「#〜」で始まる行は、コードの意味を解説するためのコメント部分なので省略してもよい。コメントにはスクリプトの簡単な説明を入れておいた。
# パラメータとして、ファイルを保存するパス、ダウンロードファイル・リストのファイル名を宣言
Param([String]$path='C:\tmp', [String]$file='list.dat')
# ファイルをダウンロードするためのWebClientオブジェクトを生成
$cli = New-Object System.Net.WebClient
# ファイルリストから順にURLを抽出
foreach($url in Get-Content $file){
# 取り出したURLからファイル名を取り出し、変数$fileにセット
$uri = New-Object System.Uri($url)
$file = Split-Path $uri.AbsolutePath -Leaf
# 指定されたURLからファイルをダウンロードし、同名のファイル名で保存
$cli.DownloadFile($uri, (Join-Path $path $file))
http://ftp.riken.jp/net/apache/commons/cli/binaries/commons-cli-1.1.zip
http://www.meisei-u.ac.jp/mirror/apache/dist/commons/beanutils/binaries/commons-beanutils-1.8.0-BETA.zip
http://ftp.kddilabs.jp/infosystems/apache/commons/collections/binaries/commons-collections-3.2.zip
PowerShellスクリプトの実行ファイルは拡張子を「.ps1」とする必要がある。ファイル名自体はなんでも構わないが、ここでは「DownloadFile.ps1」という名前で保存しておこう。
また、list.datの方はDownloadFile.ps1から読み込むダウンロード対象のファイルのリスト(テキストファイル)である。ここでは適当なURLをいくつか指定しているが、適宜、自分の用途に合わせて内容は変更してほしい。
コード全体の流れについてはリスト内のコメントをご覧いただくとして、以下ではいくつか重要なポイントにフォーカスしてみよう。
まずは、ダウンロードファイルのリストを定義したlist.datを読み込む必要がある。
このような改行区切りの情報を読み込むために、.NET Frameworkで提供するクラスライブラリを利用することも可能であるが、PowerShell標準のGet-Contentコマンドレットがより手軽に使用できる。Get-Contentコマンドレットの基本的な構文は、以下のとおり。
Get-Content <ファイルのパス>
Get-Contentコマンドレットはファイルの内容を改行単位に読み込み、結果を文字列配列として返す。つまり、ここではGet-Contentコマンドレットによって得られた読み込み内容(=list.datで定義されたURLの配列)を、foreachループで順番に取得/処理しているというわけだ。
本サンプルでは、ダウンロードしたファイルをファイルシステムに保存する際に、オリジナルのファイル名を使用している。そのために、まずはもともとのURLからファイル名だけを取り出す必要がある。URLからファイル名だけを取り出すには、いくつかの方法があるが、ここでは.NET Frameworkが提供するUriクラス(System名前空間)とPowerShell標準のSplit-Pathコマンドレットを使用することにしよう。
Uriクラスのコンストラクタには、元となるURL(文字列)を指定すればよい。Uri.AbsolutePathプロパティで「/net/apache/commons/cli/binaries/commons-cli-1.1.zip」のような絶対パスを取得できるので、あとは、ここからファイル名の部分を取り出すだけだ。ファイル名を取り出すには、Split-Pathコマンドレットで-Leafオプションを指定すればよい(Split-Pathコマンドレットについては、後日、別稿「PowerShellでパスを操作する方法」で紹介する予定だ*1)。
*1 取得した変数$urlを直接にSplit-Pathコマンドレットに渡せばよいと思われるかもしれないが、これはできない。Split-Pathコマンドレットで絶対URLを処理しようとした場合にはエラーとなる。
インターネット上のコンテンツ(ここでは指定された「.zip」ファイル)を取得するのは、.NET Frameworkで提供されているWebClientクラス(System.Net名前空間)の役割だ。
本サンプルプログラムでは、WebClientクラスのDownloadFileメソッドを利用して、指定されたURLから「.zip」ファイルを取得している。DownloadFileメソッドの一般的な構文は次のとおりである。
<WebClientオブジェクト>.DownloadFile(<ダウンロードするファイルのURL>, <保存先のパス>)
本サンプルでは、第1引数としてUriオブジェクトを指定しているが、絶対URLを文字列として指定しても構わない。第2引数には、保存先のパスを指定する。保存先のパスを生成するには、引数$pathと先ほどのSplit-Pathコマンドレットで生成したファイル名とをJoin-Pathコマンドレットで結合すればよい(Join-Pathコマンドレットについては今後別TIPSで紹介予定)。
DownloadFile.ps1を実行するには、PowerShellのプロンプトを開いたうえで、以下のようにコマンドを実行すればよい(カレントフォルダにスクリプトとlist.datファイルが保存されているものとする*2)。
PS > ./DownloadFile.ps1
commons-cli-1.1.zipをダウンロード完了しました。
commons-beanutils-1.8.0-BETA.zipをダウンロード完了しました。
commons-collections-3.2.zipをダウンロード完了しました。
*2 PowerShellでスクリプトファイルを実行する場合には、あらかじめいくつかの設定を行っておく必要がある。詳細については、別稿「Windows PowerShellコマンド&スクリプティング入門(後編)」も参照いただきたい。
上のような結果が表示され、所定のフォルダ(ここでは「c:\tmp」)に指定したファイルが保存されていれば成功だ*3。
*3 本サンプルではフォルダ/ファイルの存在チェックなどは行っていないため、リストファイルや保存先のファイルが存在しない場合は正しく動作しないので、注意すること。
なおここではDownloadFile.ps1の引数をすべてデフォルトのまま使用しているが、もちろん以下のように指定してもよい。
PS> ./DownloadFile.ps1 c:\ data.txt
この場合、data.txtで指定したリストの内容に従って、ダウンロードしたファイルが「c:\」フォルダに保存される。
■この記事と関連性の高い別の記事
Copyright© Digital Advantage Corp. All Rights Reserved.