Thursday, August 22, 2013

Create "Shared with Everyone" folder in Sky Drive Pro / Documents library - SharePoint 2013

Introduction

As I mentioned in my previous post our team faced issues in document migration from SharePoint 2010 to SharePoint 2013. The actions were not as expected.

Problem Background

In some profile we couldn't find "Shared with Everyone" which folder is having "Read" permission to "All Authenticated Users". So we created a console application which will create "Shared with Everyone" folder and set the permission as we needed.

Solution

Please pass your personal site (spWeb) to the method.

   
 public static void CreateSharedFolder(SPWeb web)
 {

    SPList list = (SPDocumentLibrary)web.Lists["Documents"];
    //Get the folders inside Documents library
    SPFolderCollection folders = web.GetFolder(list.RootFolder.Url).SubFolders;
    List<string> folderList = new List<string>();
    //Add the SPFolderCollection to a generic list
    foreach (SPFolder folder in folders)
    {
        folderList.Add(folder.Name);
    }
    //Check whether folder list has shared with everyone folder
    if (!folderList.Contains("Shared with Everyone"))
    {

       //Create folder inside Documents library 
       folders.Add("Shared with Everyone");

       //Greate users
       SPUser allUser = web.EnsureUser("NT AUTHORITY\\authenticated users");
       //Get folder
       SPListItem item = list.Folders[0];
       if (!item.HasUniqueRoleAssignments)
           item.BreakRoleInheritance(true);

       SPRoleAssignment roleAssignment = new SPRoleAssignment(allUser);
       SPRoleDefinition roleDefination = web.RoleDefinitions["Read"];
                //Add role assignment
       roleAssignment.RoleDefinitionBindings.Add(roleDefination);
       item.RoleAssignments.Add(roleAssignment);
       web.AllowUnsafeUpdates = true;
       item.Update();
       web.AllowUnsafeUpdates = false;

    }

}
 
 


Conclution
Now you can see "Shared with Everyone" folder inside SkyDrive pro.

Thursday, August 15, 2013

Move (Personal) Documents into SkyDrive Pro after migrating from SharePoint 2010 to SharePoint 2013

Introduction

If you have working on migrating SharePoint 2010 personal sites to SharePoint 2013 personal sites;  documents migration may become a headache. The expectation of the action is
"The Personal and Shared document libraries in SharePoint Server 2010 are combined into the SkyDrive Pro document library on the user's My Site in SharePoint Server 2013. Items from the Shared folder are stored in the Shared with Everyone folder in SharePoint Server 2013. Items from the Personal folder are stored at the root of the SkyDrive Pro document library and only shared with the owner of the My Site." - MicroSoft

Problem Background

But in our case, the documents didn't shift under SkyDrive but they were seen under site contents as another document library.

So I wrote a console application to move all the documents to SkyDrive. Here I'm presenting a simple code snippet which you have to modify to use other document library and sub folders under document library. 

Solution 

private static void MovePersonalDocuments(SPWeb web)
{
 SPFolder folder = web.GetFolder("Personal Documents");
 SPFileCollection collFile = folder.Files;
 ///*Copy the files to a generic List of type SPFile*/
 List listFiles = new List(collFile.Count);
 foreach (SPFile oFile in collFile)
 {
  listFiles.Add(oFile);
 }
 SPList list = (SPDocumentLibrary)web.Lists["Documents"];
 for (int i = 0; i &lt; listFiles.Count; i++)
 {
    SPFile movefile = collFile[0];
    Console.WriteLine("Moving File: " + movefile.Name);
           web.AllowUnsafeUpdates = true;
    byte[] fileBytes = movefile.OpenBinary();
    string destUrl = list.RootFolder.Url + "/" + movefile.Name;
    movefile.MoveTo(destUrl, true);
           web.AllowUnsafeUpdates = false;
   Console.WriteLine("Success");
 }
}

Conclusion 

  • Please note that I have only considered moving Personal Documents.
  • The code will help to move Shared Documents and Sub folders as well. 

Sunday, August 4, 2013

"MissingAssembly" Error after Migrating from SharePoint 2010 to SharePoint 2013

Introduction

As I mentioned in a earlier post; I started working on Migration from SharePoint 2010 to SharePoint 2013 and power shell scripting.

Problem Background


After the migration we TEST-SPContentDatabase -Name "Name of the Content Database" -WebApplication "Name of the WebApplication"  > C:\test.txt in order to test the migrated database. 

In the text file we were able to find some migrated issues. One of that is MissingAssembly. So here I'm going to show how to solve it. 

Solution 

Please note that I used Phil Childs post in order to achieve this. http://get-spscripts.com/2011/08/diagnose-missingwebpart-and.html. I have automated by getting the missing assembly details to a text file and then getting the necessary details from the text file and removing the Event receiver, For more information please read Phil's post. 

Here is the code. 

You have to change the lines which are bold and italic, according to your data. 
Add-PSSnapin Microsoft.SharePoint.PowerShell
function Run-SQLQuery ($SqlServer, $SqlDatabase, $SqlQuery)
{
   $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
   $SqlConnection.ConnectionString = "Server =" + $SqlServer + "; Database =" + $SqlDatabase + "; Integrated Security = True"
   $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
   $SqlCmd.CommandText = $SqlQuery
   $SqlCmd.Connection = $SqlConnection
   $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
   $SqlAdapter.SelectCommand = $SqlCmd
   $DataSet = New-Object System.Data.DataSet
   $SqlAdapter.Fill($DataSet)
   $SqlConnection.Close()
   $DataSet.Tables[0]
}

Run-SQLQuery -SqlServer "Name of the SQL Server" -SqlDatabase "Name of the Content DB" -SqlQuery "SELECT * from EventReceivers where Assembly = 'Virtusa.Vplus.Leaderboards.EventReceivers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c3202aa47f1aa64d'" | select Id, Name, SiteId, WebId, HostId, HostType | Format-List | out-file -filepath "C:\Data.txt" 


$textData = Get-Content C:\Data.txt

for($i=0; $i -le $textData.Length - 1; $i++)
{
   $test = $textData.Get($i)
   if($test.StartsWith("Id"))
   {
       $test -match "Id       : (?.*)"
       $Id = $matches['id']
       Write-Host "Id: $Id"
    }
    if($test.Contains("SiteId"))
    {
      $test -match "SiteId   : (?.*)"
      $SiteId = $matches['SiteId']
      Write-Host "SiteId: $SiteId"
    }
    if($test.Contains("WebId    : "))
    {
       $test -match "WebId    : (?.*)"
       $WebId = $matches['WebId']
       Write-Host "WebId: $WebId"
    }
    if($test.Contains("HostId   : "))
    {
       $test -match "HostId   : (?.*)"
       $HostId = $matches['HostId']
       Write-Host "HostId: $HostId"
       try
       {
        $site = Get-SPSite -Limit all | where {$_.Id -eq $SiteId}
        $web = $site | Get-SPWeb -Limit all | where {$_.Id -eq $WebId}
        write-Host "Web Url:" $web.Url
        write-Host "Site Url:" $site.Url
        $list = $web.Lists | where {$_.Id -eq $HostId}
        write-Host "List Name:" $list.Title

        $er = $list.EventReceivers | where {$_.Id -eq $Id}
        $er.Delete()
        write-Host "Deleted Successfully"

        }
        catch
        {
         Write-Host "Cannot Delete"
        }
   }
     
}

Conclusion

  • Running this script will take a long time. So please schedule the time frame before start running the script.