SharePoint + Powershell: Remove Hold, Record Declaration on All Documents in a Library

In order to delete a Records Library or Records Center, all holds and records in a library must be removed and the Holds and Processing timer job must be run. If this criteria is not met, the “Delete this Document Library” will not be an option in the library settings.

Here is how you can do this programmatically. Note that I did not include the deletion of documents or the document library itself.

$siteURL = $args[0]
$libraryName= $args[1]

$site = Get-SPSite $siteURL
$web = $site.RootWeb
$library = $web.Lists[$libraryName]
$records = $library.Items[0]

# First, remove all holds from all items in the Library
$holdsList = $web.Lists["Holds"]
$holds = $holdsList.Items[0]
[Microsoft.Office.RecordsManagement.Holds.Hold]::RemoveHold($records,$holds,"Holds have been removed.")

# Next, undeclare all items as records. Ps. BulkUndeclareItemsAsRecords is useless.
foreach ($record in $records) {
      [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($item)
}

Start-SPTimerJob HoldProcessing

$web.Dispose()
$site.Dispose()

 
Thanks to anavijai for the sample Hold removing code.

Chrissy is a PowerShell MVP who has worked in IT for nearly 20 years, and currently serves as a Sr. Database Engineer in Belgium. Always an avid scripter, she attended the Monad session at Microsoft’s Professional Developers Conference in Los Angeles back in 2005 and has worked and played with PowerShell ever since. Chrissy is currently pursuing an MS in Systems Engineering at Regis University and helps maintain RealCajunRecipes.com in her spare time. She holds a number of certifications, including those relating to SQL Server, SuSE Linux, SharePoint and network security. She recently became co-lead of the SQL PASS PowerShell Virtual Chapter. You can follow her on Twitter at @cl.

Posted in PowerShell, SharePoint
11 comments on “SharePoint + Powershell: Remove Hold, Record Declaration on All Documents in a Library
  1. Rebecca Ward says:

    Why is BulkUndeclareItemsAsRecords usless? Removing the holds doesn't do me much good if I can't also undeclare them. Is there another way to undeclare these files?

    • Chrissy LeMaire says:

      Rebecca, you're right: an undeclare is required. BulkUndeclareItemsAsRecords requires comma-delimited string of item IDs as input, which is buiky. Instead, I just undeclared the records as items one by one in the next three lines after the 'useless' comment.

      foreach ($record in $records) {
      [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($item)
      }

      • Karen says:

        This is exactly what I need but I am not understanding how to input the arguments. can you help with this?
        $siteURL = $args[0]
        $libraryName= $args[1]

        $site = Get-SPSite $siteURL
        $web = $site.RootWeb
        $library = $web.Lists[$libraryName]
        $records = $library.Items[0]

  2. Kelly says:

    Hi Chrissy,

    When I run this, I come across the following error. I believe the issue is on this line: $records = $library.Items[0]

    Any clues on how to get this working/can you provide an alternate script without arugements?

    Cannot index into a null array.
    At C:powershellUndeclare Records.ps1:7 char:27
    + $records = $library.Items[ <<<< 0]
    + CategoryInfo : InvalidOperation: (0:In
    + FullyQualifiedErrorId : NullArray

    Exception calling "UndeclareItemAsRecord" with "1" ar
    e null.
    Parameter name: item"
    At C:powershellUndeclare Records.ps1:10 char:86
    + [Microsoft.Office.RecordsManagement.RecordsReposito
    AsRecord <<<< ($record)
    + CategoryInfo : NotSpecified: (:) [], M
    + FullyQualifiedErrorId : DotNetMethodException

    • Hey Kelly,
      $siteURL = $args[0]
      $libraryName= $args[1]

      would be $siteURL = "http://sharepointserver/sitewithdoclib&quot;
      $libraryName = "Document Library" or whatever you named your library.

    • Sturta says:

      I'm having the same issue, same error. Even when using no arguments and the $siteURL = "http://sitename&quot;, I get the same error. I've removed the Holds section from the script, as we don't use holds.
      $siteURL = $args[0]
      $libraryName= $args[1]

      $site = Get-SPSite $siteURL
      $web = $site.RootWeb
      $library = $web.Lists[$libraryName]
      $records = $library.Items[0]

      #Undeclare all items as records.
      foreach ($record in $records) {
      [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($item)
      }

  3. Dane says:

    I will be using this string for sharepoint. Now I need to create an API string that closely resembles the online document storage command of showing all canonizations of user groups pre-defined in context.

  4. Tom Wood says:

    Ok, I made some modifications to this as it was not working for me. The main changes are:

    I removed the ‘holds’ element as we are not using holds.
    I updated the way in which the array of items in the library is obtained as I was getting only 1 item processed at array position [0].

    Here is the updated script. It now asks you to supply the site collection URL and the library name to be targeted at the console.

    Add-PSSnapin “Microsoft.SharePoint.PowerShell”

    write-host “This script will un-declare all records within a records library”

    #Get Site Collection to target from the console

    write-host “Please enter the Site Collection url of the Records Centre to be targeted”

    $siteURL = Read-host

    write-host “Please specify the name of the library to be processed”

    $libraryName= Read-Host

    $site = Get-SPSite $siteURL
    $web = $site.RootWeb
    $library = $web.Lists[$libraryName]

    # Next, undeclare all items as records.
    foreach ($item in $library.items) {

    [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($item)
    }

    $web.Dispose()
    $site.Dispose()

  5. Tom Wood says:

    Sorry, forgot to mention that with this code, you’d have to go and run the ‘Hold Processing and Reporting’ Timer Job in Central Admin if you want to be able to delete the library. If you want to do this automatically then add this line back in:

    Start-SPTimerJob HoldProcessing

  6. Nigel Price says:

    Hi
    In response to Tom’s comments.
    Dont you have to wait until the ‘Hold Processing and Reporting’ Timer Job has completed before you can do anything else programmatically. SO some sort of waitjob is required before you can do anything else.

    Regards

    Nigel

Leave a Reply

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

*