多くのフォルダ共有を使用していますが、他のプロセスによって開かれたロックされたファイルがたくさんあります。
それらのファイルを閉じる必要があります。これまでのところ、MMC-システムツール-共有フォルダ-開いているファイルを使用しています。
PowerShellを使用してOpenFiles.exeによって取得されたリスト/テーブルをフィルタリングでき、ファイルIDを取得したらnet file/closeで閉じると、はるかに便利です。 、または他のいくつかのPSネイティブは、同様の効果を意味します。
PowerShellは初めてなので、ファイルのパスを受け取り、ファイルIDを使用してそのファイルを閉じるPSスクリプトを作成する方法はあるのでしょうか。
Get-SmbOpenFileおよびClose-SmbOpenFileは、ジョブを実行します。
ファイルサーバーにログインし、PowerShellを起動します。 Get-SmbOpenFileを使用して、ファイルサーバーで開いているすべてのファイルを表示します。ファイルは次のテーブルヘッダーとともに表示されます
FileId SessionId Path ShareRelativePath ClientComputerName ClientUserName
Close-SmbOpenFileを使用してファイルを閉じます。
Close-SmbOpenFile -FileId 4415226383589
Excelファイルが問題であることがわかっている場合は、.XLSX拡張子が付いた開いているすべてのファイルの検索を絞り込むことができます。
Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX"
結果から問題のファイルを見つけたら、fileIDでファイルを閉じることができます。
ファイルサーバーで開いているすべてのファイルを閉じる場合:
Get-SmbOpenFile | Close-SmbOpenFile
開いていて、ファイル拡張子「.XLSX」と一致する1つ以上のファイルを閉じる場合。
Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX" | Close-SmbOpenFile -Force
****注**** TechNetの記事「TheClose-SMBOpenFilecmdletによると、ファイルを強制的に閉じますサーバーメッセージブロック(SMB)サーバーのいずれかのクライアントによって開かれているこのコマンドレットは、データが失われる可能性があるため、注意して使用する必要がありますファイルが閉じられる前にクライアントがすべてのファイル変更をサーバーにフラッシュバックしていない場合に、ファイルが閉じられているクライアントに対して。
CMDletの詳細について
Get-SmbOpenFile https://technet.Microsoft.com/en-us/library/jj635701(v = wps.620).aspx
Close-SmbOpenFile https://technet.Microsoft.com/en-us/library/jj635721(v = wps.620).aspx
openfiles.exe
andnet file
の両方を使用する必要がある理由はありますか?
以下は、net file
のみを使用し、PowerShellスクリプトで囲む関数です。
これを使用するには、コード全体をコピーして、PowerShellセッションに貼り付けます。補足として、net file
およびopenfiles
を使用するには管理者権限が必要です。
セッションに貼り付けると、関数Close-OpenFile
を使用できるようになります。使い方はとても簡単です。ファイルパスを関数にパイプするか、ファイルパスをパラメーターとして指定できます。
そのまま貼り付けた場合は、Get-Help Close-OpenFile -Example
を使用して例を表示すると、実際にヘルプを利用できます。以下は、参考までに同じ例です。
# Method 1 : Pipeline
@("file\path\1", "file\path\2") | Close-OpenFile
"file\path\1" | Close-OpenFile
# Method 2 : Parameter
Close-OpenFile @("file\path\1", "file\path\2")
Close-OpenFile "file\path\2"
ここで、PowerShellを開くたびにこれを使用するとします。この回答の最後に、これを行う基本的な方法を示しました(他の方法もあります)。
<#
.Synopsis
Closes Files Opened in Network Share
.EXAMPLE
@("file\path\1", "file\path\2") | Close-OpenFile
Attempts to close "file\path\1" and "file\path\2" if they are open.
.EXAMPLE
Close-OpenFile @("file\path\1", "file\path\2")
Attempts to close "file\path\1" and "file\path\2" if they are open.
.EXAMPLE
"file\path\1" | Close-OpenFile
Attempts to close "file\path\1" if it is open.
.EXAMPLE
Close-OpenFile "file\path\2"
Attempts to close "file\path\2" if it is open.
#>
function Close-OpenFile {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String[]]$filesToClose
)
Begin {
$netFile = net file
if($netFile.length -lt 7) { Throw "No Files are Open" }
$netFile = $netFile[4..($netFile.length-3)]
$netFile = $netFile | ForEach-Object {
$column = $_ -split "\s+", 4
New-Object -Type PSObject -Property @{
ID = $column[0]
FilePath = $column[1]
UserName = $column[2]
Locks = $column[3]
}
}
$count = 0
} Process {
ForEach ($file in $filesToClose) {
ForEach ($openFile in $netFile) {
if($openFile.FilePath -eq $file) {
$count++
net file $openfile.ID /close > $null
}
}
}
} End { Write-Output "Closed $count Files" }
}
以下は、PowerShellを開くたびにこの関数を使用する基本的な方法を示しています。
$env:homepath\Documents\WindowsPowerShell
に移動します(ない場合は作成します)。C:\Users\<username>\Documents\WindowsPowerShell
に解決されます。profile.ps1
(またはMicrosoft.PowerShell_profile.ps1
)というファイルを作成します。Close-OpenFiles
関数全体をコピーして貼り付け、保存します。以下は、CMDとOpenFiles.exeを使用した簡単な方法です。これは必要に応じてすぐにPoSHに変換できると思います。これをCloseFile.cmdとして保存し、パス上のフォルダーに配置します。
@echo off
if "%1" == "" goto SYNTAX
if "%2" == "" goto SYNTAX
goto RUNIT
:SYNTAX
echo Use:
echo CloseFile.cmd ^<server^> ^<file^>
goto :EOF
:RUNIT
set _server=%1
set _file=%2
openfiles /query /s %_server% /fo csv | findstr /i /c:"%_file%" > _filelist.txt
for /f "tokens=1,4 delims=," %%a in (_filelist.txt) do (
openfiles /disconnect /s %_server% /op %%b /id %%a
)
if exist _filelist.txt del _filelist.txt