Showing posts with label Saratchandra Peddinti. Show all posts
Showing posts with label Saratchandra Peddinti. Show all posts

Wednesday, August 31, 2016

Full Farm Backup fails - Causes and Solutions

Requirements to check before moving on to the Errors section..

  1. Shared Folder need to be created & full control has to be granted to timer job, SQL Server service accounts and CA's app pool account
  2. SQL Server VSS Writer service, that facilitates the backup/restore, should be running
  3. SharePoint Administration Service should be running on all servers of the farm

Error 1: Here WSS_xxx is any database.

Object WSS_XXXX failed in event OnBackup. For more information, see the spbackup.log or sprestore.log file located in the backup directory. SqlException: Cannot open backup device '\\Backup\spbr0000\0000015d.bak'. Operating system error 3(The system cannot find the path specified.). BACKUP DATABASE is terminating abnormally.

Possible Reason Solution
The path given for the backup is wrong Check the path & Correct it. It must be a Shared folder
Insufficient privileges, i.e. The Windows SharePoint Services Timer V4 (SPTimerV4) and the SQL Server service account perform backup/restore operations on behalf of the requested user. Hence these accounts should have full control on the backup locations While sharing the folder, granting 'Full Control' to 'Everyone' will not work. The domain account(ideally), under which the Timer Service & SQL Server service execute, should be explicitly granted 'Full Control' on the shared folder

Find SQL Server Accounts that carry out backup/restore by checking the below services...

SQLService.png

Sharing the folder:

Folder Sharing

Error 2: User Profile Synchronization service instance causes this issue.

FatalError: Object UPS failed in event OnBackup. For more information, see the spbackup.log or sprestore.log file located in the backup directory. SPDuplicateObjectException: An object of the type Microsoft.Office.Server.Administration.ProfileSynchronizationUnprovisionJob named "ProfileSynchronizationUnprovisionJob" already exists under the parent Microsoft.SharePoint.Administration.SPTimerService named "SPTimerV4". Rename your object or delete the existing object.

Possible Reason Solution
 The 'User Profile Synchronization service'(CA -> Manage Services on server) instance is in 'Stopping' state  Let the service instance be in a Start/Stop state. Not in 'ing' state.

Note: Usually this error is thrown when we try to unprovision a service instance which is already in 'stopping' state. Here the timer job may not be trying to unprovision the instance, however, it checks the job queue to ensure that no jobs are executing so that the system gets stored/backed up in a stable state.

Error 3: Search Service Application causing the issue

FatalError: Object Search Service Application failed in event OnBackup ...

Possible Reason Solution
 The Timer job service account doesn't have permission on the Search Service Application Grant Full Control permission to the timer job service account on the Search Service Application
 Search Service account doesn't have permission to the shared folder Share the folder to the search service account with full control

Note: Try narrowing down the permissions as much as possible. It's not advisable to grant Full Control unless it's really needed.

Original Post


by Saratchandra Peddinti via Everyone's Blog Posts - SharePoint Community

Saturday, July 30, 2016

SharePoint O365!! Why I see all my site contents are updated at once a few hours ago?

Most of the sites, I've been working with, have not been updated in the recent past. However, one fine day I opened the site content and all the lists and libraries were showing the content was modified a few hours ago. It was not a big deal at that time to figure it out what was the reason behind those 'all of a sudden & all at once' updates. Anyhow, it is time now to see what's going on. Then I found a SPUser Voice shouting at Microsoft about the same issue( reflect the content changes not the system changes). This article is to present some findings about the 'Unexpected Modified Dates'. And one of the factors being the REST Query. PFB, the screenshot..

Recently when I retrieved a list item, I found three different date attributes came along as highlighted below.

<entry xml:base="http://ift.tt/2aEFKm3"...>
<id>e11700c1-97d3-4451-8544-0bd6d1e4c995</id>
<category term="SP.Data.TestFormListItem" scheme="http://ift.tt/1aFoa69" />
<link rel="edit" href="Web/Lists(guid'e743b81c-0245-4970-a87d-9692d42813cc')/Items(<ID>)" />
<title />
<updated>2016-07-20T19:58:50Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:Modified m:type="Edm.DateTime">2016-06-20T12:35:20Z</d:Modified>
<d:Created m:type="Edm.DateTime">2016-05-31T11:33:56Z</d:Created>

</m:properties>
</content>
</entry>


Created : Attribute of the content, tells when the item/document is created
Modified : Attribute of the content, tells when the item/document's metadata is last modified
Updated : Attribute of the list item, tells when the list item is last updated.
Now, More Insight...

Before the REST Query

As we can see in the below image, the given lists were updated at the same time.

Then I though of observing which REST query is triggering the mysterious update mechanism. Then this happened...

And then this...

At this point, after observing it for multiple times I came to an understanding that every first time the items are retrieved by using REST query, the date value is getting updated. Since all the above requests are get requests, I tried to access the same resources from the site contents. However, accessing so didn't update the modified date.

I'm really ambiguous about making any further comments on this behaviour and Microsoft's thinking about how this 'Updated' is more useful than 'Modified' time. However, whatever is the intention of Microsoft, presenting it as the last modified date to the user is so confusing/miss-leading. And it raises questions about the integrity of the product.

Interesting thing is this behaviour occurs only with REST queries. I tried the below things as well..

Click on link title and open an item
Managed client object model code equivalent to "/items"
However, the "updated" property of the list object didn't get updated. Final words...

The modified date, for lists, we see in the site contents is getting updated when a user accesses the "items" using REST query (using either code or directly hitting the url in browser's address box) for the First Time - So is it for analysing the REST activities of unique uses on the list? Nay, doesn't make sense.

However, it's not just about the REST calls - It is one of the reasons. There must be multiple reasons causing this behaviour.

Riddles here :

What is the use of the "Updated" property?
Somehow, I figured out one way that is causing the "Modified" date change for lists. And the question is, what is causing the change in "Modified" dates of libraries & other objects?


ORIGINAL Post
by Saratchandra Peddinti via Everyone's Blog Posts - SharePoint Community

Thursday, August 20, 2015

Is it that difficult to read a file from SharePoint site?


Looks like a silly question. But it took me two hours to solve.
- I faced an issue while downloading a file... not from the browser, though.
My requirement was to read the data from an excel file that is stored in a document library. BTW, I was using OpenXML libraries to parse the excel data, which requires either the path of the file or the stream as a parameter. Since it is not possible to provide the path of a document that was stored in a library, I had to pass the stream as the argument.
Exactly here I encountered an issue when I tried to read the file as stream.
The name of the issue is... "NetworkStream", one of the least discussed class.
A Brief History of "NetworkStream":
It inherits from 'System.IO.Stream'. And so the methods derived in it.
However, it denies any seek operation we ask for. In fact this is the first time
I found this class.
        
// The below statement returns the NetworkStream Object
// fileInfoObject is of type - Microsoft.SharePoint.Client.FileInformation
var stream = fileInforObject.Stream;

As per the documentation, it should return a standard stream. But it returns a stream object that doesn't support any Seek operations(Length, Seek ..etc). Read here.. for the info.

In fact I tried couple of methods I found over the internet and found them of no use.
As a result of the experiments, I was left with a corrupted stream object saved to disk as a file that scolded me very badly, in machine language, when I tried to open it. Then, further search awarded me with a way to deal with the file - using the System.Net.WebClient class that provides methods for sending data to and, in my case, receiving data from a resource identified by a URI.

So, it is an easy operation as shown below when we want to get the file as stream from a site that readily authenticates us with the identity used to run the code.
Here, for authentication purpose, we can assign either NetWorkCredentials object or CredentialCache.DefaultCredentials to the WebClient.Credentials;

using (WebClient webClient = new System.Net.WebClient())
{
// excelFileUrl - path/url of excel file that is uploaded to a document library
Stream streamObject = webClient.DownloadData(excelFileUrl)
// now I can do anything with this stream - such as...
// 1. Saving to disk;
// 2. Passing as an argument to OpenXML library method to parse it.
}

It would have been end of this post if my struggle ended here. However, my actual requirement is to read the data from Office 365 SharePoint site. Here the problem is the 'Authentication'. Since our request doesn't carry any authentication tokens/cookies, the server rejects the request saying we don't have access. Here I tried to use my brain but it hardly paid off. The method I tried..


webClientObj.Credentials = sharePointOnlineCredentialsObject;

When I observed the request pattern using fiddler, I found that no FedAuth cookie is associated with the request. Then again google helped me. The solution is to make the WebClient class as Cookie aware. That is, to associate the WebClient with a cookie container that gets added the authentication cookies when we pass valid credentials.
The below method describes how to make WebClient cookie aware. We do a series of steps as..
1. Adding a cookie container to the child class - it helps storing the authentication cookies
2. Overriding the GetWebRequest method - it makes the web request associated with an authentication cookie as a header
3. while overriding, we add the UserAgent string to the web request -

In the absence of the UserAgent string, cookie will not get added to the container. By adding it, our web request mimics a request sent by a browser. This is any valid UserAgent string - need not be the one I've given below.

// Method [1]
// This class extends the capabilities of the WebClient class by adding
// a CookieContainer to it.
class AuthenticatedWebClient : System.Net.WebClient
{
public System.Net.CookieContainer WebClientCookieContainer { get; private set; }
public AuthenticatedWebClient()
{
WebClientCookieContainer = new System.Net.CookieContainer();
}
protected override WebRequest GetWebRequest(Uri url)
{
var request = (HttpWebRequest)base.GetWebRequest(url);
//Adds the existing cookie container to the Request
request.CookieContainer = WebClientCookieContainer;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.0; rv:12.0) Gecko/20100101 Firefox/12.0";
return request;
}
}

Now the downloading part - The below snippet tells how to pass credentials along with the Cookie aware WebClient class. We pass credentials, using the NaveValueCollection object, to the login url of the Office 365 site.

using (AuthenticatedWebClient authenticatedWebClient = new AuthenticatedWebClient())
{
System.IO.Stream filestream = null;
var values = new NameValueCollection{{ "username", "saratchandra@myorganization.com" },{ "password", "mypassword" }};
authenticatedWebClient.UploadValues("http://ift.tt/1sRvdjz", values);
string url = "http://ift.tt/1EGJcQC";
byte[] content = authenticatedWebClient.DownloadData(url);
filestream = new System.IO.MemoryStream(content);
// The below code is a custom helper method to parse the excel data
OpenXmlExcelHelper.GetExcelData(filestream);
}

With the method explained above, everything seemed to be under control. However, the result again was an incomplete chunk of byte stream - which again is not useful.

This time I really had to use my brains and...this time it worked.. The below is the code snippet for that. A simple way of making a WebClient cookie aware without struggling much.
Here, the `credentials` object is of type - SharePointOnlineCredentials

// Method [2]
using (WebClient webClient = new System.Net.WebClient())
{
webClient.Headers.Add("Cookie", credentials.GetAuthenticationCookie(new Uri("http://ift.tt/1JuEq08")));
string url = "http://ift.tt/1EGJcQC";
byte[] content = webClient.DownloadData(url);
filestream = new System.IO.MemoryStream(content);
// custom method to parse excel data
OpenXmlExcelHelper.GetExcelData(filestream);
}
Original Post

by Saratchandra Peddinti via Everyone's Blog Posts - SharePoint Community

Friday, January 9, 2015

Demystified : Breaking the Role Inheritance of a SecurableObject with CSOM

Managing permissions is a very important aspect of SharePoint. As there are so many techniques to authenticate a user to a SharePoint application, the permissions part takes care of the authorization. There are so many articles that discuss the permissions levels, groups etc to a great extent.



In this post I'm going to discuss the following things.


  • Code snippet to break role inheritance of a Securable Object - In current example a list

  • Analyzing the code with User Interface



public static void AssignUniquePermissions(string ctxUrl,string listTitle){
ClientContext ctx = new ClientContext(ctxUrl);
List targetList = ctx.Web.Lists.GetByTitle("listTitle");
ctx.Load(targetList);

// the below line of code breaks the Permission Inheritane
// The below piece of code is equivalent to...
targetList.BreakRoleInheritance(true,false);

/* PermissionKind => is an Enum type that represents
all the permissions available */
/* BasePermissions => is a class to which we set the Selected
Permissions. Later we use 'BasePermissions' object in creating
the 'RoleDefinition' */
BasePermissions permissions = new BasePermissions();
permissions.Set(PermissionKind.ViewListItems);
permissions.Set(PermissionKind.AddListItems);
permissions.Set(PermissionKind.EditListItems);
permissions.Set(PermissionKind.DeleteListItems);


/* Create a new role definition => Creating a Permission Level
@ /_layouts/addrole.aspx of site collection. */
//The below piece of code is equivalent to...
RoleDefinitionCreationInformation roleDefInfo = new RoleDefinitionCreationInformation();
// Permission Level Name
roleDefInfo.Name = "ExampleEditListItems1";
roleDefInfo.Description = "Allows a user to manage list items";
roleDefInfo.BasePermissions = permissions;
/* Adds RoleDefinition => Adds Permission Level
@ /_layouts/role.aspx */
RoleDefinition roleDef = ctx.Site.RootWeb.RoleDefinitions.Add(roleDefInfo);

// Creating another RoleDefinition
BasePermissions permissions2 = new BasePermissions();
permissions2.Set(PermissionKind.ApproveItems);
RoleDefinitionCreationInformation roleDefInfo2 = new RoleDefinitionCreationInformation();
// Permission Level Name
roleDefInfo2.Name = "ExampleEditListItems2";
roleDefInfo2.Description = "Allows a user to Approve Items";
roleDefInfo2.BasePermissions = permissions2;
RoleDefinition roleDef2 = ctx.Site.RootWeb.RoleDefinitions.Add(roleDefInfo2);

/* The permissions we are assigning to the User/Group
Equivalent to 'Grant User Permissions Directly
(in this example) by selecting multiple permission
levels */
// The below piece of code is equivalent To..
RoleDefinitionBindingCollection permissionLevelsCollection = new RoleDefinitionBindingCollection(ctx);
// Add the role to the collection.
permissionLevelsCollection.Add(roleDef);
permissionLevelsCollection.Add(roleDef2);

// User user = ctx.Web.EnsureUser("Domain\\userId"); (or)
Group group = ctx.Web.SiteGroups.GetById(12);

/* The page that contains all the Permissions. =>
@ _layouts/user.aspx of the corresponding securable object */
RoleAssignmentCollection roleAssignmentCollection = targetList.RoleAssignments;
RoleAssignment roleAssignment = roleAssignmentCollection.Add(group, permissionLevelsCollection);

ctx.ExecuteQuery();
Console.WriteLine("Done!!");
Console.ReadKey();
}




targetList.BreakRoleInheritance(true,false);

This above line of code is equivalent to clicking on the 'Stop Inheriting Permissions' option in the ribbon


What is the difference between BreakRoleInheritance(true,true/false)?

This function breaks the role inheritance of the SecurableObject on which we are calling the function in both cases.

The second parameter(true/false) acts on the Child objects of the SecurableObject on which we called the function.

true: It makes the children of the current SecurableObject inherit RoleAssignments from the current SecurableObject even though they have UniqueRoleAssignments on them.

false: It allows the children of the current SecurableObject have their own RoleAssignments(UniqueRoleAssignments) if they have any.

Back To Code



Creating a RoleDefinition:

Creating a RoleDefinition is equivalent to creating a new permission level from the SharePoint UI @ 'addrole.aspx' of the root web


// Adds the permission level to the collection of permission levels at the root web levelRoleDefinition roleDef = ctx.Site.RootWeb.RoleDefinitions.Add(roleDefInfo);

Everything I mentioned in the below image happens only after executing the query.

You find this info when you click on the Permission Level created @

~siteCollectionUrl/_layouts/editrole.aspx?role=ExampleEditListItems1

createRoleDef

Back To The Code


Granting Permissions To a User Or Group:

Adding RoleDefinition Objs to RoleDefinitionBindingCollection obj is equivalent to

select the multiple permission checkboxes as shown in the below image.


permissionLevelsCollection.Add(roleDef); permissionLevelsCollection.Add(roleDef2);

grantPermissions




// if we want to grant permissions to a user User user = ctx.Web.EnsureUser("Domain\\userId"); (or)
// if we want to grant permissions to a Group
// The group id '12' represents 'TestGroup1' as shown in the above image
Group group = ctx.Web.SiteGroups.GetById(12);

// This line of code grants permissions to the Group
RoleAssignment roleAssignment = roleAssignmentCollection.Add(group, permissionLevelsCollection);
// This line of code grants permissions to the User
RoleAssignment roleAssignment = roleAssignmentCollection.Add(user, permissionLevelsCollection);


Original Post

by Saratchandra Peddinti via Everyone's Blog Posts - SharePoint Community