This item cannot be updated because it is locked as read-only

Had to call in Microsoft Support to help unlock files that were marked as read-only. Some files appeared to be locked, but using the UI, they couldn’t be unlocked, declared as a record, or edited.

Error: This item cannot be updated because it is locked as read-only
Error: The file “your file string” is checked out for editing by SHAREPOINT\system

This script was setup to run on a SharePoint 2010 instance. If you need to run it on another version, try updating the $sharePointAssembly line.
To unlock a file, input the URL of the file in the line that starts with $fileUrl.


$recordFields =
  "_vti_ItemHoldRecordStatus",
  "_vti_ItemDeclaredRecord"

$recordProperties =
  "ecm_RecordRestrictions",
  "ecm_ItemLockHolders",
  "ecm_ItemDeleteBlockHolders"

$fileUrl = "http://siteURL/siteCollection/libraryName/folder/subFolder/fileName.pdf"

$sharePointAssembly = [System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")

Add-Type -TypeDefinition @"
using Microsoft.SharePoint;

public class EventsDisabler : SPEventReceiverBase
{
  public EventsDisabler() {}
  
  public bool EventsDisabled
  {
    get { return !EventFiringEnabled; }
    set { EventFiringEnabled = !value; }
  }
}
"@ -ReferencedAssemblies $sharePointAssembly

Write-Host "Getting site collection at $fileUrl..."
[Microsoft.SharePoint.SPSite]$site = New-Object Microsoft.SharePoint.SPSite($fileUrl)
if ($site -eq $null) { exit }
$siteUrl = $site.Url
Write-Host "Found site collection $siteUrl"
Write-Host ""

Write-Host "Getting web at $fileUrl..."
[Microsoft.SharePoint.SPWeb]$web = $site.OpenWeb()
if ($web -eq $null) { exit }
$webTitle = $web.Title
Write-Host "Found web $webTitle"
Write-Host ""

Write-Host "Verifying current user is System Account"
$web.CurrentUser.ID
$site.SystemAccount.ID
if ($web.CurrentUser.ID -ne $site.SystemAccount.ID)
{
  Write-Error "Please run this script as System Account" -Category PermissionDenied
  #exit
}
Write-Host ""

Write-Host "Getting list at $fileUrl..."
Write-Host $fileUrl
[Microsoft.SharePoint.SPList]$list = $web.GetList($fileUrl)
if ($list -eq $null) { exit }
$listTitle = $list.Title
Write-Host "Found list $listTitle"
Write-Host ""

Write-Host "Getting list item at $fileUrl..."
[Microsoft.SharePoint.SPListItem]$listItem = $web.GetListItem($fileUrl)
if ($listItem -eq $null) { exit }
$listItemName = $listItem.Name
Write-Host "Found list item $listItemName"
Write-Host ""

$eventsDisabler = New-Object EventsDisabler
$eventsOriginallyDisabled = $eventsDisabler.EventsDisabled
if ($eventsOriginallyDisabled -eq $false)
{
  Write-Host "Disabling events"
  $eventsDisabler.EventsDisabled = $true
  Write-Host ""
}

$didWork = $false
$itemNeedsUpdate = $false

#Discard any check-out
if ($listItem.File -ne $null -and $listItem.File.CheckOutType -ne [Microsoft.SharePoint.SPFile+SPCheckOutType]::None)
{
  Write-Host "Undoing check-out"
  $listItem.File.UndoCheckOut()
  $didWork = $true
}
else
{
  Write-Host "No file or file is not checked out"
  Write-Host ""
}

#Iterate the Record fields and set all values to null
foreach($recordField in $recordFields)
{
  if ($listItem.Fields.ContainsField($recordField) -eq $true -and $listItem[$recordField] -ne $null)
  {
    $recordFieldValue = $listItem[$recordField]
    Write-Host "$recordField = $recordFieldValue"
    Write-Host "Setting $recordField to null"
    $listItem[$recordField] = $null
    $didWork = $true
    $itemNeedsUpdate = $true
  }
}

#Iterate the Record properties and remove any that exist
foreach($recordProperty in $recordProperties)
{
  if ($listItem.Properties.ContainsKey($recordProperty) -eq $true)
  {
    $recordPropertyValue = $listItem.Properties[$recordProperty]
    Write-Host "$recordProperty = $recordPropertyValue"
    Write-Host "Removing property $recordProperty"
    $listItem.Properties.Remove($recordProperty)
    $didWork = $true
    $itemNeedsUpdate = $true
  }
}

#Remove the icon Record lock overlay
if ($listItem.IconOverlay -eq "lockoverlay.png")
{
  Write-Host "Removing the icon Record lock overlay"
  $listItem.IconOverlay = $null
  $didWork = $true
  $itemNeedsUpdate = $true
}

if ($didWork -ne $true)
{
  Write-Host "No changes were made"
}
Write-Host ""

#Update the item
if ($itemNeedsUpdate -eq $true)
{  
  Write-Host "Updating item"
  $listItem.SystemUpdate()
  
  Write-Host ""
}

if ($eventsOriginallyDisabled -ne $true)
{
  Write-Host "Enabling events"
  $eventsDisabler.EventsDisabled = $false
  Write-Host ""
}

$web.Dispose()
$site.Dispose()

The Process cannot access the file because it is being used by another process

Central Admin won’t load…

After rebooting my farm I wasn’t able to access Central Administration.

Went into IIS and noticed the site was stopped.  When I tried to start it, I was greeted with the following error: The Process cannot access the file because it is being used by another process.

On the server hosting the site, get to a command prompt and type:  netstat -ano

scroll through the list and find the port that Central Admin is using.  After you find it, make note of the PID (right column).

Now, open task manager, click on the Processes tab.  From the View menu, click on Selected Column… Select PID (Process Identifier).

Sort the PID column in Task Manager, locate the PID that you made note of in the command window.  Kill the process.

Go back to IIS, start the Site (right click on the site, Manage Web Site, Start).

Browse to Central Admin!