web-dev-qa-db-ja.com

Powershell:ファイルをロックしないGet-Content

頻繁に変更されるリモートPC上のファイルを読み取る必要があります。そうなると、私のスクリプトがファイルへの書き込みと衝突して、アクセスできなくなることがあります。ファイルへの書き込み方法を変更できないので、自分が持っているものを使用する必要があります。

スクリプトをGet-Contentで継続的に読み取り、その後頻繁にファイルに書き込む別のスクリプトを開始して、テストを実行しました。時々、書き込み操作は不可能でした。

ファイルをロックせずにリモートPCでget-contentを使用することは可能ですか?

7
lcam
[System.IO.FileStream]$fileStream = [System.IO.File]::Open("\\remote\share\Text Document.txt", [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$byteArray = New-Object byte[] $fileStream.Length
$encoding = New-Object System.Text.UTF8Encoding $true
while ($fileStream.Read($byteArray, 0 , $byteArray.Length)) {
    $encoding.GetString($byteArray)
}
$fileStream.Dispose()
4
t1meless

書き込み中のコンテンツを同時に読み取ることはできません。

解決策として、シャドウコピーを使用してファイルを読み取ることができます。そのためには、シャドウコピーをマウントする必要があります。

$s1 = (Get-WmiObject -List Win32_ShadowCopy).Create("X:\", "ClientAccessible")
$s2 = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $s1.ShadowID }
$d  = $s2.DeviceObject + "\"   # 
cmd /c mklink /d X:\tmpshacpy "$d"

この後、マウントされた場所(X:\ tmpshacpy)にアクセスして、ファイルを正常に読み取ることができます。

読み取りが完了した後でシャドウコピーをマウント解除するには、$ s2.Delete()を使用します。

8
Overmind