Wednesday, June 29, 2016

SharePoint - unlock a file that is exclusively locked by another user

It appears that both SharePoint 2010 and 2013 still have the bug to potentially lock a file even away from the very person who last checked out the file.

This buggy behavior is described in this Microsoft article.

Basically, when a document in SharePoint is opened by a client program like Word, Excel, SharePoint places a lock on the document on the server. The write lock times out after 10 minutes. Users cannot modify the document during the time when the document is locked.

In a scenario where the program (Word, Excel, etc) that opens the document unexpectedly quits or crashes and you try to open the document again before the write lock times out (10 minutes), you may receive the message that says the document is (exclusively) locked by another user. Even if you are the last person who opened the document, you may receive this message, too.

Now the problem may continue even if you wait for 10 minutes. When the document is coninued to be in locked status, we can use Powershell script to remove the lock as described here.

## To find out about locked info of the file
$web = Get-SPWeb "https://sharepoint.mycompany.com/sites/mysite"
$list = $web.Lists["Shared Documents"]
$item = $list.GetItemById(3)
$file = $item.File
$file

The LockType property from script above may show "None", yet the file may still be locked away from the last person who opened it. Now use Powershell to clear the lock.
$fileTime = New-Object System.TimeSpan(10000)
## Create a new file lock on the file
$file.Lock([Microsoft.SharePoint.SPFile+SPLockType]::Exclusive, "Test Lock", $fileTime)
## Remove the lock from the file
$file.UndoCheckOut()

If the script is actually locked by another user and the lock is not being released for any reason, you can use the following script to remove the lock via impersontion, too.
$web = Get-SPWeb "https://sharepoint.mycompany.com/sites/mysite"
$list = $web.Lists["Shared Documents"]
$item = $list.GetItemById(3)
$file = $item.File
$userID = $file.LockedByUser.ID
$user = $web.AllUsers.GetByID($userID)

$impersonatedSite = New-Object Microsoft.SharePoint.SPSite($web.Url, $user.UserToken)
$impersonatedWeb = $impersonatedSite.OpenWeb();
$impersonatedList = $impersonatedWeb.Lists[$list.Title]
$impersonatedItem = $impersonatedList.GetItemById($item.ID)
$impersonatedFile = $impersonatedItem.File
$impersonatedFile.ReleaseLock($impersonatedFile.LockId)

No comments: