PowerShell Copy-Itemを使用してファイルを効率的にコピーする方法:包括的なガイド

ファイルのコピー。それはセクシーではありませんが、やらなければなりません。GUIではクリップボードを使用してコピー&ペーストしますが、PowerShellではCopy-Itemというコマンドレットがあります。

ファイルのコピーに関するコマンドは、すべてのシェル言語で古くから存在しています。PowerShellでは、PowerShellスクリプト内でファイルまたはフォルダをポイントAからポイントBにコピーするために、最も一般的な方法はPowerShellのCopy-Itemコマンドレットを使用することです。このコマンドレットを使用すると、フォルダ内のファイルを再帰的にコピーしたり、必要なファイルを選択するためにワイルドカードを使用したり、ファイルコピーにPowerShellリモートを使用したりすることができます!

このコマンドレットはPowerShellプロバイダのコマンドレットの一部です。これは一般的なコマンドレットで、その名前によって認識されます。これらのプロバイダのコマンドレットのほとんどは、異なるプロバイダ間で使用することができますが、私はPowerShellをほぼ10年間使用してきましたが、ファイルシステムプロバイダでのみCopy-Itemの使用を見たことがあります。

このコマンドレットの使用により、PowerShellを使用して開発者はさまざまな方法でファイルとフォルダをコピーすることができます。

基本的な使用方法

最も基本的な方法では、Copy-Itemコマンドレットは、Pathパラメータをソースファイルパスとして、Destinationパラメータを宛先フォルダパスとして使用して、単一のファイルをポイントAからポイントBにコピーします。

PS> Test-Path -Path C:\PointB\1.txt
False
PS> Copy-Item -Path C:\PointA\1.txt -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\1.txt
True 

このcmdletは空のフォルダもコピーすることができます。 C:\EmptyFolder フォルダ内のアイテムをリストアップしてから、それらをコピーします。

PS> Get-ChildItem -Path C:\EmptyFolder\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
False
PS> Copy-Item -Path C:\EmptyFolder\ -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
True 

おそらくフォルダ内に読み取り専用のファイルがあるかもしれません。デフォルトでは、Copy-Item は上書きしません。上書きするには、Force パラメータを追加してください。

Copy-Itemの選択的な使用

単一のファイルやフォルダだけでなく、フォルダのすべての内容をコピーすることもできます。Copy-ItemのPath パラメータは、アスタリスクなどのワイルドカード文字を受け入れます。アスタリスクは1文字以上の一致、クエスチョンマークは1文字のみの一致に使用されます。

PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> @(Get-ChildItem -Path C:\PointA).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path C:\PointA\* -Destination C:\PointB\
PS> @(Get-ChildItem -Path C:\PointB).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path 'C:\PointA\26?0.txt' -Destination C:\PointB\
PS> Get-ChildItem -Path C:\PointB\

Directory: C:\PointB
Mode                LastWriteTime         Length Name
-a----        8/11/2017   8:59 AM              5 2600.txt
-a----        8/11/2017   8:59 AM              5 2610.txt
-a----        8/11/2017   8:59 AM              5 2620.txt
-a----        8/11/2017   8:59 AM              5 2630.txt
-a----        8/11/2017   8:59 AM              5 2640.txt
-a----        8/11/2017   8:59 AM              5 2650.txt
-a----        8/11/2017   8:59 AM              5 2660.txt
-a----        8/11/2017   8:59 AM              5 2670.txt
-a----        8/11/2017   8:59 AM              5 2680.txt
-a----        8/11/2017   8:59 AM              5 2690.txt

複数のフォルダをマージする

Copy-Itemのもう1つの便利な機能は、複数のフォルダを同時にコピーすることができることです。複数のパスをPath パラメータに渡すと、Copy-Itemはそれぞれのパスを見て、パスに応じてフォルダまたはファイルをコピーし、すべてを1つの宛先に「マージ」します。

PS> Copy-Item -Path C:\PointB\*,C:\PointC\*,C:\PointD\* -Destination C:\PointE
PS> Get-ChildItem -Path C:\PointE

Directory: C:\PointE
Mode                LastWriteTime         Length Name
-a----       11/11/2017  12:15 PM              2 PointBFile.txt
-a----       11/11/2017  12:15 PM              2 PointCFile.txt
-a----       11/11/2017  12:16 PM              4 PointDFile.txt

再帰的にファイルをコピーする

すべてのファイルが単一のフォルダに含まれ、その中にもフォルダがないという理想的な状況にはならないでしょう。通常、親フォルダに多くのサブフォルダがあり、それらの中にもコピーしたいファイルが含まれています。 Copy-ItemRecurse パラメータを使用すると、各サブフォルダを調べ、再帰的にすべてのファイルとフォルダをコピーします。

ここでは、ファイルとフォルダを Get-ChildItem から直接 Copy-Item にパイプしています。 Copy-Item にはパイプラインのサポートがあります!

PS> (Get-ChildItem -Path C:\PointB\ -Recurse).Count
5
PS> Get-ChildItem -Path C:\PointB\ | Copy-Item -Destination C:\PointC -Recurse
PS> (Get-ChildItem -Path C:\PointC\ -Recurse).Count
5

PassThruパラメータを使用する利点

PowerShellの多くのcmdletにはPassThruパラメータがあります。通常は何も返さないcmdletも、PassThruパラメータを使用することで操作対象のオブジェクトを返すことができます。このcmdletも同様です。スクリプトを作成し始めた当初は、このパラメータを使用する必要を感じなかったため、使用しませんでした。

たとえば、ファイルをリモートの場所にコピーし、後でそのファイルをスクリプト内で参照したい場合、次のようにします:

$remoteFilePath = '\WEBSRV1\c$\File.txt'
Copy-Item -Path C:\File.txt -Destination $remoteFilePath
Write-Host "I've just copied the file to $remoteFilePath"

この方法は機能しますが、もっと良い方法があります。リモートパスのために変数を定義する代わりに、Copy-ItemコマンドレットをPassThruパラメータを使用して実行した際に返されるオブジェクトをキャプチャするだけです。返されるオブジェクトには常に宛先ファイルのパスが含まれます。

$copiedFile = Copy-Item -Path C:\File.txt -Destination '\WEBSRV1\c$'

PowerShellリモートセッションを使用してファイルをコピーする

PowerShell v5で導入された便利な機能の1つは、このコマンドレットがデフォルトのSMBプロトコルではなく、WinRMとPowerShellリモートセッションを使用してファイルを転送する能力です。Sessionパラメータを使用することで、Copy-Itemは既存のPowerShellセッションを使用してファイルを転送します。これはファイアウォールを回避するための素晴らしい方法であり、セッションの通信が暗号化されている場合は追加のセキュリティレイヤーとなります。

PS> $session = New-PSSession -ComputerName WEBSRV1
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
False
PS> Copy-Item -Path C:\File.txt -ToSession $session -Destination 'C:\'
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
True

ファイル.txtをSMB経由でコピーしてC$の管理共有が利用可能であることを期待することもできましたし、宛先パスに\\WEBSRV1\c$を使用することもできました。しかし、代わりにToSessionパラメータを使用したため、宛先パスは常にリモートセッションが実行されているコンピューターのローカルパスになります。

まとめ

Copy-Itemコマンドレットは、何度も使用することになるPowerShellのコアコマンドレットの一つです。PowerShellでは、ワイルドカードを使用してファイルやフォルダをさまざまな方法でコピーすることができます。さらに、複数のフォルダ内のファイルをマージしたり、既存のPowerShellリモートセッションを使用したりすることもできます!

詳細は以下をご参照ください。

Copy-item

Source:
https://adamtheautomator.com/copy-item/