最近遇到一个问题,在SharePoint2010中无法edit, unlock或者declare一个file,在修改时候会显示下面错误"This item cannot be updated because it is locked as read-only".
并且无法使用PowerShell unlock file,在执行Undocheckout命令时会弹出下面error:
Exception calling "ReleaseLock" with "1" argument(s): "The operation on file "file location" cannot be completed because the specified lock arguments are not valid."
对于这种问题可以通过下面的script解决:(需要替换对应文件的URL并运行)
$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()
执行完成后,文件可以正常编辑修改, 问题解决。
此script只适用于在SharePoint2010运行,如果需要在其他版本,需要更新$SharePointAssembly行。
记录一下方便之后使用, 感谢阅读。