Tuesday, December 28, 2010

Check In SharePoint Documents using Powershell while Preserving "Modified" and "Modified By" MetaData

The Problem:

I was recently handed the following tasks:
  1. Checkin thousands of recently migrated documents

  2. maintain modified by metadata

  3. maintain modified date metadata

  4. must be done in powershell
The Solution:

I did some research and found a good post describing how to preserve the modifed by data here, but I still had to find a way to get it into powershell and also address the "modified date" requirement.

Below is the powershell I came up with that is working for me. You will probably want to update the list query piece to ensure the correct items are retreived. Also, I'm not quite sure the "RunWithElevatedPriveleges" is required or not, so you can test that out as well.

Hopefully this helps someone out there!

#function to return bindings to use in GetMethod() function
function Bindings()
{
return [System.Reflection.BindingFlags]::CreateInstance -bor
[System.Reflection.BindingFlags]::GetField -bor
[System.Reflection.BindingFlags]::Instance -bor
[System.Reflection.BindingFlags]::NonPublic
}

#Function to checkin a file using a specific user
function CheckInFileByUser([Microsoft.SharePoint.SPFile]$file, [string]$comment, [Microsoft.SharePoint.SPCheckinType]$checkInType, [Microsoft.SharePoint.SPUser]$user)
{
$bindings = Bindings
[System.Type[]] $types = [string],[Microsoft.SharePoint.SPCheckinType],[bool], [Microsoft.SharePoint.SPUser]
$method = $file.GetType().GetMethod("CheckIn",$bindings,$null,$types,$null)
$params = $comment,$checkInType,$false,$user
$method.Invoke($file,$params)
}

#Main code section
$baseUrl = "http://localhost/sites/records"
$listName = "Record Library"

Clear-Host
$site = Get-SPSite $baseUrl
$web = $site.OpenWeb($site.RootWeb.ID)
$list = $web.Lists[$listName]

#example only, get items using view or query of your choice
Foreach($item in $list.Items)
{
$file = $item.File
if($file.Level -eq [Microsoft.SharePoint.SPFileLevel]::Checkout)
{
#get the current date to use later
[System.DateTime]$date = $item["Modified"]
[Microsoft.SharePoint.SPFile]$file = $item.File

#get the current editor SPUser to use when checking in the file
$user = New-Object microsoft.SharePoint.SPFieldUserValue($web, $item["Editor"])

#check in the file
CheckInFileByUser $file "My Comment" "MajorCheckIn" $user.User
#change the modified date back to the original value
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges(
{
$item = $list.Items.GetItemById($item.ID);
$item["Modified"] = $date
$item.Update()
} )
}
}