Monday, May 18, 2015

PowerShell Script to Modify List Items (Author, Editor, Created, Modified)

I recently had to prototype an event receiver that I wrote in my development environment designed to trigger on the migration of data from SharePoint 2007 to 2013 using DocAve Migrator. Since I don't have DocAve running on my laptop, I basically wrote a couple of PowerShell scripts to simulate what it does. The starting point, however, was to take the contents of a document library and modify the "Modified" timestamp so the event receiver would trigger in the first place (logic being that migrated files wouldn't be Modified today but, rather, sometime in the past). Anyway, here's what I came up with... A few caveats:

1. While I was changing the Modified timestamp, I also wanted to change the Author and Editor metadata, so those are changed to one of the users listed in the $usersLogin array at random

2. I decided to make the Modified timestamp more or less random with the Created timestamp some random number of seconds prior to that...it's all a bit unnecessarily complex, I'm guessing, but it's how I wanted to do it...

3. I also wanted to make sure that the random date, if it happened to come up in 2015, was never in the future.

<#
Title: Modify-ItemAttributes.PS1
Author: Jason Ramsey
Category: Utility Script
Description:
Given a SharePoint site and SharePoint list therein, script will identify all items of a target content type
within the list (recursively, so inside subordinate folders as well) and modify selected metadata fields.
In this case, the item's Created date will be some random number of seconds prior to the items Modified date.
#>

#Add the SharePoint snapin
Add-PSSnapin Microsoft.SharePoint.Powershell -ea SilentlyContinue

#set the web url and the list name to work upon
$url = "http://<targetSPSite>"
$listName = "<TargetList>"
$targetContentType = "<TargetContentType>"

#Get the appropriate list from the web
$web = Get-SPWeb $url
$list = $web.lists[$listName]

#Build retention code array
$retentionCode = @("Non-Sensitive Data","Sensitive Data","Sensitive PII")

#Build user array
$usersLogin = @("i:0#.w|SANDBOX\user1", "i:0#.w|SANDBOX\user2", "i:0#.w|SANDBOX\user3", "i:0#.w|SANDBOX\user4")

#Get all the items with the desired content type
$listItems = $list.Items

#Iterate through all the files
foreach ($item in $listItems)
{
#Generate a random number to access the $retentionCode array
$randoRC = Get-Random -Maximum #retentionCode.Count

#Generate random numbers to access the $usersLogin array for author and editor
$randoAu = Get-Random -Maximum $usersLogin.Count
$randoEd = Get-Random -Maximum $usersLogin.Count

#Generate a bunch of random numbers to create random date strings
$randoModYr = Get-Random -Minimum 2012 -Maximum 2016
if ($randoModYr -eq 2015)
{
$randoModMo = Get-Random -Minimum 1 -Maximum 6
}
else
{
$randoModMo = Get-Random -Minimum 1 -Maximum 13
}
if ($randoModMo -eq 2)
{
$randoModDa = Get-Random -Minimum 1 -Maximum 29
}
elseif ($randoModMo -eq 9 -OR $randoModMo -eq 4 -OR $randoModMo -eq 6 -OR $randoModMo -eq 11)
{
$randoModDa = Get-Random -Minimum 1 -Maximum 31
}
elseif ($randoModMo -eq 5 -AND $randoModYr -eq 2015)
{
$randoModDa = Get-Random -Minimum 1 -Maximum 14
}
else
{
$randoModDa = Get-Random -Minimum 1 -Maximum 32
}
$randoModHo = Get-Random -Maximum 24
$randoModMi = Get-Random -Maximum 60
$randoModSe = Get-Random -Maximum 60

#Create the rando date string for Modified
$randoModDate = "{0}/{1}/{2} {3}:{4}:{5}" -f $randoModMo, $randoModDa, $randoModYr, $randoModHo, $randoModMi, $randoModSe

#Create the rando date string for Created that is sometime in the past
$randoCreDiff = -(Get-Random -Maximum (([math]::pow(2,27))))

#Print out the current item name
Write-Host ""
Write-Host ("File {0} being updated..." -f $item["Name"]) -foregroundcolor "yellow"

#Print out current Created by and Created date
Write-Host ("...... ORIG ... created by {0} on {1}" -f $item["Author"].tostring(), $item["Created"]) -foregroundcolor "blue"

#Print out current Modified by and Modified date
Write-Host ("...... ORIG ... last modified by {0} on {1}" -f $item["Editor"].tostring(), $item["Modified"]) -foregroundcolor "blue"

#Set the target values
$authorLogin = $usersLogin[$randoAu]
$editorLogin = $usersLogin[$randoEd]
$dateModify = Get-Date $randoModDate
$dateCreate = $dateModify.AddSeconds($randoCreDiff)

#Make the user strings for author and editor
$author = Get-SPUser -Web $web | where {$_.userlogin -eq $authorLogin}
$authorString = "{0};#{1}" -f $author.ID, $author.UserLogin.Tostring()
$authorDisplay = "{0};#{1}" -f $author.ID, $author.DisplayName.Tostring()
$editor = Get-SPUser -Web $web | where {$_.userlogin -eq $editorLogin}
$editorString = "{0};#{1}" -f $editor.ID, $editor.UserLogin.Tostring()
$editorDisplay = "{0};#{1}" -f $editor.ID, $editor.DisplayName.Tostring()

#Set the created by field
$item["Author"] = $authorString
$item.Properties["vti_author"] = $authorDisplay
$item["Created"] = $dateCreate

#Set the modified by values
$item["Editor"] = $editorString
$item.Properties["vti_modifiedby"] = $editorDisplay
$item["Modified"] = $dateModify
#$item.ModifiedBy = $editorString
#$item.TimeLastModified = $dateModify

#Set the retention code
$item["Retention Code"] = $retentionCode[$randoRC]

#Because crap seems to get caught in the MetaInfo (Properties) tag as well...
#$item.Properties.vti_author = $author.tostring()
#$item.Properties.vti_modifiedby = $editor.tostring()

#Print out new Created by and Created date
Write-Host("...... CHAN ... created by {0} on {1}" -f $authorString, $dateCreate) -foregroundcolor "green"

#Print out new Modified by and Modified date
Write-Host ("...... CHAN ... last modified by {0} on {1}" -f $editorString, $dateModify) -foregroundcolor "green"

#Print out new Retention Code
Write-Host ("...... CHAN ... retention code is {0}" -f $retentionCode[$randoRC]) -foregroundcolor "green"

Write-Host ""
Write-Host ""

#Store changes without overwriting the existing Modified details
$item.Update()
}


by Jason Ramsey via Everyone's Blog Posts - SharePoint Community

No comments:

Post a Comment