Copy_ListItem_Field

Language:
PowerShell
Keywords:
SharePoint
Code Snippet

# For all list items, copy data from the sourcefield to the destfield
# runs as system account; disables event handlers (and workflows); does not increase version number
Function Copy_ListItem_Field( [Microsoft.SharePoint.SPList]$tList
                            , $tSourceFieldName
                            , $tDestFieldName
                            ) {

    # can't use GetFieldByInternalName since that throws an exception when not found... *sigh*... silly SP OM
    if (($tList.Fields | where { $_.InternalName -eq $tSourceFieldName }) -ne $null -and
        ($tList.Fields | where { $_.InternalName -eq $tDestFieldName }) -ne $null)
    {
        try {

            # Load the parent web and site IDs (used later in RunWithElevatedPrivileges)
            $web = $tList.ParentWeb
            $site = $web.Site
            $webID = $web.ID
            $siteID = $site.ID
            $site.Dispose()
            $web.Dispose()

            # Execute as System Account (ensures that version history accurately accounts for the data changes)
            [Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges({

                # new SPSite and SPWeb using new context
                cUsing ($site = New-Object Microsoft.SharePoint.SPSite($siteID)) {
                    cUsing ($web = $site.OpenWeb($webID)) {

                        $tListItemID_Start = 0
                        $tListItemID_Last = 0
                        $tListItemsUpdated = 0

                        # Loop through list items
                        $tQuery = New-Object Microsoft.SharePoint.SPQuery
                        $tQuery.ViewFields = [System.String]::Format("<FieldRef Name=`"ID`" /><FieldRef Name=`"{0}`" /><FieldRef Name=`"{1}`" />", $tSourceFieldName, $tDestFieldName)
                        $tQuery.Query = [System.String]::Format("<OrderBy Override=`"TRUE`"><FieldRef Name=`"ID`" /></OrderBy><Where><IsNotNull><FieldRef Name=`"{0}`" /></IsNotNull></Where>", $tSourceFieldName)
                        $tQuery.ViewAttributes = "Scope=`"Recursive`""
                        $tQuery.RowLimit = 1000
                        do {
                            # load this set of items
                            $tListItems = $web.Lists[$tList.ID].GetItems($tQuery)

                            # loop through each set of RowLimit
                            foreach($tListItem in $tListItems) {

                                # DEBUG
                                if ($tListItemID_Start -eq $null -or $tListItemID_Start -eq 0) { $tListItemID_Start = $tListItem.ID }

                                # only update if necessary
                                if ($tListItem.Properties[$tDestFieldName] -ne $tListItem.Properties[$tSourceFieldName]) {

                                    # DisabledItemEventsScope will ensure that events will not fire (workflows will not start)
                                    cUsing ($object = New-Object DisabledItemEventsScope) { 

                                        # set new field value to old field value
                                        $tListItem.Properties[$tDestFieldName] = $tListItem.Properties[$tSourceFieldName]

                                        # SystemUpdate to ensure that the version isn't increased (and thus that the change isn't pending approval)
                                        $tListItem.SystemUpdate($false)

                                    } # disable item event receivers
                                    
                                    # Increment counter
                                    $tListItemsUpdated = $tListItemsUpdated + 1
                                    
                                } # if updating record

                                # DEBUG
                                $tListItem_Last = $tListItem.ID
                                
                            } # ForEach ListItem
                            
                            $tQuery.ListItemCollectionPosition = $tListItems.ListItemCollectionPosition
                            
                        } while ($tQuery.ListItemCollectionPosition -ne $null)

                        Write-Host([System.String]::Format("List [{0}] : Updated [{1}] items : Copy from [{2}] to [{3}]", $tList.Title, $tListItemsUpdated, $tSourceFieldName, $tDestFieldName))

                    } # using SPWeb
                } # using SPSite

            }) # RunWithElevatedPrivileges (as System Account)

        } # Try
        catch [System.Exception] {
            Write-Error([System.String]::Format("EXCEPTION WHILE COPYING LISTITEM DATA... Start ID [{0}]; End ID [{1}]", $tListItem_Start, $tListItem_Last))
            Write-Error([System.String]::Format("Message [{0}]", $_.Exception.Message))
        } # try/catch
    } # if List contains Source and Destination fields
} # Function


Created 2011-10-13
comments powered by Disqus
Login