【 広告 】

PowerShell入門を終えたので、簡易コピーツールを作ってみました。

投稿日: 2023-04-09

thumnail

こんにちは、だしです。お元気ですか?

先日、PowerShellの学習に取り組みました。
入門を終えましたので、なにか作ろうと思い、簡易コピーツールを作成しました。
これから、その手順について記します。

コマンドの実行は、「コマンドプロンプト」にて行います。

作業環境の作成

まず、作業環境を作るために、以下のコマンドを実行します。

[コマンドプロンプト]
mkdir c:\work\sample\from
mkdir c:\work\sample\to\a001
mkdir c:\work\sample\to\a002
mkdir c:\work\sample\to\a003
echo > c:\work\sample\from\a001.txt
echo > c:\work\sample\from\a002.txt
echo > c:\work\sample\from\a003.txt
cd c:\work\sample\

作業ディレクトリ(作業フォルダ)を c:\work\sample とします。(以下、作業ディレクトリと記載)

作業環境を確認するために、以下のコマンドを実行します。

[コマンドプロンプト]
tree /f

作業ディレクトリには、以下のディレクトリがあります。

  • from ディレクトリ : コピー元ファイルがあるディレクトリです。3つのテキストファイルがあります。
  • to ディレクトリ : コピー先のディレクトリです。コピー元ファイルと同じ名前(拡張子を除く)のディレクトリがあります。

from ディレクト内の各テキストファイルを、to ディレクトリ内の同名ディレクトリにコピーするものとします。

準備ができましたので、次に進みます。

PowerShell スクリプトのテスト

作業ディレクトリにスクリプトファイルを作成します。
ファイル名は、restore.ps1 とします。

スクリプトの内容は以下のとおりです。
Write-Host コマンドレットは、画面に文字を表示させるためのものです。

restore.ps1

Write-Host "Hello."

コマンドプロンプトからスクリプトを実行してみます。

[コマンドプロンプト]
powershell .\restore.ps1

実行してみたところ、以下のエラーが発生しました。

調べてみたところ、実行ポリシーの問題であることがわかりました。
以下のように実行すると解決するようです。

[コマンドプロンプト]
powershell -ExecutionPolicy RemoteSigned .\restore.ps1

今度はうまくいきました。「Hello.」と表示されています。

毎回このコマンドを入力するのも大変なので、バッチファイルを作成します。
ファイル名は、restore.bat とします。

restore.bat

powershell -ExecutionPolicy RemoteSigned .\restore.ps1

バッチファイルの実行結果は、以下のとおりです。

スクリプトのテストはこれで完了です。
次は、スクリプトを作りこんでいきます。

PowerShell スクリプトの作成

まず、コピー元ディレクトリとコピー先ディレクトリのパスを変数に入れておきます。
そして、コピー元ディレクトリ内のテキストファイルを取得します。

Get-ChildItem コマンドレットは、指定した場所から子項目を取得するためのものです。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt

実行結果は、以下のとおりです。

次に、取得したファイルごとにコピー処理を行いたいので、繰り返しの処理を行います。
パイプラインと繰り返しにて実現します。
ForEach-Object コマンドレットは、受け取ったファイルリストの各項目に対して処理を行うためのものです。
取得したファイルの数だけ「hoge」と表示させるものとします。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt | ForEach-Object {
    Write-Host "hoge"
}

実行結果は、以下のとおりです。

次は、取得した各ファイルのフルパスとファイル名を表示させます。
取得したファイルは、「$_」で参照できます。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt | ForEach-Object {
    Write-Host "-----"
    Write-Host $_.FullName
    Write-Host $_.Name
}

実行結果は、以下のとおりです。

次は、ファイル名から拡張子を除いたものを取得します。
.Net の GetFileNameWithoutExtension メソッド を利用します。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt | ForEach-Object {
    Write-Host "-----"
    $fromFile = $_.FullName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
    Write-Host $fromFile
    Write-Host $name
}

実行結果は、以下のとおりです。

次は、コピー先ディレクトリのパスと拡張子を除いたファイル名からコピー先のファイル名のフルパス文字列を作成します。
ここでは、文字列の連結を利用します。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt | ForEach-Object {
    Write-Host "-----"
    $fromFile = $_.FullName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
    $toFile = $toDir + "\" + $name + "\" + $_.Name
    Write-Host $fromFile
    Write-Host $toFile
}

実行結果は、以下のとおりです。

コピー元ファイル名とコピー先ファイル名のフルパスが取得できたので、ファイルをコピーします。
Copy-Item コマンドレットは、ファイルやディレクトリをコピーするためのものです。

restore.ps1

$fromDir = "C:\work\sample\from"
$toDir = "C:\work\sample\to"

Get-ChildItem $fromDir\*.txt | ForEach-Object {
    $fromFile = $_.FullName
    $name = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
    $toFile = $toDir + "\" + $name + "\" + $_.Name
    Write-Host $fromFile ---> $toFile
    Copy-Item $fromFile $toFile
}

実行結果は、以下のとおりです。

最後に、ファイルのコピー結果を確認するために、以下のコマンドを実行します。

[コマンドプロンプト]
tree /f

実行結果は、以下のとおりです。

できました!

今回は、これで終了です。
ここまで読んでくださいまして、ありがとうございます。
今回の投稿が誰かの役に立てたのであれば、嬉しく思います。
また、次回お会いしましょう。