Thursday, May 24, 2012

Synch User Fields when copying lists from one sitecollection to another

If you copy a list from one sitecollection to another one with a list template and the copied list has user fields than you'll have other users in the destionation list.

This occures because SharePoint saves all user in a own UserInfo table for each sitecollection. A user in SiteCollection 1 can have the ID 5 and in another the ID 3.

As the SPUserField is a LookUp Field to the User Info List the name of the User in the destination list can change.

Two little PowerShell Scripts can help here. The first one reads the user info for a field in the source list and creates a csv with the information. The second one reads the csv and updates the destination list. Copy the code to two .ps1 files.

Open the SharePoint 2010 Management Shell and run the "Dump user Info" script to dump the infos to a .csv file. Afterwards run the second script to update the destination list.


Dump User Info

 # Adapt these values  
 $web = Get-SPWeb "http://sharepoint/sites/sourcelist/"   
 $list = $web.Lists["SourceList"]  
 $field = "UserField"  
 $csv = "C:\temp\user.csv"  
 # ---------------------  
 $userInfos = @()  
 foreach($item in $list.Items) {  
   $userFld = [Microsoft.SharePoint.SPFieldUser] $item.Fields.GetField($field)    
   if ($null -ne $userFld) {          
     if ($null -ne $item[$field]) {  
       $fieldVal = new-object Microsoft.SharePoint.SPFieldUserValue($web, $item[$field].ToString())      
       if ($null -ne $fieldVal){  
         $user = $fieldVal.User        
         $userInfos += New-Object PSObject -Property @{  
           Title = $item.Title  
           Login = $user.LoginName  
         }  
       }  
     }  
   }else{  
     Write-Host "Field: " $field " not found in list!" -foregroundcolor red  
   }  
 }  
 $userinfos | Export-CSV $csv -NoTypeInformation  
 Write-Host "END - Script"  

UpdateUser Info

 $web = Get-SPWeb "http://sharepoint/sites/io/"   
 $list = $web.Lists["Services"]  
 $field = "Verantwortlich_x0020__x0028_ad_x"  
 $items = $list.Items  
 $csv = "C:\temp\user.csv "  
 $log = "C:\temp\usersynch.log"  
 Start-Transcript -path $log   
 $import = Import-Csv $csv  
 foreach ($obj in $import)  
 {   
   Write-Host "Searching for " $obj.Title -foregroundcolor blue  
   $items | Where-Object { $_.Title -eq $obj.Title} | foreach {  
     Write-Host " >> Updating item to new user: " $obj.Login -foregroundcolor green  
     try  
     {  
       $_[$field] = $web.EnsureUser($obj.Login).ID  
       $_.Update()      
     } catch [Microsoft.SharePoint.SPException] {  
       Write-Host " >> Error: could not find user: " $obj.Login -foregroundcolor red            
     }   
   }  
   Write-Host ""  
 }  
 Write-Host "End Synch Process"  
 Stop-Transcript  

Tuesday, May 8, 2012

Copy SharePoint Lists between sites with different language templates

An easy way to copy a list with content between to sites is to create a list template, upload it in the other site to the list template gallery and create a new list with the uploaded template.

The problem starts when the site templates have different languages. For example you create a list template in a site with english site template and you upload it to a site with a german site template, you'll not see the template in the create page.

A way to change this ist to modify the.stp file, which is created when you make the list template. SO the first steps are:
  1. Create a list template. You can do this in the list settings. Just click "Save list as template" and give in the the filename and the template name.
  2. Download the created template to a local folder.

Extract the template file

Now we will modify the .stp file. An .stp file is nothing more than a microsoft cabinet file. Therefore rename the file from "mylist.stp" to "mylist.cab". You can now open the file and see all the compressed files inside.

The next step is to make a local folder e.g "C:\temp\mylist" where we'll copy all files within the cab file. So open  the cap file and drag all files inside to the mylist folder. As it's a cab file you can't copy the files, you have the drag them with the mouse.

Afterwards open the manifest.xml in the mylists folder and change the language code within the xml to the destination language code. (See Language Codes )

<Language>1031</Language>

Create a new template

In this step we create the stp again. Unfortunately it is not so easy as it seems to be. First of all we have to create a .ddf file. Create a new file in the mylist folder and rename it to "definition.ddf".

Open the .ddf file and paste the fallowing code inside:

; DIAMOND Directive File (.ddf)
.OPTION EXPLICIT
; Generate errors on variable typos
.Set CabinetNameTemplate=mylist.stp
.Set Cabinet=on
.Set Compress=on

;The files specified below are stored, compressed, in the cabinet file
30000000.000
manifest.xml

In the last section write down all the files which should be within the new .stp file. These should be all except the .ddf file.

You can also change the CabinetTemplateName. This is the name of the file, but this is not important for us.

Create cabinet

Open the DOS command promp and go to the mylists folder. Type the following command:

makecab /f definition.ddf



The result should end in a mylist.stp file within a subfolder. You can now go and upload the new .stp file to the list gallery of your destination site.

The list template should be finally visible in the list create dialog.

Monday, May 7, 2012

Item-Level Permission for a SharePoint Document Library

The SharePoint Document Library doesn't have the option in his UI-Settings to change the item-level permisssions like normal SharePoint lists.

This means that you can't create a document library in which only user who created the documents can only see their documents and no one else.

You can simulate the behaviour by changing the permissions on each single document but this could be expensive and could also cause performance issues on  large libraries.

The better option is the activate the item level security by PowerShell. It seems that Microsoft  only disabled the UI Option but with PowerShell you can reactivate it. I don't know why Microsoft disabled this option but in my tests this method worked very well.

 $web = Get-SPWeb http://YourSite/  
 $list = $web.Lists["Your Document Library Name"]  
 $list.ReadSecurity = 2  
 $list.Update()  
 $web.Dispose()  

What the values for ReadSecurity property means can be seen here.

There is also a property for the writesecurity, that you can use to enable users to edit only their own items.

Sources