Windows環境におけるシステム管理や日常的な業務自動化において、ファイルやフォルダの操作は最も頻繁に行われるタスクの一つです。
PowerShellでは、これらの操作を直感的かつ強力に実行するためにCopy-ItemやMove-Itemといった標準コマンドレットが用意されています。
従来のコマンドプロンプト(cmd.exe)におけるcopyやmoveコマンドと比較して、PowerShellはオブジェクトベースの処理やパイプラインを活用した柔軟なフィルタリングが可能であり、複雑なファイル操作をわずか一行のコードで完結させることができます。
本記事では、PowerShellを用いたファイル・フォルダのコピーおよび移動の基本から、現場で役立つ実践的なテクニックまでを詳しく解説します。
PowerShellにおけるファイル操作の基本概念
PowerShellでファイルやフォルダを操作する際、中心となるのが「Item(アイテム)」という概念です。
PowerShellではファイルシステムだけでなく、レジストリや証明書ストアなども同様の階層構造として扱えるよう設計されており、それらを操作するコマンドには共通してItemという名称が含まれています。
ファイル操作において最も多用されるコマンドレットは以下の2つです。
| コマンドレット | 役割 | 主なエイリアス |
|---|---|---|
Copy-Item | ファイルやフォルダをコピーする | cp, copy |
Move-Item | ファイルやフォルダを移動する(リネームも含む) | mv, move |
これらのコマンドレットは、単一のファイルを扱うだけでなく、ワイルドカードを用いた一括処理や、後述する再帰的な処理をサポートしています。
Copy-Item コマンドレットによるファイル・フォルダのコピー
Copy-Itemは、指定したソース(コピー元)からデスティネーション(コピー先)へデータを複製するコマンドです。
単一ファイルのコピー
最も基本的な使い方は、-Pathパラメータでコピー元を指定し、-Destinationパラメータでコピー先を指定する方法です。
# 特定のファイルを別のフォルダへコピーする
Copy-Item -Path "C:\Source\sample.txt" -Destination "D:\Backup\"
上記の例では、sample.txtがD:\Backupフォルダ内にコピーされます。
もしコピー先でファイル名を変更したい場合は、パスの末尾に新しいファイル名を指定します。
# コピーと同時にファイル名を変更する
Copy-Item -Path "C:\Source\sample.txt" -Destination "D:\Backup\sample_old.txt"
フォルダ(ディレクトリ)のコピーと再帰処理
フォルダをコピーする場合、注意が必要なのが中身の扱いです。
単にフォルダを指定しただけでは、そのフォルダ自体は作成されますが、中のファイルやサブフォルダはコピーされません。中身をすべて含めてコピーするには、-Recurseパラメータを使用する必要があります。
# フォルダとその中身をすべて再帰的にコピーする
Copy-Item -Path "C:\Source\Project" -Destination "D:\Backup\" -Recurse
このコマンドを実行すると、Projectフォルダ内のすべての階層構造が維持されたままコピーされます。
上書きの制御とエラーハンドリング
コピー先に同名のファイルが存在する場合、PowerShellはデフォルトでエラーを返します。
既存のファイルを強制的に上書きしたい場合は、-Forceパラメータを付与します。
# 既存ファイルを強制的に上書きしてコピーする
Copy-Item -Path "C:\Source\config.ini" -Destination "D:\App\config.ini" -Force
逆に、誤った上書きを防ぎたい場合は、実行前に-WhatIfパラメータを付けて、どのような処理が行われるかシミュレーションすることをお勧めします。
# 実行結果をシミュレーションする(実際にはコピーされない)
Copy-Item -Path "C:\Source\*.log" -Destination "D:\LogBackup\" -Recurse -WhatIf
What if: Performing the operation "Copy File" on target "Item: C:\Source\error.log Destination: D:\LogBackup\error.log".
Move-Item コマンドレットによるファイル・フォルダの移動
Move-Itemは、ファイルを別の場所へ「移動」させるために使用します。
移動が完了すると、元の場所にあったファイルは削除されます。
ファイルの移動とリネーム
基本的な構文はCopy-Itemと同じですが、挙動が異なります。
# ファイルを別のドライブへ移動する
Move-Item -Path "C:\Data\report.pdf" -Destination "E:\Archive\"
また、PowerShellにおいて「ファイル名の変更(リネーム)」は、同一ディレクトリ内での移動として扱われます。
# 同一フォルダ内で名前を変更する
Move-Item -Path "C:\Data\old_name.txt" -Destination "C:\Data\new_name.txt"
複数ファイルの一括移動
ワイルドカードを使用することで、特定の条件に合致するファイルを一括で移動させることが可能です。
# すべてのテキストファイルをArchiveフォルダへ移動する
Move-Item -Path "C:\Data\*.txt" -Destination "C:\Data\Archive\"
この際、移動先に同名のファイルがあるとエラーになります。
Copy-Itemと同様に、-Forceを使用することで強制的に上書き移動することも可能です。
実践的な応用テクニック
基本操作を理解したところで、実務で役立つ高度なテクニックをいくつか紹介します。
ワイルドカードを活用した高度なフィルタリング
PowerShellのパス指定では、*(任意の文字列)や?(任意の一文字)を活用できます。
# 2023で始まるログファイルだけをコピーする
Copy-Item -Path "C:\Logs\2023*.log" -Destination "D:\Backup\2023_Logs\"
-Filter, -Include, -Exclude パラメータの使用
より厳密な条件指定が必要な場合は、フィルタリングパラメータを使用します。
特に-Excludeは、特定のファイルだけを除外してコピーしたい場合に非常に便利です。
# .tmpファイルを除外して、すべてのファイルをコピーする
Copy-Item -Path "C:\Source\*" -Destination "D:\Destination\" -Recurse -Exclude "*.tmp"
注意点として、-Includeや-Excludeを使用する場合、-Pathの末尾に*を付ける必要があります。
これを忘れると意図した通りに動作しないことが多いため注意してください。
パイプラインを利用した効率的な処理
PowerShellの最大の強みは、複数のコマンドを繋ぐ「パイプライン」です。
例えば、「特定のサイズ以上のファイルだけを探して移動する」といった処理も、Get-ChildItemと組み合わせることで簡単に実現できます。
# 100MB以上のファイルだけを抽出してArchiveフォルダへ移動する
Get-ChildItem -Path "C:\Downloads\" -File | Where-Object { $_.Length -gt 100MB } | Move-Item -Destination "D:\LargeFiles\"
このスクリプトの流れは以下の通りです:
Get-ChildItemでダウンロードフォルダ内のファイル一覧を取得。Where-Objectでサイズが100MBを超えるものだけに絞り込む。Move-Itemでそれらを移動する。
このように、オブジェクトのプロパティ(サイズ、更新日時など)に基づいて操作対象を動的に決定できるのが、従来のコマンドにはないPowerShellのメリットです。
トラブルシューティングと注意点
ファイル操作を自動化する際には、いくつか陥りやすい罠があります。
権限の問題と管理者実行
システムフォルダ(C:\Windows や C:\Program Files など)への書き込みや移動は、通常ユーザーの権限では制限されています。
これらの場所を操作するスクリプトを実行する場合、PowerShellを「管理者として実行」する必要があります。
権限が不足している場合、「アクセスが拒否されました」というエラーが表示されます。
パスに含まれる特殊文字の扱い
ファイル名やフォルダ名に [](大括弧)が含まれている場合、PowerShellはこれをワイルドカードパターンとして解釈しようとします。
これにより、「ファイルが存在するのに見つからない」というエラーが発生することがあります。
これを回避するには、-Pathの代わりに-LiteralPathパラメータを使用します。
# 特殊文字を含むパスを正しく扱う
$path = "C:\Data\[Reports] 2026.pdf"
Copy-Item -LiteralPath $path -Destination "D:\Backup\"
-LiteralPathを使用すると、文字列が入力した通りに解釈されるため、意図しないパターンの解析を防ぐことができます。
ネットワークパス(UNCパス)の利用
PowerShellはネットワーク上の共有フォルダもシームレスに扱えます。
# ネットワーク経由でファイルをコピーする
Copy-Item -Path "C:\LocalData\file.zip" -Destination "\\FileServer01\Public\Backup\"
ただし、ネットワーク越しのコピーでは認証情報が必要になる場合があります。
その場合は、あらかじめNew-PSDriveなどでドライブをマウントしておくか、適切な権限を持つユーザーで実行されているかを確認してください。
大量ファイルの操作におけるパフォーマンス
数万件規模のファイルをコピー・移動する場合、標準のCopy-Itemでは処理時間が長くなることがあります。
そのようなケースでは、.NETの静的メソッドを直接呼び出すことで高速化が図れる場合があります。
# .NETメソッドを使用して高速に移動する(一例)
[System.IO.File]::Move("C:\Source\huge.dat", "D:\Dest\huge.dat")
ただし、この方法はPowerShell独自の柔軟なパラメータ(-WhatIfやパイプライン連携など)が使えなくなるため、通常はCopy-Item/Move-Itemを使用し、パフォーマンスが極端に求められる場面でのみ検討するのがベストプラクティスです。
まとめ
PowerShellにおけるファイルやフォルダのコピー・移動は、システム管理の自動化を支える非常に重要な要素です。
本記事で紹介した主なポイントを振り返ります。
Copy-Itemは複製、Move-Itemは移動(リネーム)を担当する。- フォルダの中身を含めてコピーするには、-Recurseパラメータが必須である。
- 上書きが必要な場合は-Forceを使い、安全のために
-WhatIfで事前に確認する。 - パイプラインを活用することで、ファイルサイズや更新日時などの属性に基づいた高度な操作が可能になる。
- 特殊な記号を含むパスを扱う際は、
-LiteralPathの使用を検討する。
これらの基礎をマスターすることで、手作業で行っていた煩雑なファイル整理やバックアップ作業を、安全かつ効率的なスクリプトへと置き換えることができるようになります。
まずは身近なファイルのバックアップなど、簡単な操作からPowerShellの活用を始めてみてください。
