{"id":1002,"date":"2012-05-28T21:05:28","date_gmt":"2012-05-28T20:05:28","guid":{"rendered":"http:\/\/www.stuartroberts.net\/?p=1002"},"modified":"2013-05-10T14:22:20","modified_gmt":"2013-05-10T13:22:20","slug":"export-metadata-terms","status":"publish","type":"post","link":"http:\/\/www.stuartroberts.net\/index.php\/2012\/05\/28\/export-metadata-terms\/","title":{"rendered":"Export MetaData Terms"},"content":{"rendered":"<p>Central administration provides a way to import metadata term sets and terms by uploading a CSV file.  However, it does not provide a mechanism for exporting terms to a CSV.<\/p>\n<p>There are quite a lot of PowerShell and command line utilities on the web for accomplishing this, however, the ones that I found did not cater for terms that are more than one level deep.  After all, you can create a term hierarchy that is up to seven levels deep.<\/p>\n<p>So, to help fill this gap I&#8217;ve written a simple PowerShell script that does exactly this.<\/p>\n<p>One caveat with importing CSV files through Central Administration is that it can only import one term set per CSV.  So when exporting more than one set you have to create a separate file for each of them.  You&#8217;d have thought the import script would have been able to handle multiple sets&#8230;<br \/>\n<!--more--><br \/>\nThe PowerShell script that I&#8217;ve written allows you to specify a single term group to export. It will be easy to modify to export all (or a specific set of) term groups if required.<\/p>\n<p>I&#8217;ll provide a link to the complete script at the end of this post, so won&#8217;t show the entire script here, just the main functions.<\/p>\n<pre lang=\"powershell\">\r\nfunction Export-SPTerms {\r\n  param (\r\n        [string]$siteUrl = $(Read-Host -prompt \"Please provide the site collection URL\"),\r\n        [string]$termGroupName = $(Read-Host -prompt \"Please provide the term group name to export\"),\r\n        [string]$saveLocation = $(Read-Host -prompt \"Please provide the path of the folder to save the CSV file to\")\r\n  )\r\n\t\r\n  if ([IO.Directory]::Exists($saveLocation) -eq $false)\r\n  {\r\n    New-Item ($saveLocation) -Type Directory | Out-Null\r\n  }\r\n\t\r\n  $taxonomySession = Get-SPTaxonomySession -site $siteUrl\r\n  $taxonomyTermStore =  $taxonomySession.TermStores | Select Name\r\n  $termStore = $taxonomySession.TermStores[$taxonomyTermStore.Name]\r\n\t\r\n  # Ampersands are stored as fullwidth ampersands (see http:\/\/www.fileformat.info\/info\/unicode\/char\/ff06\/index.htm)\r\n  [Byte[]] $amp = 0xEF,0xBC,0x86\r\n\t\r\n  foreach ($group in $termStore.Groups) {\r\n    if ($group.Name -eq $termGroupName) {\r\n      foreach ($termSet in $group.TermSets) {\r\n        # Remove unsafe file system characters from filename\r\n        $parsedFilename =  [regex]::replace($termSet.Name, \"[^a-zA-Z0-9\\\\-]\", \"_\")\r\n        $file = New-Object System.IO.StreamWriter($saveLocation + \"\\termset_\" + $parsedFilename + \".csv\")\r\n\t\t\t\r\n        # Write out the headers\r\n        $file.Writeline(\"Term Set Name,Term Set Description,LCID,Available for Tagging,Term Description,Level 1 Term, Level 2 Term,Level 3 Term,Level 4 Term,Level 5 Term,Level 6 Term,Level 7 Term\")\r\n\t\t        \r\n        try {\r\n          Export-SPTermSet $termSet.Terms\r\n        }\r\n        finally {\r\n          $file.Flush()\r\n          $file.Close()\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>This function accepts various parameters for configuring which term store group to export and the location to save the CSV file(s).<\/p>\n<p>Next, it iterates through the top level term sets for the specified group and generates a CSV file to store the terms for the current term set.  It also adds the headers to the first row.  As you can see, it adds seven columns for storing up to the maximum allowable number of term levels.<\/p>\n<p>Lastly, this function calls the <em>Export-SPTermSet<\/em> function which will export the term set&#8217;s terms to the CSV file.<\/p>\n<pre lang=\"powershell\">\r\nfunction Export-SPTermSet {\r\n  param (\r\n        [Microsoft.SharePoint.Taxonomy.TermCollection]$terms,\r\n\t\t[int]$level = 1,\r\n\t\t[string]$previousTerms = \"\"\r\n  )\r\n\t\r\n  if ($level -ge 1 -or $level -le 7) {\r\n    if ($terms.Count -gt 0 ) {\r\n      $termSetName = \"\"\r\n      if ($level -eq 1) {\r\n        $termSetName =  \"\"\"\" + $terms[0].TermSet.Name.Replace([System.Text.Encoding]::UTF8.GetString($amp), \"&\") + \"\"\"\"\r\n      }\r\n\r\n      $terms | ForEach-Object {\r\n        $currentTerms = $previousTerms + \",\"\"\" + $_.Name.Replace([System.Text.Encoding]::UTF8.GetString($amp), \"&\") + \"\"\"\";\r\n\t\t\t\t\r\n        $file.Writeline($termSetName +\r\n                        \",\"\"\" + $_.TermSet.Description + \"\"\"\" + \r\n                        \",,\" + $_.IsAvailableForTagging +\r\n                        \",\" + $_.GetDescription() + $currentTerms);\r\n\t\t\t\t\r\n        if ($level -lt 7) {\r\n          Export-SPTermSet $_.Terms ($level + 1) ($previousTerms + $currentTerms)\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>This function recursively calls itself up to seven times, depending on how far down the hierarchy the terms go for a particular term set.<\/p>\n<p>As promised, here&#8217;s a link to the <a href='http:\/\/www.stuartroberts.net\/wp-content\/uploads\/2012\/05\/Export-TermSets.zip'>complete script<\/a>, which works for both SharePoint 2010 and 2013.  For 2013, make a small change to the script so the SharePoint assembly being referenced is version 15.0.0.0 instead of 14.0.0.0.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Central administration provides a way to import metadata term sets and terms by uploading a CSV file. However, it does not provide a mechanism for exporting terms to a CSV. There are quite a lot of PowerShell and command line &hellip; <a href=\"http:\/\/www.stuartroberts.net\/index.php\/2012\/05\/28\/export-metadata-terms\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[3,8],"tags":[41,81,83],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/plx2I-ga","_links":{"self":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1002"}],"collection":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/comments?post=1002"}],"version-history":[{"count":14,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1002\/revisions"}],"predecessor-version":[{"id":1469,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/posts\/1002\/revisions\/1469"}],"wp:attachment":[{"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/media?parent=1002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/categories?post=1002"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.stuartroberts.net\/index.php\/wp-json\/wp\/v2\/tags?post=1002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}