Friday, April 27, 2018

Onedrive Tips and Tricks: SharePoint sync sets every document to read-only

Issue: SharePoint sync sets every document to read-only


Onedrive Limitation: Libraries with Checkout, Required columns or metadata, or when Draft Item Security is set to either Only users who can edit or Only users who can approve items in Version Settings of the library.

Solution: For OneDrive libraries, OneDrive will show an error and the user will not be able to synchronize the library until the mentioned settings have been removed.

How to Change library settings: Library Settings > Advanced Settings and Version Settings.

Cheers!!!

Wednesday, January 24, 2018

Unable to delete SharePoint Online sub-site. Sites that have subsites or certain apps can't be deleted.

Issue Details:

You can not delete a SharePoint site which has an active sub site under it. While trying to delete you see error occurred message.

SP hosted app (deployed by user)  is also technically created as a sub-site under the site where it is activated, the sub-site can not be deleted without uninstalling/deleting the app.

Solution:
In order to remove the sub-site, we have to remove all apps on this sub-site (Remember: Not from Site Collection). (It may ask you to go back to classic experience in SharePoint Online site).

Resolution Steps:

1. Click on gear icon, go to site contents 
2. Go to app 
3. App Setting
4. Remove/delete
 
Wait for few min until the message is shown. Now try deleting the site again and it should not show any issue now. 

:) 


Thursday, January 18, 2018

Following Content feature takes you to access denied page in SharePoint online site

Issue Details: 
While trying to activate "Following Content" feature takes you to access denied page in a random SharePoint online site/sub-site.

Steps to repro: 
Go to site setting > Manage Site Features> Following Content > Click on activate > and you get access denied even if you are SCadmin.





Issue Resolution: Account used to create the site/sub-site can only activate this feature.

How to Resolve:

1. Make sure you know who created the site (Simple option > Go to site pages > default page or home page > version history > Version 1.0 modified by or created by

2. Login with that account or ask that user to login

3. Site Setting > Manage Site Features > "Following Content" > Activate.......done :)

Sunday, July 10, 2016

SharePoint Hybrid Posts

Hi, Currently working on implementation of Hybrid Search with current environment of SP 2013 and SharePoint Online Tenant. Will share my experience soon here.

Thursday, October 1, 2015

Connections to the SharePoint server are currently disabled because the project is in Offline mode


Developing SharePoint hosted app, if somehow you are not able to connect with your tenant site and provide to work in offline mode and your project go to offline mode in Visual Studio. Now to come back online to  deploy your app:

Open SharePoint project
Select solution
Click F4
You will see: Server Connection
Select : Online

Cheerssssssssss :)

Monday, July 20, 2015

SharePoint Online - Create a SharePoint Group dynamically based on the permission type to all SharePoint Sites

Scenario - Suppose you have a SharePoint site collection and you would like to add a new group to all sites and sub-sites (Unique Permissions). 

The following code creates a group to all sites based on the permission type and name it with "SITENAME_PERMISSION". You can change it to any parameter.


using (ClientContext clientContextSub = new ClientContext(strSiteUrl))
            {
                SecureString passWord = new SecureString();
                foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
     clientContextSub.Credentials = new SharePointOnlineCredentials(userName, passWord);
                clientContextSub.ExecuteQuery();
                try
                {

                 Web webSubWeb = clientContextSub.Web;
                 GroupCollection groupCollection = webSubWeb.SiteGroups;
                 clientContextSub.Load(webSubWeb.RoleAssignments);
                 clientContextSub.Load(
                 webSubWeb,
                   web2SubWebSubNode => web2SubWebSubNode.Title,
                   web2SubWebSubNode => web2SubWebSubNode.Url,
                   web2SubWebSubNode => web2SubWebSubNode.LastItemModifiedDate,
                   web2SubWebSubNode => web2SubWebSubNode.HasUniqueRoleAssignments);
                   clientContextSub.ExecuteQuery();
                  
                    if (webSubWeb.HasUniqueRoleAssignments)
                    {
                        bool _permissionGroupAvailable = false;
                        string _groupNameToAssign = string.Empty;
                        string groupOwener = string.Empty;
                        foreach (RoleAssignment assignment in webSubWeb.RoleAssignments)
                        {
                            try
                            {
                                string Role = string.Empty;
                                clientContextSub.Load(assignment.Member);
                                clientContextSub.Load(assignment.RoleDefinitionBindings);
                                clientContextSub.ExecuteQuery();

                    foreach (RoleDefinition roleDef in assignment.RoleDefinitionBindings)
                                {
//CMBAddGroup is selected permission type from a dropdown (Ex- Full Control, Read, Contribute)
       if (roleDef.Name.ToString().Trim() == cmbAddGroup.SelectedItem.ToString().Trim())
                                    {
                                        _permissionGroupAvailable = true;
                                        break;
                                    }

                                }
                                if (_permissionGroupAvailable)
                                { break; }

                            }

                            catch (Exception ex)
                            {
                               continue;
                            }
                        }
                        if (!(_permissionGroupAvailable))
                        {
                           
                           {
_groupNameToAssign = webSubWeb.Title + "_" + cmbAddGroup.SelectedItem.ToString();
GroupCreationInformation newGroupInfo = new GroupCreationInformation();
newGroupInfo.Title=_groupNameToAssign.ToString();
Group groupExist = webSubWeb.SiteGroups.GetByName(_groupNameToAssign);
                            if (groupExist == null)
                            {
Group oGroup = webSubWeb.SiteGroups.Add(newGroupInfo);
RoleDefinitionBindingCollection collRoleDefinitionBinding = new RoleDefinitionBindingCollection(clientContextSub);
RoleDefinition oRoleDefinition = webSubWeb.RoleDefinitions.GetByName(cmbAddGroup.SelectedItem.ToString());
collRoleDefinitionBinding.Add(oRoleDefinition);
webSubWeb.RoleAssignments.Add(oGroup, collRoleDefinitionBinding);
clientContextSub.Load(oGroup, group => group.Title);
clientContextSub.Load(oRoleDefinition,role => role.Name);
clientContextSub.ExecuteQuery();
                            }
                            else
                            {
RoleDefinitionBindingCollection collRoleDefinitionBinding = new RoleDefinitionBindingCollection(clientContextSub);
RoleDefinition oRoleDefinition = webSubWeb.RoleDefinitions.GetByName(cmbAddGroup.SelectedItem.ToString());
collRoleDefinitionBinding.Add(oRoleDefinition);
webSubWeb.RoleAssignments.Add(groupExist, collRoleDefinitionBinding);
clientContextSub.Load(groupExist, group => group.Title);
clientContextSub.Load(oRoleDefinition,role => role.Name);
clientContextSub.ExecuteQuery();

                            }
                            }
                            }

                       
                        }
                    }

            

                catch (Exception ex)
                {
                    helpClass.ErrorLog("", "Error MESSAGE: " + ex.Message);

                }
            }

        }


Wednesday, June 3, 2015

SharePoint Online - How to get size of a site collection Recycle Bin - First Stage Recycle Bin

Requirement - In SharePoint Online, First Stage Recycle Bin consumes your site quota space. The following code gets how much data is there under the First Stage Recycle Bin.

Note - Always pass Site URL. Web URL will not work and always return 0.

Function getRecycleBinSize takes URL is parameter and stores all results in a data table.

public void getRecycleBinSize(string URL)
        {
            DataTable dtRecycleBin = new DataTable();
            using (ClientContext clientContext = new ClientContext(URL))
            {
                SecureString passWord = new SecureString();
                foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
                clientContext.Credentials = new SharePointOnlineCredentials(userName, passWord);
                Site s = clientContext.Site;
                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.Load(s);
                clientContext.Load(s.RecycleBin);
                clientContext.ExecuteQuery();
                if(dtRecycleBin.Columns.Count==0)
                {
                dtRecycleBin.Columns.Add(constantVariables.Title);
                dtRecycleBin.Columns.Add(constantVariables.deletedBy);
                dtRecycleBin.Columns.Add(constantVariables.deletionDate);
                dtRecycleBin.Columns.Add(constantVariables.location);
                dtRecycleBin.Columns.Add(constantVariables.itemState);
                dtRecycleBin.Columns.Add(constantVariables.itemType);
                dtRecycleBin.Columns.Add(constantVariables.leafName);
                dtRecycleBin.Columns.Add(constantVariables.size);
                }
             
                RecycleBinItemCollection recyclebinItemCollection = s.RecycleBin;
                clientContext.Load(recyclebinItemCollection);
                clientContext.ExecuteQuery();
                int count = recyclebinItemCollection.Count;
                int i = 0;
                foreach (RecycleBinItem item in recyclebinItemCollection)
                {                  
                   
                    if (item.ItemState.ToString().ToLower() == "FirstStageRecycleBin".ToLower())
                    {
                        DataRow newRow = dtRecycleBin.NewRow();
                        dtRecycleBin.Rows.Add(newRow);
                        newRow[0] =  item.Title.ToString() ;
                        newRow[1] =  item.DeletedBy.ToString();
                        newRow[2] =  item.DeletedDate ;
                        newRow[3] =  item.DirName ;
                        newRow[4] =  item.ItemState ;
                        newRow[5] =  item.ItemType ;
                        newRow[6] =  item.LeafName;
                        newRow[7] =  item.Size ;
                    }
                    i++;
                                   
                }
            }
            dataGridView2.DataSource = null;
            dataGridView2.DataSource = dtRecycleBin;
        }

Thursday, May 28, 2015

SharePoint Online - Add User to SharePoint Security Group with a specific permission

The following code can be used to add user to a specific group.

Requirement - Business want to add a specific user to a site collection and all it's sub-site in a specific group. Ex: Full Control or Read or Edit.


using (ClientContext clientContextSub = new ClientContext(siteUrl))
                        {
                            SecureString passWord = new SecureString();
                            foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
                clientContextSub.Credentials = new SharePointOnlineCredentials(userName, passWord);
                            Web webSubWeb = clientContextSub.Web;
                            GroupCollection groupCollection = clientContextSub.Web.SiteGroups;
                            UserCollection ucol = clientContextSub.Web.SiteUsers;
                            clientContextSub.Load(webSubWeb);
                            clientContextSub.ExecuteQuery();

                           //txtAddUserToGroup is a text file to add to groups
                            Principal user = ucol.GetByEmail(txtAddUserToGroup.Text.ToString().Trim());
                            clientContextSub.Load(user);
                            clientContextSub.ExecuteQuery();


// dtGroupUsers is a datatable logging who's being added to which group with other information
                            if (dtGroupandUsers.Rows.Count == 0)
                            {
                                if(dtGroupandUsers.Columns.Count==0)
                                {
                                dtGroupandUsers.Columns.Add(constantVariables.SiteURL);
                                dtGroupandUsers.Columns.Add(constantVariables.Title);
                                dtGroupandUsers.Columns.Add(constantVariables.userGroups);
                                dtGroupandUsers.Columns.Add(constantVariables.userLogin);
                                dtGroupandUsers.Columns.Add(constantVariables.emailAddress);
                                dtGroupandUsers.Columns.Add(constantVariables.name);
                                dtGroupandUsers.Columns.Add(constantVariables.LastModified);
                                dtGroupandUsers.Columns.Add(constantVariables.siteInheritance);
                                dtGroupandUsers.Columns.Add(constantVariables.groupOwner);
                                dtGroupandUsers.Columns.Add(constantVariables.permission);
                                }
                            }
                            else
                            { dtGroupandUsers.Rows.Clear(); }          
                            if (user != null)
                            {
                                addUsertoGroup(webSubWeb, clientContextSub,user);
                             
                            }
                            }
                    }

///***Other Function ***///
public void addUsertoGroup(Web webSubWeb, ClientContext clientContextSub, Principal user)
        {
string groupOwener = string.Empty;
            clientContextSub.Load(webSubWeb);
            clientContextSub.Load(webSubWeb.Webs);
            clientContextSub.Load(webSubWeb.RoleAssignments);
            clientContextSub.ExecuteQuery();
            foreach (RoleAssignment assignment in webSubWeb.RoleAssignments)
            {
                string Role = string.Empty;
                clientContextSub.Load(assignment.Member);
                clientContextSub.Load(assignment.RoleDefinitionBindings);
                GroupCollection groupCollection = webSubWeb.SiteGroups;
                clientContextSub.ExecuteQuery();
                foreach (RoleDefinition roleDef in assignment.RoleDefinitionBindings)
                {
                    if (roleDef.Name != string.Empty)
                    {
                       //cmbUserCollection.Text  is a dropdown control and user has selected "Full Control" and any group having permission "Full Control" with add this user.

      if (roleDef.Name.ToString().ToLower() == cmbUserCollection.Text.ToString().ToLower())
                        {
                            int Cnt = assignment.RoleDefinitionBindings.Count;
                            Principal Pri = assignment.Member;
                            if (Pri.PrincipalType == PrincipalType.SharePointGroup)
                            {                              
                                UserCreationInformation userCreationInfo = new UserCreationInformation();
                                userCreationInfo.Email = user.LoginName;
                                userCreationInfo.LoginName = user.LoginName;
                                userCreationInfo.Title = user.Title;
                                Group grp = groupCollection.GetByName(Pri.LoginName);
                                clientContextSub.Load(grp);
                                clientContextSub.ExecuteQuery();
                               
                                grp.Users.Add(userCreationInfo);
                             
                                    DataRow dtGU = dtGroupandUsers.NewRow();
                                    dtGroupandUsers.Rows.Add(dtGU);
                                    dtGU[0] = "\"" + webSubWeb.Url.ToString() + "\"";
                                    dtGU[1] = "\"" + webSubWeb.Title.ToString() + "\"";
                                    dtGU[2] = "\"" + grp.Title.ToString() + "\"";
                                    dtGU[3] = "\"" + user.LoginName.ToString() + "\"";
                                    if (user.LoginName.Contains('#'))
                                    {
dtGU[4] = "\"" + user.LoginName.Substring(18, (user.LoginName.Length - 18)).Trim() + "\""; }
                                    dtGU[5] = "\"" + user.Title.ToString() + "\"";
                                    dtGU[6] = "\"" + webSubWeb.LastItemModifiedDate;
                                    dtGU[7] = "";
                                    dtGU[8] = "\"" + grp.OwnerTitle.ToString() + "\"";
                                    dtGU[9] = roleDef.Name.ToString();
                            }              
                        }            
                    }
                }
               
            }
           
            if (webSubWeb.Webs.Count > 0)
            {
                foreach (Web web in webSubWeb.Webs)
                {
                    addUsertoGroup(web, clientContextSub, user);

                }
           
            }}

Monday, February 23, 2015

Adding Content Menu and Custom Menu items on a tree node - Windows Application using C#

This code shows how you can add a context menu with the context menu items to your window application on a tree node.

ToolStripMenuItem siteSettings = new ToolStripMenuItem();
            siteSettings.Text = "Site Settings";
            siteSettings.BackColor = Color.AliceBlue;
            siteSettings.Image = imageList1.Images[5];

            ToolStripMenuItem lstContentTypeReport = new ToolStripMenuItem();
            lstContentTypeReport.Text = "Lists Content Types";
            lstContentTypeReport.BackColor = Color.AliceBlue;
            lstContentTypeReport.Image = imageList1.Images[5];

            ToolStripMenuItem treeStructure = new ToolStripMenuItem();
            treeStructure.Text = "Site Structure";
            treeStructure.BackColor = Color.AliceBlue;
            treeStructure.Image = imageList1.Images[15];


            ToolStripMenuItem manageAuditSettings = new ToolStripMenuItem();
            manageAuditSettings.Text = "Manage Audit Settings";
            manageAuditSettings.BackColor = Color.AliceBlue;
            manageAuditSettings.Image = imageList1.Images[15];

            ToolStripMenuItem manageSPAlerts = new ToolStripMenuItem();
            manageSPAlerts.BackColor = Color.AliceBlue;
            manageSPAlerts.Text = "Manage ShaerPoint Alerts";
            manageSPAlerts.Image = imageList1.Images[14];

            ToolStripMenuItem addUsers = new ToolStripMenuItem();
            addUsers.Text = "Add Users";
            addUsers.BackColor = Color.AliceBlue;
            addUsers.Image = imageList1.Images[13];

            ToolStripMenuItem siteStorageAnalysis = new ToolStripMenuItem();
            siteStorageAnalysis.Text = "Site Storage Analysis";
            siteStorageAnalysis.BackColor = Color.AliceBlue;
            siteStorageAnalysis.Image = imageList1.Images[12];

            ToolStripMenuItem sitePemissions = new ToolStripMenuItem();
            sitePemissions.Text = "Site Permissions";
            sitePemissions.BackColor = Color.AliceBlue;
            sitePemissions.Image = imageList1.Images[11];

            ToolStripMenuItem findUserSecurity = new ToolStripMenuItem();
            findUserSecurity.Text = "Find User Security";
            findUserSecurity.BackColor = Color.AliceBlue;
            findUserSecurity.Image = imageList1.Images[10];
            contextMenuStrip2.Items.AddRange(new ToolStripMenuItem[] { siteSettings, lstContentTypeReport, manageAuditSettings, treeStructure, manageSPAlerts, addUsers });
            contextMenuStrip2.Items.Add(new ToolStripSeparator());
            contextMenuStrip2.Items.AddRange(new ToolStripMenuItem[] { siteStorageAnalysis, sitePemissions, findUserSecurity });



                Treenode Control:


                         TreeNode Groups = new TreeNode("Sites");                     
                  

                        Groups.ContextMenuStrip = groupContextMenu;

SharePoint Online - Connect and fetch information usign client side object model (C#)

Below code example shows how to connect to a tenant application and iterate through with all the site collections.

Tip: Assuming you have permission to read content to all site collection under this tenant.
 If not, use proper try catch with continue option. J

Step 1 - Add reference for the following assemblies. 

using Microsoft.Online.SharePoint.TenantAdministration;
using Microsoft.SharePoint.Client;

Step 2 -
string userName = "";
string passWord = "";

using (ClientContext clientContext = new ClientContext(txtTenantUrl.Text))
            {

                SecureString passWord = new SecureString();
           foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
           clientContext.Credentials = new SharePointOnlineCredentials(userName, passWord);

                Tenant tenant = new Tenant(clientContext);
                SPOSitePropertiesEnumerable spp = tenant.GetSiteProperties(0, true);
                clientContext.Load(spp);
                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.Load(web.Webs);
                clientContext.Load(clientContext.Web.SiteGroups);
                clientContext.Load(clientContext.Web.SiteUsers);
                clientContext.ExecuteQuery();

                foreach (SiteProperties sp in spp)
                {
                   
                              string owner = sp.Owner.ToString();
                    string URL = sp.Url.ToString();
                    string webCount = sp.WebsCount.ToString();
                    string webLastModified = sp.LastContentModifiedDate.ToString();
                    string webStatus = sp.Status.ToString();
                    string webStorage = sp.StorageUsage.ToString();
                    string level = sp.StorageMaximumLevel.ToString();
string contentLastModified = sp.LastContentModifiedDate.ToString();
                }
               
            }