SharePoint provides the SystemUpdate method for updating a list without checking out an item. This gives you the option to write a script or function that updates a list without interfering with other user activities or changing things like "last modified by" values.
You can also use this method to update page content.
When you want to update webpart properties through the SPLimitedWebPartManager object you don't have the SystemUpdate method though. When you change a property value and try to save the changed values through the SaveChanges() method you get an error.
"The file is not checked out. You must first check out this document before making changes."
With the PowerShell code below you will be able bypass this.
$spAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$ft = $spAssembly.GetTypes() | Where-Object { $_.Name -eq "SPLayoutProperties" }
Function SaveChangesReflection($wpm)
{
$bindingFlags = [System.Reflection.BindingFlags]::NonPublic.value__ + [System.Reflection.BindingFlags]::Public.value__ + [System.Reflection.BindingFlags]::Instance.value__
$wpm2prop = $wpm.GetType().GetProperties($bindingFlags) | Where-Object { $_.Name -eq "WebPartManager" }
$wpm2obj = $wpm2prop.GetValue($wpm, $null)
$t1 = [Microsoft.SharePoint.WebPartPages.SPWebPartManager]
$t2 = [System.Web.UI.WebControls.WebParts.WebPart]
$objTypeArr = @($t1, $t2)
[System.Object[]]$valueArr = @($wpm2obj, [System.Web.UI.WebControls.WebParts.WebPart]$wp)
$splCtor = $ft.GetConstructor("instance,nonpublic" , $null , $objTypeArr , $null)
$spl = $splCtor.Invoke($valueArr)
$wpm2objr = $wpm2obj.GetType()
$wpm2objrsci = $wpm2objr.GetMembers($bindingFlags) | Where-Object { $_.Name -match "SaveChangesInternal"}
$wpm2objrsci.Invoke($wpm2obj,@($spl,$true,$true))
}
The code utilises the internal method "SaveChangesInternal". This method takes an IgnoreSecurity parameter.
The first two lines initialises a few objects the function needs to optimize permance.
Happy Coding.