Propagating legacy Document IDs into SharePoint

Document IDs in SharePoint

Document IDs are generated automatically by SharePoint when configured, but what if you have your own legacy Document IDs that you want to use? There is a way to push them in.

The first trick is recognizing there are two internal fields created when Document IDs are enabled.
ows__dlc_DocId : The actual Document ID
ows__dlc_DocIdUrl : The special Redir.ASPX based URL with the document ID within it

Let’s examine the later field in a bit more detail. This contains a URL with a reference to “DocIdRedir.aspx” which is an ASPX ghosted page that will redirect either via local service lookup, or a fallback to a search based lookup. Here’s what it looks like:

http ://server/_layouts/DocIdRedir.aspx?ID=DOC-1000-3109, DOC-1000-3109″

Note the comma, then the repeated Document ID.

Now imagine if there’s a field in our document library that has the legacy Document ID we want to use.

The script below goes through, and systematically replaces the existign Document ID with the Legacy one we want to use.

[system.reflection.assembly]::LoadWithPartialName("Microsoft.Sharepoint") 
Write-Host ("$(get-date) Running script to assing DOcIDs")
$SiteFilter = "*"
$siteUrl = "http ://SharePoint" #use your own Web App URL
$ThisLibOnly = $null; #allows for filtered selection of libraries
Write-Host ("$(get-date) Assigning DocIDs from Legacy IDs")
$webApp=Get-SPWebApplication $SiteURL
$Sites = $webApp | Get-SPSite -Limit all
foreach ($site in $Sites)
{
$OutputSuffix=$loopLetter;
$mylogfile="C:Tempoutput.log"
write-host $site.Url
Write-Host -foregroundcolor darkblue "$($site.id) - $($site.Url) - $($site.contentdatabase.id) - $($site.contentdatabase.name)"   
$WebScope = Start-SPAssignment
foreach ( $TargetWeb in $site.AllWebs)
{
Write-Host("Working in site: " + $TargetWeb)
$ListOfLists = @();
# Loop through all doc libs
$lists=$TargetWeb.lists;
$listsCount=$lists.count
for ($ii=0; $ii -lt $listsCount; $ii++)
{
$JPlib=$lists[$ii];
if ( ($JPlib.BaseType -ne "DocumentLibrary") -or ($JPlib.hidden) )
{
# forget the rest and return to top
Write-Host -foregroundcolor darkred "fast test skipping Library: $($JPlib)";   
}
elseif ($JPLib.Title -Match "Photo|Image|SitesAssets|CustomizedsReports|Templates|Pages|Picture|cache|style")
{
# forget the rest and return to top
Write-Host -foregroundcolor darkred "fast test skipping Library because it mentions $Matches: $($JPlib)";   
}
elseif (!$JPlib.contenttypesenabled)
{
continue; # no content types, no interest
}
else
{  
Write-Host -foregroundcolor green "Processing Library: $($JPlib)";   
$ListOfLists += $JPlib.title;
}
}
foreach ($CurrentLib in $ListofLists)
{
$JPlib=$TargetWeb.lists[$CurrentLib];
$JPlib.title
if ($JPlib -eq $null)
{
Write-Host "COULD NOT GET LIB $($CurrentLib)"
continue;
}
Write-Host -foregroundcolor green "Processing Library: $($JPlib) in $($TargetWeb)";   
if (($ThisLibOnly -eq $null) -or
($JPlib.title -eq $ThisLibOnly)) 
{
$JPItems=$JPlib.Items;
$JPCount=$JPItems.get_count();
if ($JPCount -eq 0) {continue} #can't do much on a library with no items!
for ($i=0; $i -lt $JPCount; $i++)  #Do not use ItemCount, that one includes folders!
{	
$JPItem=$JPItems[$i];
$SourceValue=$JPItem["LegacyDocID"];
if (($SourceValue -eq $null) -or ($SourceValue.length -le 0))
{
write-host "-" -nonewline
continue; #nothing to assign
}
elseif ($JPItem["ows__dlc_DocId"] -ne $SourceValue) #avoid reassigning same value
{
Write-Host "Old DocID=$($JPItem['ows__dlc_DocId']),LegacyDocID=$($SourceValue)"
$oldDocIDValue=$JPItem["ows__dlc_DocId"]
$JPItem["ows__dlc_DocId"] = $SourceValue;
if ($JPItem["ows__dlc_DocIdUrl"].length -gt 1)
{
$JPItem["ows__dlc_DocIdUrl"]= $JPItem["ows__dlc_DocIdUrl"].replace($oldDocIDValue,$SourceValue);
}
$JPItem.systemupdate() #without generating version
Write-Host "$($i): $($JPItem.url)"
}
else
{  #special!  $JPItem["ows__dlc_DocIdUrl"]=$null;
Write-Host "DOcID Match! $($JPItem.url)"
Write-Host "Old DocID=$($JPItem['ows__dlc_DocId']),LegacyDocID=$($SourceValue)"
}
}		
}
Write-Host "+" -NoNewline
}# Lib loop
$JPlib.Update();
$JPlib=$null;
} #all libs?
try
{
$TargetWeb.dispose()
} catch{}
$TargetWeb=$null;
Stop-SPAssignment $WebScope
} #all webs?
} # all sites?
$site.Dispose()
$site=$null;
Stop-SPAssignment $SiteScope
Write-Host "SCRIPT COMPLETE $(get-date)"
3 replies
  1. kevin
    kevin says:

    Hi Joel,

    I followed your script and replaced Document ID and Id’s in URL successfully but when i click on document id from metadata i get following message or use search (Document ID web part) i dont find that document.

    Operation Completed Successfully
    No documents with the ID XXXX-XX-XX-XXXX-XXXX were found in this site collection.

    Anything else i have to do ?

    Thanks,
    Kevin

    Reply
    • Joel Plaut
      Joel Plaut says:

      There are two ways these IDs get consumed; one is by lookup within the Site Collection, the other is via enterprise search. Given the later, I’d suggest trying again after a crawl.

      It’s possible there’s a difference in the text you used for IDs, I’d double check the values.

      Also, of course ensure the appropriate DocID features are enabled.

      Joel

      Reply

Trackbacks & Pingbacks

  1. […] script is for propagating legacy Document IDs into SharePoint. This is great if you are moving existing documents to SharePoint where you want to retain the […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *