How to get Users and Groups in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can retrieve users in a SharePoint group in SharePoint 2013 Online using managed .NET Client Side Object Model (CSOM). We’ll create a Console Application in Visual Studio for the purpose of the demo.

Open Visual Studio 2013.

File –> New Project –> Visual C# –> Console Application and name it as ‘GetUsersInGroup’

Add a reference to assemblies ‘Microsoft.SharePoint.Client’ and ‘Microsoft.SharePoint.Client.Runtime’.

Import the following two namespaces.

using Microsoft.SharePoint.Client;
using System.Security;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

In the client object model, the list groups in a site-collection needs to be fetched first and then based on the groups another call needs to be made to SharePoint Online to get the list of users. The following code snippet explains it all.

namespace GetUsersInGroupCSOM
{

    class Program
    {
        static void Main(string[] args)
        {
            //Replace it with the url of your tenant or your site-collection
            string SiteUrl = "https://yoursite.sharepoint.com";

            System.Uri oUri = new System.Uri(SiteUrl);

            using (ClientContext oClientContext = new ClientContext(SiteUrl))
            {
                //Replace it with your user id for SharePoint Online
                string UserName = "lavsunswe@yoursite.onmicrosoft.com";


                //Replace it with your password
                string Password = "yourpassword";

                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);

                //Load the site-collection groups using CSOM
                oClientContext.Load(oClientContext.Web.SiteGroups);
                oClientContext.ExecuteQuery();

                GroupCollection oSiteCollectionGroups= oClientContext.Web.SiteGroups;
                Console.WriteLine("List of groups in the site collection");
                Console.WriteLine("-------------------------------------");

                foreach (Group  oGroup in oSiteCollectionGroups)

                {
                    
                    Console.WriteLine(oGroup.Title);
                    Console.WriteLine("n");


                                
                }

                //Load the users collection in the Group 1

                oClientContext.Load(oSiteCollectionGroups[1].Users);
                oClientContext.ExecuteQuery();

                Console.WriteLine("List of users in the first group of site-collection");
                Console.WriteLine("-------------------------------------");
              foreach(User oUser in oSiteCollectionGroups[1].Users)
                {
                    Console.WriteLine(oUser.Title);
                    Console.WriteLine("n");
                
                }


               
                Console.ReadLine();



            }



        }

        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

    }
}

image

 Subscribe to my blog

List of Azure services that can be moved from one subscription to another subscription

I have a requirement to transfer the entire SharePoint 2013 Farm on  Azure with Virtual Network, Cloud services, Storage accounts, Virtual Machines, Subnets and Availability sets to a different Subscription on Azure. I did some analysis and in this migration process i have learnt that the following Azure services (as of today 07/29/2014) can be transferred from one Azure subscription to another Azure subscription without data-loss and downtime, by raising a support ticket with Microsoft Azure Support :-

  • Virtual Machines
  • Cloud Services
  • CDN
  • Web sites
  • Media Services
  • Service Bus
  • Storage
  • Multi Factor Authentication
  • Traffic Manager
  • Mobile Services
  • Virtual Network
  • Access Control Service (ACS)
  • Caching – we need to work with Engineering Team for migrating caching service
  • Reserved IP Address and the Reserved IPs under the list

However, there are certain Azure services that cannot be moved from One subscription to another subscription (as of today 07/29/2014):-

a) Active Directory (AAD)
b) BizTalk Services
c) HD Insight
d) Backup 
e) Hyper-V Recovery Manager
f) Azure Store
g) Import / Export
h) Scheduler
i) Management Services 
j) SQL Reporting

The following pre-conditions should be met before initiating a subscription transfer with Microsoft Azure support :

  • Source and destination subscription should be active
  • Selective service transfer is not feasible as of today, it might come in future. It has to be all or nothing.
  • The destination azure subscription should be empty, otherwise it will be overwritten during upgrade
  • Source and destination subscription should have same server administrator assigned until the migration is complete.

 Subscribe to my blog

Consume a SharePoint 2013 Online REST feed using .NET managed code

In this post, we’ll see how we can consume a SharePoint 2013 online REST feed using managed c# code. I’d be using a Provider Hosted App template in Visual Studio 2013 for this demonstration. It is very straight forward to consume a Restful .NET service by issuing HttpWebRequest from c# code and getting HttpWebResponse.

I will be invoking https://yoursite.sharepoint.com/_api/web/lists from c# code to get the list of SharePoint lists in this Office 365 site. The following screenshot shows the response for this Restful service in the browser.

image

Now let’s start creating a Provider hosted app project in Visual Studio 2013.

File –> New Project –> Visual C# –> Office/SharePoint –> App for SharePoint 2013 and name it as ‘ReadRESTCSharp’ & set the site for debugging and app type as ‘Provider-hosted’.

image

Specify the web project type as ‘ASP.NET Web Forms Application’. In the next step, Visual Studio 2013 would prompt for setting App Authentication Type, I did not see this option while using Visual Studio 2012 to create Provider hosted apps.

image

Set the App authentication type as ‘Use Windows Azure Access Control Service’ (mentioned in the above screenshot).

Click ‘Finish’ to create the app.

Go to  ASP.NET Web Forms project and open the default.aspx.cs

Import the following three namespaces at the top.

using Microsoft.SharePoint.Client;
using System.Net;
using System.IO;

In page_load comment out the following lines of code.

//var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            //using (var clientContext = spContext.CreateUserClientContextForSPHost())
            //{
              //  clientContext.Load(clientContext.Web, web => web.Title);
               // clientContext.ExecuteQuery();
                //Response.Write(clientContext.Web.Title);
            //}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Since I’m using my own developer tenant in Office 365, I would want to trust all the certificates issued by SharePoint Online to my browser. Otherwise, it will keeping popping up a message to trust the certificates in Visual Studio 2013, when I hit F5 and debug the app.

Open the TokenHelper.cs and the add the following static method ‘TrustAllCertificates’

public static void TrustAllCertificates()
        {
            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);
        }

If you are using Visual Studio 2012, it adds ‘TrustAllCertificates’ in TokenHelper.cs by default.
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

I will be using my Office 365 developer tenant for this demo, which forces the need to get the Access Token from Office 365 and pass it as a part of the header in the HttpWebRequest. First I need to get the ContextTokenString by invoking GetContextTokenFromRequest method in TokenHelper.cs. Then I need to get the actual SharePointContextToken by invoking ReadAndValidateContextToken method in the TokenHelper.cs. Finally I need to get AccessToken by invoking the GetAccessToken method in the TokenHelper.cs. I won’t go too detailed about this one. All the dynamics of the Token exchange is covered in one of my previous article.

Once the AccessToken is received, a HTTPWebRequest needs to be issued by setting the AccessToken with Bearer, also we need to set the HTTPRequest method as ‘GET’ and HTTPRequest accept headers as “application/json;odata=verbose”.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using Microsoft.SharePoint.Client;

namespace ReadRESTCSharpWeb
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_PreInit(object sender, EventArgs e)
        {
            Uri redirectUrl;
            switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
            {
                case RedirectionStatus.Ok:
                    return;
                case RedirectionStatus.ShouldRedirect:
                    Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                    break;
                case RedirectionStatus.CanNotRedirect:
                    Response.Write("An error occurred while processing your request.");
                    Response.End();
                    break;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            
            // The following code gets the client context and Title property by using TokenHelper.
            // To access other properties, the app may need to request permissions on the host web.
            //var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            //using (var clientContext = spContext.CreateUserClientContextForSPHost())
            //{
              //  clientContext.Load(clientContext.Web, web => web.Title);
               // clientContext.ExecuteQuery();
                //Response.Write(clientContext.Web.Title);


            //}

            TokenHelper.TrustAllCertificates();

            //Get the ContextTokenString
            string ContextTokenString = TokenHelper.GetContextTokenFromRequest(Request);



            if (ContextTokenString != null)
            {

                //Get the SharePointContextToken
                SharePointContextToken ContextToken = TokenHelper.ReadAndValidateContextToken(ContextTokenString, Request.Url.Authority);

                Uri sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);

                //Get the AccessToken
                string AccessToken = TokenHelper.GetAccessToken(ContextToken,sharepointUrl.Authority).AccessToken;

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(@"https://yoursite.sharepoint.com/_api/web/lists");
                request.Method = "GET";
                request.Accept = "application/json;odata=verbose";
                request.Headers.Add("Authorization", "Bearer " + AccessToken);

                HttpWebResponse response =(HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());

                Response.Write("<h2>List of SharePoint lists in SharePoint Online fetched from managed code</h2>");
                Response.Write("<p>" + reader.ReadToEnd() + "</p>");
                Response.Flush();
            
            
            }




        }
    }
}

After executing the above we get the successful HTTPResponse which can be seen in debug mode in Visual Studio 2013.

image
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

  Subscribe to my blog

How to retrieve current user in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can retrieve the current user in a SharePoint 2013 online site using client side object model (CSOM). We’ll  be using a console application for the purpose of this demonstration.

Open Visual Studio 2013

File –> New Project –> C# –> Console application

Add  reference to the following assemblies.

Microsoft.SharePoint.Client.dll

Microsoft.SharePoint.Client.runtime.dll

Import the following namespaces at the top of Program.cs

using  Microsoft.SharePoint.Client;
using System.Security;

namespace Retrievecurrentuser
{
    class Program
    {
        static void Main(string[] args)
        {

            using (ClientContext oClientContext = new ClientContext(@"https://yoursite.sharepoint.com"))
            {

                //Assign User Id for your SharePoint Online tenant     
                string UserName = "userid@yoursite.onmicrosoft.com";

                //Assign password for your SharePoint online tenant
                string Password = "password";

                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);


                //load the properties of web object
                Web oWeb = oClientContext.Web;
                oClientContext.Load(oWeb);
                oClientContext.ExecuteQuery();

                //retrieve the site name
                string SiteName = oWeb.Title;

                //retrieve the current user
                oClientContext.Load(oWeb.CurrentUser);
                oClientContext.ExecuteQuery();

            Console.WriteLine("Login Name"+ oClientContext.Web.CurrentUser.LoginName);
                Console.WriteLine("Is Admin"+ oClientContext.Web.CurrentUser.IsSiteAdmin);
                Console.WriteLine("Email"+ oClientContext.Web.CurrentUser.Email);
                
                Console.ReadLine();


            }
        }

        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Then create a clientcontext in the program.cs, load the web object (execute query) and then load the current user based on the web object.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Now we’ll be able to fetch the user properties like the below.

image

 Subscribe to my blog

How to create a SharePoint 2013 Site by invoking SP 2013 REST endpoints

In this post, we would see on how to create a SharePoint 2013 site using the SharePoint 2013 RESTful endpoints available in HostWeb. I would be using a SharePoint hosted app to demonstrate this scenario.

File –> New –> Office/SharePoint –> Apps and name it as ‘CreateSiteApp’.

image

In the SharePoint hosted app, I’d be making a call to the /_api/web/webinfos/add available in HostWeb to create a sub-site under HostWeb.

Open App.js file.

Copy and paste the following code. The following snippet leverages Cross Domain library of SharePoint 2013 to make

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;



// This code runs when the DOM is ready and creates a context object which is needed
 to use the SharePoint object model
$(document).ready(function () {
    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);


});

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}


function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);
    executor.executeAsync(
        {
            url:  AppWebUrl +"/_api/web/webinfos/add",
            type: "POST",
            data: JSON.stringify(
                {
                    'parameters': {
                        '__metadata': { 'type': 'SP.WebInfoCreationInformation' },
                        'Url': 'SundarSite',
                        'Title': 'SundarSite',
                        'Description': 'Site created using REST',
                        'Language': 1033,
                        'WebTemplate': 'sts',
                        'UseUniquePermissions': false
                    }
                }
            ),
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/json;odata=verbose",
                "content-length": 1028,
                "X-RequestDigest": $("#__REQUESTDIGEST").val()

            },
            success: successHandler,
            error: errorHandler
        }
        );




       

}

function successHandler(data) {
    document.getElementById("message").innerText =
        "Site Created Successfully";

}

function errorHandler(data, errorCode, errorMessage) {
    document.getElementById("message").innerText =
        "Could not complete cross-domain call " + errorMessage;
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 Subscribe to my blog

How to access data in Host Web from SharePoint 2013 App

When we build SharePoint 2013 Apps, one of the common scenario that we will have is to read the data from Host Web.  This presents a classical Cross-Domain call scenario (where the fully-qualified domain for App Web and Host Web are different). By default, when we access the Host Web resources from App Web either using Java Script Model or Client Object Model, we’d get an access denied error. This fix for this scenario is to leverage javascript client-side solution in the form of (SP.RequestExecutor.JS) file. The cross domain libraries helps us to interact with more one domain in the SharePoint 2013 App through the Proxy. Let’s jump on to the steps.

Open Visual Studio 2013

File –> New –> Project –> Apps for SharePoint 2013 –> SharePoint hosted apps and name the App as ‘ReadHostWeb;

Set the site for debugging, in this case I’m using my Office 365 developer tenant ‘https://mytenant.sharepoint.com’

I’ve created an Announcement list in my Host Web and it has three Columns Title, Body and Version.

Open Default.aspx and paste the following snippet of code inside

 

<div id="ListFieldDiv"></div>

    <script type="text/javascript">
        var HostWebUrl;
        var AppWebUrl;
        var ListFieldHtml;

        // Load the required SharePoint libraries
        $(document).ready(function () {
            //Get the URI decoded URLs.
            HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
            AppWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPAppWebUrl")
            );

            
            var scriptbase = HostWebUrl + "/_layouts/15/";

            
            $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);
            
        });


        
        
        function execCrossDomainRequest() {
            
            var executor = new SP.RequestExecutor(AppWebUrl);

            
            executor.executeAsync(
    {
        url:
            AppWebUrl +
            "/_api/SP.AppContextSite(@target)/web/lists('5fabe2a3-7a5f-4444-ba3e-a684558d1e27')/fields?@target='" +
            HostWebUrl + "'",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: successHandler,
        error: errorHandler
    }
);

        }

        
        function successHandler(data) {

            var jsonObject = JSON.parse(data.body);
            var results = jsonObject.d.results;

            for (i = 0; i < results.length; i++)
            {
                if (results[i].Hidden == false) {

                    

                    if ((results[i].TypeDisplayName == "Single line of text") || (results[i].TypeDisplayName == "Multiple lines of text")) {

                        
                        if (results[i].Title == "undefined" || results[i].Title == "Version")
                        {


                        }
                        else
                        {
                            ListFieldHtml = ListFieldHtml + "<p>" + results[i].Title;

                        }

                        
                    }
                }
                

            }
            
            document.getElementById("ListFieldDiv").innerHTML = ListFieldHtml;

            
            


            
        }

       
        function errorHandler(data, errorCode, errorMessage) {
            document.getElementById("AnnouncementsDiv").innerText =
                "Could not complete cross-domain call " + errorMessage;
        }

       
        function RetrieveQueryStringParameter(ParamsforRetrieval) {
            var params =
                document.URL.split("?")[1].split("&");
            var strParams = "";
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == ParamsforRetrieval)
                    return singleParam[1];
            }
        }
        </script>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 image

 Subscribe to my blog

Deploying SharePoint 2013 on Microsoft Azure using IAAS–Part 3

This post is continuation to my previous post Deploying SharePoint 2013 on Azure using IAAS – Part 2. In this article, we’ll see how to install SQL 2012 RTM.

Provisioning, Configuring and Setup of SQL Server 2012 VM

New à Virtual Machine à From Gallery à SQL Server 2012 Enterprise SP1.

clip_image002

clip_image004

clip_image006

The next step is to allocate the empty disk space of 50 GB space to the primary VM ‘SP2013-SQL1’ . Refer the part 1 of this article to know more about the empty disk allocation for various VMs.

Log-in to the SP2013-SQL1 VM and join the server to the Domain (techguru.com). Use the account ‘sp_install’ for joining the server to the domain.

clip_image008

On the F drive, create 3 folders namely Data, Backup and Log.

On Start menu àSQL Server 2012 Management Studio.

Right click on the default database instance à properties.

In the Server Properties click database settings. On the default database location settings, change the location of Data, Log and Backup to the corresponding folders on F drive.

clip_image010

The next step is to grant the service account sp_farm_db with Sys Admin rights.

Security à Logins à New login à sp_farm_db@techguru.com.

clip_image012

In the Server Roles à Select sysadmin

clip_image014

The next step is to grant NT AUTHORITYSYSTEM account with relevant permissions.

Security à Logins à New login à NT AUTHORITYSYSTEM.

clip_image016

Right click on NT AuthoritySystem à Properties à Securables.

Grant these 3 permissions ‘Alter any availability group’, ‘Connect SQL’ and ‘View server state’ to the account NT AuthoritySystem.

Now we need to unblock the ports 1433 (default SQL Server Ports) and 5022 (high availability port).

Start à Windows Firewall with advanced security.

Click à Inbound rules.

Action pane à New Rule.

On the Rule Type à Program à Next.

On the Program Page à Set Program Path as %ProgramFiles%Microsoft SQL ServerMSSQLBinnsqlservr.exe

clip_image018

On the Action Page à Allow Connection.

On the profile page à Keep defaults.

Name the rules ‘SQL Ports Rule’.

Setup of back-up SQL Server

clip_image020

clip_image022

Then allocate the empty disk space of 50 GB. This completes the part 3 of the series. In the next post, we’ll see how to configure SQL Server 2012 Always On.

 Subscribe to my blog

Good Resources for SharePoint 2013 on Azure

I came across the following resources that are found useful for planning SharePoint 2013 on Microsoft Azure. I thought of collating and making a post around this.

IOPS

Performance Considerations for SQL Server in Azure Virtual Machines

Performance Guidance for SQL Server in Windows Azure Virtual Machines

High Availability:

High Availability and Disaster Recovery for SQL Server in Windows Azure Virtual Machines

Approach with Custom Log shipping:

Deploying highly available SharePoint Internet Sites on Windows Azure Virtual Machines

Geo-DR for SQL Server on Windows Azure Infrastructure Services using Log Shipping

SharePoint 2013 on Windows Azure Infrastructure

SharePoint 2013 on Windows Azure Infrastructure Services

IOPS:

Performance Considerations for SQL Server in Azure Virtual Machines

Performance Guidance for SQL Server in Windows Azure Virtual Machines

High Availability

High Availability and Disaster Recovery for SQL Server in Windows Azure Virtual Machines

Approach with Custom Log shipping:

Deploying highly available SharePoint Internet Sites on Windows Azure Virtual Machines

Geo-DR for SQL Server on Windows Azure Infrastructure Services using Log Shipping

SharePoint 2013 on Windows Azure Infrastructure

SharePoint 2013 on Windows Azure Infrastructure Services

Authentication

Windows Azure Active Directory with SharePoint 2013

Internet Sites in Windows Azure using SharePoint Server 2013

Azure Compute and Storage Price Reductions

Windows Azure Active Directory with SharePoint 2013

Internet Sites in Windows Azure using SharePoint Server 2013

Azure Compute and Storage Price Reductions

 Subscribe to my blog

Deploying SharePoint 2013 on Microsoft Azure using IAAS–part 2

This post is the continuation to my previous post  – Deploying SharePoint 2013 on Microsoft Azure using IASS–part 1. The focus of the part2 of this series to cover the steps required to configure Domain Controllers (both Primary and Backup) in detail.

Configuration of Domain Controllers

Log on to the SP2013-DC1 VM (created in the Part1 of the article).

Server Manager àDashboard à Add Roles and Features.

Select Installation Type (set the default value of Role-based or feature-based installation).

Select Destination Server and Select a Server from the Server pool and click next.

clip_image002

Select Server Roles àActive Directory Domain Services and click Next

clip_image004

clip_image006

Now the Active Directory Domain Services are successfully installed in this Server SP 2013-DC1 and SP2013-DC2. We have already performed the step of initializing the Empty Disks. The next logical step is to perform activity of Promoting the SP2013-DC1 VM as the Domain Controller for the SharePoint 2013 farm that we are going to build.

Promotion of Virtual Machine to Domain Controller of the SP Farm

In this step, we would be performing the list of steps that are required to promote the Virtual Machine SP2013-DC1 as the Domain Controller of the SP Farm.

Server Manager à Manage link (on upper right hand corner) à Promote this server to a domain controller.

clip_image008

Deployment Configuration à Add a Forest

Set any arbitrary name for Root Domain name and Click next.

clip_image010

Set the Directory Services Restore Mode password as ‘Password123’.

clip_image012

We will get an error like ‘a delegation for the DNS cannot be found” and this can be ignored.

Additional Options à You will see the NetBios name reflected as the root domain name given in the previous step.

clip_image014

The next step is to set the path for Database folder, log files folder and SYSVOL folder.

clip_image016

Review all the selected options and Click next. We’ll see successful message for pre-requisites.

clip_image018

Click Install.

We’ll see a success message ‘The server was successfully configured as Domain Controller’. We need to create the set of Users (Service Accounts mentioned in the section 1b) in the Domain.

Server Manager à Tools à Active Directory Users and Computers.

Action à New à User.

clip_image020

Set the password as ‘password-1’ and make it as password never expire.

clip_image022

Repeat the above 2 steps for creating other service accounts like sp_farm_db, sp_install and sqlservice.

Provide domain admin rights for sp_install user.

clip_image023

Grant more rights to sp_install user.

On the domain name à Right click à Properties à Security à Advanced à

Advanced Security settings for domain à Select allow for Read all properties and Create computer objects.

This completes the setup of primary domain controller. We’ll set up the back-up domain controller in the next section.

Setup of back-up domain controller

In this section, we’ll see the necessary steps to configure back-up domain controller. The whole idea is that we’ll not be promoting the back-up DC (SP2013-DC2) as the domain controller for the farm, rather we will be adding the domain controller to the domain (techguru.com) running on primary domain controller VM (SP2013-DC1).

Click ‘Promote this server to Domain Controller’ and select ‘Add a domain controller to an existing domain’. Select credential techgurusp_install and the password for performing this operation.

clip_image025

clip_image027

clip_image029

clip_image031

clip_image033

Now we have successfully installed the domain controller. In the next post, we’ll cover the steps to configure SQL Server 2012 on Microsoft Azure for the SharePoint 2013.

 Subscribe to my blog

Deploying SharePoint 2013 on Microsoft Azure using IAAS–part 1

The objective of this article is to articulate the setup of SharePoint 2013 farm on Microsoft Azure platform using Infrastructure as a Service (IASS). Basically I  pretty much followed the steps mentioned in the MSDN article. I’m using Microsoft Azure trial subscription for the entire setup of SharePoint on Azure.

Configuration of Windows Azure Infrastructure components

The first step in setting up the SP 2013 Farm is to start provisioning the following three basic Network components and a Storage Account in the Azure Instance:

· One Virtual Network

· Four subnets

· Two DNS Servers

· One Windows Azure Storage account

On the lower-left corner, Click New à Virtual Network

Name for Virtual Network

Region: East Asia

Affinity Group: Create a new Affinity Group

clip_image002

On the DNS Servers type, type DNSServer1 and assign IP address as 10.0.0.4

On the DNS Servers type, type DNSServer2 and assign IP address as 10.0.0.5

clip_image004

On the Virtual Network Address Spaces, Click CIDR box to add subnet button. Add four subnets for each of the following

· DCSubnet (replaces Subnet-1), 10.0.0.0/11

· DataSubnet, 10.32.0.0/11

· AppSubnet, 10.64.0.0/11

· WebSubnet, 10.96.0.0/11

clip_image006

Now the virtual network is created.

clip_image008

Creation of Storage Account

The next step is to create Windows Azure Storage Account

Go to the Azure Management Portal.

New –> Data Services –> Storage and Quick Create

clip_image010

For the url enter name as “sundarsp”

Leave the default location/affinity group, which is selected as SundarAffinity.

Leave the default selection for Replication as ‘Geo-Redundant’ which will ensure the durability of the data.

Standards, Conventions and Limits

There are few conventions, standards and limits that I will be following throughout this article. It’s all again based on the msdn guidance.  http://msdn.microsoft.com/en-us/library/azure/dn275966.aspx.

When it comes to the allocating empty disk space, a size of 20 GB will be allocated to Primary Domain Controller & Back-Up Domain Controller VM. An empty disk size of 50 GB will be allocated to Database Server and SharePoint Server VMs.

Virtual Machine Type

Empty Disk Size

Primary Domain Controller

20 GB

Backup Domain Controller

20 GB

Database servers

50 GB

SharePoint Servers

50 GB

When it comes to Subnet creation, it is recommended to create four Subnets for different servers.

Sever

Subnet Name

Domain Controller

DC Subnet

SharePoint Server

WebSubnet

Sql Server

Data Subnet

App Server

AppSubnet

Availability Sets in Azure provides the capability to allocate Virtual Machines to different fault domains when a failure occurs. It increases availability and reliability. The recommendation is to create four Availability Sets as per the below conventions

Availability Set

Servers

DCAvailSet

SP2013-DC1 and SP2013-DC2

WFEAvailSet

SP2013-Web1 and SP2013-Web2

AppAvailSet

SP2012-App1 and SP2013-App2

SQLAvailSet

SP2012-SQL1 and SP2012-SQL2

We’ll be creating an Active Directory Domain by name ‘techguru.com’ (any arbitrary name that you can create for your need. I’ll also be creating the following set of Service Accounts on the techguru.com domain with a password of ‘password-1’ and password set as never expires.

Service Account

Purpose

Sp_farm

Account to manage the SharePoint farm

Sp_farm_db

Account to Manage the SQL Server (with SysAdmin rights )

Sp_install

Account with Domain administration rights for installing Roles and Features on various servers

Sqlservice

Account that SQL Server Instances run as.

Creation of Virtual Machines from Gallery

The creation of Virtual Machines typically involves the following five steps:-

1) Provisioning of Virtual Machine Instance

2) Creation and Attachment of empty disks

3) Initializing Empty Disks (The specification for empty disks are mentioned in the previous section 1.b)

4) Creation of Availability Set and its Associations for various VMs (The list of Availability Set are mentioned in the previous Section 1.b)

5) Logging into VM and perform initial setup activities

The following set of Virtual Machines need to be created for setting up the SP 2013 Farm. Since I’m having only the Trial version of Azure, I’m selecting only A2 VM with 2 cores of CPU. If you are setting the real Dev-Test SP 2013 environment for your customer on Azure, you need much more than that.

VM Name

Purpose

VM Image

VM Type

Subnet

SP2013-DC1

Primary Domain Controller

Windows Server 2012 Data Center

A2 2 cores

DC Subnet

SP2013-DC2

Back-up Domain Controller

Windows Server 2012 Data Center

A2 2 cores

DC Subnet

SP2013-SQL1

Database Server

MS SQL 2012 SP1 Enterprise on Win 2008 R2 SP1

A2 2 cores

Data Subnet

SP2013-SQL2

Database Server

MS SQL 2012 SP1 Enterprise on Win 2008 R2 SP1

A2 2 cores

Data Subnet

SP2013-App1

SharePoint App Server

Microsoft SharePoint Server 2013 Trial

A2 2 cores

AppSubnet

SP2013-App2

SharePoint App Server

Microsoft SharePoint Server 2013 Trial

A2 2 cores

AppSubnet

SP2013-Web1

SharePoint WFE

Microsoft SharePoint Server 2013 Trial

A2 2 cores

WebSubnet

SP2013-Web2

SharePoint WFE

Microsoft SharePoint Server 2013 Trial

A2 2 cores

WebSubnet

Creation of domain controller VM

New –> Compute –>Virtual Machine à from Gallery.

Select Virtual Machine operating system.

First, we’ll create a VM for Domain Controller and we’ll select Windows Server 2012 Data Center for Domain Controllers.

clip_image012

Set the password as ‘Pass@word1’.

clip_image014

clip_image016

clip_image018

Attach an empty disk of 20 GB to the Domain Controller VM and set it as Read/Write

clip_image020

Now we have attached the empty disk of 20 GB to the primary domain controller (sp2013-dc1) VM. The next step is to create Availability Set for the domain controller VM.

Virtual Machines –> Configure –> Availability Set –> Create an Availability Set

clip_image021

Set the name for availability set as ‘DC Avail Set’ and Save. Now let’s try logging in to VM.

In the Remote Desktop Connection Dialog Box click Connect and provide your user account as <<Machinename>>.cloudapp.netUserName and provide the password. Once we log in to the VM, we need to perform the Task of Initializing the Empty disks (mentioned in previous section)

Creation of Backup Domain Controller VM

Compute –> Virtual Machine –> From Gallery

clip_image023

clip_image025

clip_image027

Attach an empty disk of 20 GB to the back-up Domain Controller VM

clip_image029

Now we have successfully attached the Empty Disk to the backup domain controller VM. The next step is to select the ‘Availability Set’. Select the existing Availability Set of ‘DCAvailSet’ for back-up domain controller and save.

clip_image030

Now we have successfully created Availability Set for Domain Controller VMs (Primary and back-up). Now we need to log in to the SP2013-DC2 VM and perform the Empty Disk Initialization steps mentioned in section 1f.

Empty Disk Initialization

The empty disk initialization task need to be performed for all the types of the VMs that we would be creating as a part of SharePoint 2013 farm set up. Perform the following task on a VM running Windows Server 2012.

Server Manager à Click File and Storage Services à Disks

Select the Disk that is with the capacity of 20 GB and partition set to Unknown.

clip_image032

Create a new Volume, accept defaults and Set the Drive volume as ‘F’

clip_image034

clip_image036

The next step is to configure the Domain Controllers (both Primary and Back-up), it will be covered in detail in the part 2 of this article.

 Subscribe to my blog