宛先ディレクトリにソースディレクトリよりも新しいファイルがあるかどうかを確認する最良の方法

宛先ディレクトリにソースディレクトリよりも新しいファイルがあるかどうかを確認する最良の方法

ソース ディレクトリと宛先ディレクトリがあります。ソース ディレクトリ内のすべての項目が宛先ディレクトリ内の項目と同じかそれより新しいことを確認したいと考えています。

Windows で最適な方法は何ですか。PowerShell が望ましいですが、より高速であれば robocopy のようなものでも構いません。

私の最初の考えは次のようなものです:

$src = Get-ChildItem -Recurse -path C:\temp\src\
$dest = Get-ChildItem -Recurse -path C:\temp\dest\
Compare-Object -ReferenceObject $dest -DifferenceObject $src
## TODO: Check result of Compare-Object and throw error if there's an unexpected change?

すべての SideIndicators が正しい方向を指している限り、必要な情報はおそらく得られるので、これを使用して宛先の予期しない変更を検出できますが、このアプローチはわかりにくく複雑に思えるので、この道を進む前にもっと良い方法があるかどうか疑問に思っています。

(ユースケースとしては、DevOps パイプライン以外では宛先を変更すべきではないが、時々変更する人がいるため、宛先に予期しない変更または新しいファイルがある場合は、事前に確認し、パイプラインを終了してさらに調査してから、ファイルをデプロイします)

答え1

属性をテストするために作成したファイル構造は次のとおりです。

PS C:\> Get-ChildItem C:\temp2\src -recurse

    Directory: C:\temp2\src

Mode                 LastWriteTime         Length Name                                                                                                                           
----                 -------------         ------ ----                                                                                                                           
-a----         8/27/2022   9:58 PM              3 myfile1.txt                                                                                                                    
-a----         8/27/2022   9:59 PM              6 myfile2.txt

PS C:\> Get-ChildItem C:\temp2\dest -recurse

    Directory: C:\temp2\dest

Mode                 LastWriteTime         Length Name                                                                                                                           
----                 -------------         ------ ----                                                                                                                           
-a----         8/27/2022   9:58 PM              3 myfile1.txt                                                                                                                    
-a----         8/27/2022   9:58 PM              3 myfile2.txt

SRC と DEST の 2 つのディレクトリがあり、それぞれに 2 つのファイルがあります。ファイルの 1 つ (myfile2.txt) には、LastWriteTime の値が異なります。以下のコードを実行すると、そのファイルに関して SRC と DEST の不一致があることが示され、同じファイルについてはフィードバックは提供されません。

次のスニペットでは、パスを編集するために$srcFilesとの値のみを変更します。他の部分は変更する必要はありません。$destFiles

$Results = @()
$srcFiles = Get-ChildItem "C:\temp2\src" -recurse | select Name,LastWriteTime
$destFiles = Get-ChildItem "C:\temp2\dest" -recurse | select Name,LastWriteTime
$srcFileTable = @{}
$destFileTable = @{}

foreach($srcFile in $srcFiles)
{
    $srcFileTable.Add(($srcFile.Name),($srcFile.LastWriteTime))
}
foreach($destFile in $destFiles)
{
    $destFileTable.Add(($destFile.Name),($destFile.LastWriteTime))
}

$srcFileTable.keys | %{
    if ($destFileTable.keys -match $_){
        if (!($destFileTable.$_ -match $srcFileTable.$_)) {
            $Results += new-object psobject -property @{Hash="SRC";Key=$_;Value=$srcFileTable.$_}
        }
    } Else {$Results += new-object psobject -property @{Hash="SRC";Key=$_;Value=$srcFileTable.$_}}
}
$destFileTable.keys | %{
    if ($srcFileTable.keys -match $_){
        if (!($srcFileTable.$_ -match $destFileTable.$_)) {
            $Results += new-object psobject -property @{Hash="DEST";Key=$_;Value=$destFileTable.$_}
        }
    } Else {$Results += new-object psobject -property @{Hash="DEST";Key=$_;Value=$destFileTable.$_}}
}
$Results | select Hash,Key,Value | sort -property Key,Hash | FT

これを実行すると、次のような結果が得られます。

Hash Key         Value               
---- ---         -----               
DEST myfile2.txt 8/27/2022 9:58:37 PM
SRC  myfile2.txt 8/27/2022 9:59:09 PM

これは、SRC ファイル名と DEST ファイル名が異なるLastWriteTimeことを示しており、この場合、誰かが myfile2.txt の SRC ファイルを編集し、それが dest のファイルとは異なると推測できます。

関連情報