PowerShell で Rename-Item や Copy, Move, Remove など、各種操作を行う際に必須となるのが、 そのファイルが File Lock されているかどうかの確認です。 システム管理の一環として、ファイルの処理は欠かせないので 使う場面は多いはずです。 さて、PowerShell で FileLock 状態を取得するCmdlet はありません。 今回 ちらっと作ってみたので参考になれば幸いです。
コード
GitHub に挙げてあります。
https://github.com/guitarrapc/PowerShellUtil/tree/master/Test-FileLock
今回はモジュールとして用意しました。 ファイルロックの検知部分はこのようにしてみました。
try { # initialise variables $script:filelocked = $false # attempt to open file and detect file lock $script:fileInfo = New-Object System.IO.FileInfo $Path $script:fileStream = $fileInfo.Open([System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None) # close stream if not lock if ($fileStream) { $fileStream.Close() } } catch { # catch fileStream had falied $filelocked = $true } finally { # return result [PSCustomObject]@{ path = $Path filelocked = $filelocked } }
今回は Test-FileLock と Get-FileLock Cmdlet としてモジュールを用意しています。
利用例
基本的には、 File でのみ結果が返ってきます。 -Verbose を付けることで、対象がDirectoryだった場合にはメッセージが出ます。 対象がフォルダ、Registry や環境変数では動きません。
Test-FileLock
Test-FileLock は Path を受けて $true / $false を返します。
#region Test-FileLock will return file lock status for the file # true for locked file Test-FileLock -Path 'C:\Program Files\Windows NT\Accessories\wordpad.exe' # false for not locked file Test-FileLock -Path 'D:\Software\SumoLogics\SumoCollector_linux_amd64_19_40-8.sh' # blank for Directory (as it always returns true) # Add -Verbose if you want to check if it were not file Test-FileLock -path D:\Hyper-V -Verbose # error for not exist # Add -Verbose if you want to check if it were not file Test-FileLock -Path D:\ge # access error Test-FileLock -path "C:\Windows\System32\LogFiles\HTTPERR\httperr1.log" # Path recurse Get-ChildItem -path $env:USERPROFILE -Recurse | %{Test-FileLock -path $_.FullName -Verbose} # Registry is ignore Get-FileLock -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion # Environment Variables is ignored Get-FileLock -Path $env:AMDAPPSDKROOT #endregion
Get-FileLock
Get-FileLock は Path を受けて ファイルパスと $true / $false を返します。
#region Get-FileLock will return file name and file lock status for the file # locked file Get-FileLock -Path 'C:\Program Files\Windows NT\Accessories\wordpad.exe' # not locked file Get-FileLock -Path 'D:\Software\SumoLogics\SumoCollector_linux_amd64_19_40-8.sh' # blank for Directory (as it always returns true) # Add -Verbose if you want to check if it were not file Get-FileLock -path D:\Hyper-V -Verbose # not exist Get-FileLock -Path D:\ge # access error Get-FileLock -path "C:\Windows\System32\LogFiles\HTTPERR\httperr1.log" # Path recurse Get-ChildItem -path $env:USERPROFILE -Recurse | %{Get-FileLock -path $_.FullName -Verbose} # Registry is ignore Get-FileLock -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion # Environment Variables is ignored Get-FileLock -Path $env:AMDAPPSDKROOT #endregion
まとめ
もうちょっと楽に ファイルロックを取得できるといいのですが、まぁ実用できるのでいいです。 もっといい方法ないかなーです。