Close locked file in Windows Share using Powershell and Openfiles
Is there a reason that you need to use both openfiles.exe
and net file
?
Below is a function that uses only net file
and wraps it around a PowerShell Script.
To use it, you can copy the whole code, and paste it into a PowerShell session. As a side note, you need Administrator privilege to use net file
and openfiles
.
Once you paste it into your session, you will be able to use the function Close-OpenFile
. The usage is very simple. You can either pipe the file paths into the function, or to specify the file paths as a parameter.
If you pasted it as is, you can actually get help by using Get-Help Close-OpenFile -Example
to see examples. Below are the same examples for your convenience.
# 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"
Now, suppose you want to use this every time you open PowerShell. I've provided a basic way to do this (there are other ways to do it) at the end of this answer.
<#
.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" }
}
Below illustrates a basic way to have this function every time you open PowerShell.
- Navigate to
$env:homepath\Documents\WindowsPowerShell
(create it if you don't have it).
This typically resolves toC:\Users\<username>\Documents\WindowsPowerShell
. - Create a file called
profile.ps1
(orMicrosoft.PowerShell_profile.ps1
). - Copy and Paste the entire
Close-OpenFiles
function and save it.
![Renato Reyes](https://i.stack.imgur.com/TV8t4.jpg?s=256&g=1)
Renato Reyes
Updated on September 18, 2022Comments
-
Renato Reyes almost 2 years
I work with a lot of folder shares, but there are a bunch of locked files which have been opened by some other process.
I need to close those files. So far I've been using MMC - System Tools - Shared Folders - Open Files.
It would be far more convenient if I could use PowerShell to filter the list/table retrieved by OpenFiles.exe and once I get the file ID close it with net file /close, or some other PS native means to similar effect.
I am new to PowerShell, so I wonder if there is a way to create a PS script that receives the file's path and then used the file ID to close that file?