Monday 19 August 2013

Export document set to XML

This script pulls a document set out of SharePoint and saves it to your hard drive.

#load SharePoint Powershell snap in
Add-PSSnapin "Microsoft.Sharepoint.PowerShell" -ErrorAction SilentlyContinue

   Save document set to hard drive
      Iterates through each tender in document set and procededs to save them to the local hard drive.
   retrieve-ccwTenders -siteUrl http://wingtipserver -listName MyDocumentSet -savePath c:\
function retrieve-ccwTenders
            #Site url for the sharepoint collection
                           HelpMessage="Enter in the site URL where the Tenders Documnet set resides")]
            [ValidateScript({Get-SPSite -Identity $_ | Select-Object -Property Exists -ErrorAction SilentlyContinue})]
            #The name of the documents set
                           HelpMessage = "Enter in the Display Name of the Document set")]
            #The path where to save your Tenders
             HelpMessage = "Enter the file path where to save your tenders document set")]
            [ValidateScript({Test-Path $_})]

            #get site using user supplied parameter
            $site = Get-SPSite($siteUrl)

            #get the Root web of the site
            $rootWeb = $site.RootWeb
            #get Documnet Set instance
            $DocumentSet = $rootWeb.Lists.TryGetList($listName)
            #make sure the document set is not null
            if($DocumentSet -ne $null)
                  #iterate through all documents sets(tenders)
                  $DocumentSet.Items | foreach {
                        #ensure that item is a document set
                        if($_["HTML File Type"] -eq "SharePoint.DocumentSet")
                              SaveDocSetMetadata $_
                        elseif($_["HTML File Type"] -eq $null)
                              #save the document to folder & Append File metadata to XML Document
                              SaveDocSetDocument $_

function SaveDocSetMetadata($docset)
      $DocsetSavePath = [System.IO.Path]::Combine("$savePath\DocumentSet", $docset.Title)
      #create folder on HD to store Tender Data
      if((Test-Path $DocsetSavePath) -eq $false)
            New-Item -ItemType directory -Path $DocsetSavePath | Out-Null
      #create xml object in memory
      $docsetXML = New-Object Xml
      #create xml declaration
      [System.Xml.XmlDeclaration] $xmlDeclaration = $docsetXML.CreateXmlDeclaration("1.0", "UTF-16", $null);
      $docsetXML.AppendChild($xmlDeclaration)  | Out-Null
      #create Root Node
      $root = $docsetXML.CreateElement("DS")   
      $docsetXML.AppendChild($root) | Out-Null
      #create metadata node
      $metadata = $docsetXML.CreateElement("Metadata")
      $root.AppendChild($metadata)  | Out-Null
      #get relevent metaData for tender
      $docset.Fields | foreach {   
            $data = $docsetXML.CreateElement("Data")
            $data.InnerText = $docset[$_.Title]
            $data.SetAttribute("Title", $_.Title)
            $data.SetAttribute("InternalName", $_.InternalName)
            $data.SetAttribute("ReadOnly", $_.ReadOnlyField)
            $metadata.AppendChild($data)  | Out-Null 
      #save xml object to file
      $temp = $docsetXML.Save("$DocsetSavePath\Tender.xml")
      Write-output "Created $DocsetSavePath/Tender.xml"

function SaveDocSetDocument($docset)
      $wc = New-Object System.Net.WebClient
      $source = $docset["Encoded Absolute URL"]
      $folder = $docset["Path"].Substring($docset["Path"].lastindexof("/")+1)
      $fileName = $docset["FileLeafRef"]
      $destination = [System.IO.Path]::Combine("$savePath\DocumentSet", $folder)
            $wc.DownloadFile($source, [System.IO.Path]::Combine($destination, $fileName))

      #Get the xml File path
      $xmlPath = [System.IO.Path]::Combine($destination, "Tender.xml")
      #get the xml document
      [xml]$docsetXML = Get-Content -Path $xmlPath
      #get the last element in the xml document
      $lastChild = $docsetXML.DS.get_LastChild()
      #check if the last element is <files />, create one if it isn't
      if($lastChild.Name -eq "Files")
            $files = $lastChild
            $files = $docsetXML.CreateElement("Files")
      #grab the <files /> element
      $filesNode = $docsetXML.DS.AppendChild($files)
      #create a <file /> element         
      $file = $docsetXML.CreateElement("File")

      $file.SetAttribute("ContentType", $docset["Content Type"])
      $file.SetAttribute("SortOrder", $docset["Sort Order"])
      $file.SetAttribute("FilePath"$folder + "\" + $fileName)
      $file.SetAttribute("urlPath", $docset["Server Relative URL"])
      #append the <file /> element to the <files /> element
      $file = $filesNode.AppendChild($file)  | Out-Null
      #save xml changes