News About Migration into SPO and CSOM Throttlings

The new APIs that are available to help with migrations moving forward

We have great documentation that talks through what it means to be blocked, how to look for it (HTTP 429s), and how to avoid it at https://msdn.microsoft.com/en-us/library/office/dn889829.aspx.

SPO Migration PowerShell cmdlets are designed to move on-premises content from file shares and SharePoint Server libraries and One Drive to SharePoint Online and OneDrive for Business. Requiring minimal CSOM calls, it leverages Azure temporary BLOB storage to scale to the demand of large migration of data content.

SPO Migration User Guide: https://technet.microsoft.com/en-us/library/mt203923.aspx

Video of the new API : https://channel9.msdn.com/Events/Ignite/2015/BRK3153

CreateMigrationJob:       https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.site.createmigrationjob.aspx

DeleteMigrationJob:       https://msdn.microsoft.com/EN-US/library/office/microsoft.sharepoint.client.site.deletemigrationjob.aspx

GetMigrationJobStatus:  https://msdn.microsoft.com/EN-US/library/office/microsoft.sharepoint.client.site.getmigrationjobstatus.aspx

Doc for the PowerShell Commands : https://technet.microsoft.com/en-us/library/mt143608.aspx

(Special thanks for my colleague Dustin)

Advertisements

How to send Real Meeting Request from Sharepoint 2010 – part 1

Hello Everyone,

Recently I have faced with so many threads for sending meeting requests form Sharepoint .As you know there is not any out of the box feature that able to send real Meeting Request from Sharepoint. If you  ask me , i agree with Microsoft on their perspective about it is not needed to add this feature as build-in  and fallowing questions prove that implementation is a bit tricky and restricts flexibility of a global platform product like Sharepoint is not considerable.

  • How much sense it makes to have a “global” solution sending meeting invitations by SharePoint?
  • Does have each employee or user an Email/Exchange account and Outlook? What about versions , compatibility ?
  • What are the possible benefits not using Outlook to send invitations and create meeting workspaces?
  • How many people should create those meetings on the SharePoint platform?
  • Are there also outside/foreign people who should create those meetings?
  • Have a similar application like Outlook to use all sharepoint web services to do the job.

So in many forums contains solutions and workarounds for solving this issue . One of them is using Workflow and sending request emails . Nice and simple one.
you may see other options with fallowing link:
http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/e18a7b4e-230e-41d4-84df-ba3fda17bec9

In this article i am going to tell you more complex but more real solution for this issue. the key point is “Microsoft Exchange Web Services (EWS) Managed API 1.1 ” . the solution is using EWS in Sharepoint 2010 and sending real meeting requests from sharepoint.

Here is the links for How to send Real Meeting Request From Sharepoint 2010 Series:
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-1/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-2/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-3-deployment/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-requests-from-sharepoint-2010-part4-usage/

For apply this you need some prerequisites :

* Sharepoint Server 2010
* Exchange Server 2010
* Installing Exchange Web Services (EWS) Managed API 1.1 to Sharepoint servers.
* A service Account for Exchange impersonation.
* Visual Studio 2010 (optional)

First we should download EWS Managed API and install the api to sharepoint server 2010 that we are developing on it
For downloading Microsoft Exchange Web Services (EWS) Managed API 1.1 you can use fallowing link:
http://www.microsoft.com/download/en/details.aspx?id=13480

Note: I could not publish all code in the article .you can download full project and source code form fallowing link:
http://spssampleprojects.codeplex.com/releases/view/82359
http://spssampleprojects.codeplex.com/wikipage?title=Send%20Meeting%20Request%20Sample%20Project.&referringTitle=Home

1) Open Visual Studio 2010 and  Create a new blank Sharepoint Project and add reference of newly installed api dll “Microsoft.Exchange.WebServices”
C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll

2) Add a new VisualWebPart named “MeetingRequestWebPart” . We use this web parts only for Meeting Workspaces . in this demo we can only able to manage meeting requests for specific Events which are related to a Sharepoint Meeting Workspace web site.Also you can change the design according your business needs.
The webpart GUI is simple just contains 4 links and information label.

  • Send Meeting Requests (For First send)
  • ReSend Meeting Requests ( For Changes.)
  • Refresh Attendees Status
  • Cancel Meeting
<div>
    <asp:Panel ID="AdminPanel" runat="server" >
        <asp:LinkButton ID="btnSendMeetingRequest" runat="server">Send Meeting Request</asp:LinkButton>
        <br />
        <asp:LinkButton ID="btnReSendMeetingRequest" runat="server">ReSend Meeting Request</asp:LinkButton>
        <br />
            <asp:LinkButton ID="btnRefreshAttendeesStatus" runat="server">Refresh Attendees Status</asp:LinkButton>
        <br />
            <asp:LinkButton ID="btnCancelMeeting" runat="server">Cancel Meeting</asp:LinkButton>
        <br />
    </asp:Panel>
    <div>
        Information: 
        <asp:Label ID="InformationText" runat="server"></asp:Label>
    </div>
</div>

3) We need an account for impersonation.This account is resposible for connecting Exchange Server and manage operations like create,delete,update while impersonating less priviledged account means a user who can able to created an event. In my Example a have “Blog\MeetingService” account.

The following prerequisites are required to configure Exchange Impersonation:

  • Administrative credentials for the computer that is running Exchange 2010 that has the Client Access server role installed.
  • Domain Administrator credentials, or other credentials with the permission to create and assign roles and scopes.
  • Remote PowerShell installed on the computer from which you will run the commands.

Connect your Exchange 2010 server and Open the Exchange Management Shell.

  • Run the New-ManagementRoleAssignment cmdlet to add the permission to impersonate to the specified user. The following example shows how to configure Exchange Impersonation to enable a service account to impersonate all other users in an organization.
    New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:Blog\MeetingService

For Configuring Exchange Imperonation you can get more info from fallowing article :
http://msdn.microsoft.com/en-us/library/bb204095%28v=EXCHG.140%29.aspx

4) Add a new Class named “ExchangeServiceConnection

ExchangeServiceConnection Class Constructor
  1. public ExchangeServiceConnection()
  2.       {
  3.           string ExchangeServiceURL = string.Empty;
  4.           string UserName = string.Empty;
  5.           string Password = string.Empty;
  6.           string Domain = string.Empty;
  7.           try
  8.           {
  9.               ExchangeServiceURL = WebConfigurationManager.AppSettings[“ExchangeServiceURL”];
  10.               UserName = WebConfigurationManager.AppSettings[“ExchangeServiceUserName”];
  11.               Password = WebConfigurationManager.AppSettings[“ExchangeServicePassword”];
  12.               Domain = WebConfigurationManager.AppSettings[“ExchangeServiceDomain”];
  13.           }
  14.           catch (Exception ex)
  15.           {
  16.               string message = “Please Add Fallowing records to your webapplication web.config file” + Environment.NewLine +
  17.                   “->ExchangeServiceURL : Connection url for exchange server exp:https://exchange.domain.local/EWS/Exchange.asmx&#8221; + Environment.NewLine +
  18.                   “->ExchangeServiceUserName: Username exp: exserviceadmin” + Environment.NewLine +
  19.                   “->ExchangeServicePassword: Password exp: Pass@Word” + Environment.NewLine +
  20.                   “->ExchangeServiceDomain: Domain exp: DOMAIN”;
  21.               ULSLoggingService.LogMonitorable(ULSLoggingService.SMR_MONITORABLE, message);
  22.               ULSLoggingService.LogError(ULSLoggingService.SMR_VERBOSE, ex.Message + Environment.NewLine + ex.StackTrace);
  23.           }
  24.           try
  25.           {
  26.               ServicePointManager.ServerCertificateValidationCallback =  new RemoteCertificateValidationCallback(RemoteCertificateValidation);
  27.               _service = new ExchangeService();
  28.               _service.Credentials = new NetworkCredential(UserName, Password, Domain);
  29.               _service.Url = new Uri(ExchangeServiceURL);
  30.           }
  31.           catch (Exception ex)
  32.           {
  33.               ULSLoggingService.LogError(ULSLoggingService.SMR_VERBOSE, ex.Message + Environment.NewLine + ex.StackTrace);
  34.           }
  35.       }

Before the begin to tell important part , we should add some AppSettings Keys to our webapplication’s web.config file.

    <add key="ExchangeServiceURL" value="https://exchange.blogbugrapostaci.com/EWS/Exchange.asmx" />
    <add key="ExchangeServiceUserName" value="MeetingService" />
    <add key="ExchangeServicePassword" value="the password is here" />
    <add key="ExchangeServiceDomain" value="BLOG" />

if you don’t know your exhcange service url you may get this via PowerShell:
http://blog.bugrapostaci.com/2012/02/17/getting-serivce-url-of-exchange-server-by-exchange-web-service-ews-api-using-autodiscoverurl/
ServicePointManager.ServerCertificateValidationCallback =  new RemoteCertificateValidationCallback(RemoteCertificateValidation);

_service = new ExchangeService();    // We are creating new Exchange Service
_service.Credentials = new NetworkCredential(UserName, Password, Domain);    //and set our MeetingService account for credentials.we get the information from web.config file .
_service.Url = new Uri(ExchangeServiceURL);   //I am using here manuel service url . For getting information about AutoResolve options you should check “Useful Resources” section.

Exhcange server need a certification configuration. In my test envoriment i havent any certificate so fallowing CallBack provides us bypass validation.

ServicePointManager.ServerCertificateValidationCallback =  new RemoteCertificateValidationCallback(RemoteCertificateValidation);

 public virtual bool RemoteCertificateValidation(Object obj, X509Certificate cert, X509Chain chain, SslPolicyErrors errors)
        {
            // Validate the certificate and return true or false as appropriate.
            // Note that it not a good practice to always return true because not
            // all certificates should be trusted.
            return true;
        }
ExchangeServiceConnection 2nd Constructor
  1.         public  ExchangeServiceConnection(SPUser ImpersonateUser):this()
  2.         {
  3.             if (ImpersonateUser == null)
  4.             {
  5.                 string message= “SMR -> Impersonation User is NULL”;
  6.                 ULSLoggingService.LogError(ULSLoggingService.SMR_ERROR, message);
  7.             }
  8.                 if (!string.IsNullOrEmpty(ImpersonateUser.Email))
  9.                 {
  10.                     _service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, ImpersonateUser.Email);
  11.                 }
  12.                 else
  13.                 {
  14.                     string messageFormat = “SMR -> Incorrect email or user for Impersonation {0}”;
  15.                     string message = string.Format(messageFormat, ImpersonateUser.Name);
  16.                     ULSLoggingService.LogError(ULSLoggingService.SMR_ERROR, message);
  17.                     throw new Exception(message);
  18.                 }
  19.         }

For impersonation i have created a second constructor which getting a SPUser Prameter .
Impersonation operation is very simple

_service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, ImpersonateUser.Email);

5) Add and use fallowing function in your Meeting Request webpart

In WebPart -> Sending Meeting Request
  1.         public void SendMeetingRequest()
  2.         {
  3.             SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
  4.             MeetingInfo info = MeetingInfo.GetMeetingInfo(currentMeeting);
  5.             SPList attendeesList = SPContext.Current.Web.Lists[“Attendees”];
  6.             ExchangeServiceConnection conn = new ExchangeServiceConnection(SPContext.Current.Web.CurrentUser);
  7.             Appointment app = ExchangeHelper.CreateAppointment(conn.Service, info);
  8.             //Add Attendees from Meeting Workspace Attendees List.
  9.             AddAttendees(app);
  10.             try
  11.             {
  12.                 app.Save();
  13.                 info.AppointmentID = app.Id.UniqueId;
  14.                 InfoMessage = “Meeting Request sent successfully”;
  15.             }
  16.             catch (Exception ex)
  17.             {
  18.                 ULSLoggingService.LogError(ULSLoggingService.SMR_ERROR, ex.Message + Environment.NewLine + ex.StackTrace);
  19.                 InfoMessage = “An Error occured.Please contact your administrator”;
  20.             }
  21.             SaveAppointment(info);
  22.         }

The “MeetingInfo” class is a serializable data class that stores current meeting information like Meeting Title,Location ,EventDate,EndDate,OrganizerAccount etc. This class collects its data from 3 seperated data store 1) in Meeting Workspace “Meeting Series” List’s item data 2) related “Calendar” Event item data and 3) created Exchange AppointmentID and appointment created time.Why we are doing this or why we need another object to store all data ? Beacuse sharepoint objects are not able to serializable .You may need to keep changes and compare them .Also we have to store appointment object information which is created in Exchange Server for finding it when we need.

//Geting currentMeeting object form “Meeting Series” list.
SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
//Creating a MeetingInfo object and filling it all needed information from currentMeeting object , related Event, !!Appointment data will be add later.
MeetingInfo info = MeetingInfo.GetMeetingInfo(currentMeeting);

//Creating a Exchange Service Connection and Impersonate with current user (By the way in WebPart Page_Load event we are restricting other users can can use this webpart except owner and orginazer of this meeting instance.So we are sure that the current user is owner this meeting.)
ExchangeServiceConnection conn = new ExchangeServiceConnection(SPContext.Current.Web.CurrentUser);

//Creating An Exchange Appointment object
Appointment app = ExchangeHelper.CreateAppointment(conn.Service, info);

(Basically we are doing in this function something like below:
Appointment app = new Appointment(service);
app.Subject = info.Title;             
app.Start = info.EventDate;             
app.End = info.EndDate;             
app.Location = info.Location;            
….
return app;
)

//Adding all attendees to newly created Appointment object from “Attendees” list which is defined in Meeting Workspace.
SPList attendeesList = SPContext.Current.Web.Lists[“Attendees”]
AddAttendees(app);

app.Save();  //Saving the appointment to Exchange.(this will creates a new appointment in Exchange server for current owner and sends meeting request to attendees)
info.AppointmentID = app.Id.UniqueId;  //We are storing the ID of the Appointment. ***

SaveAppointment(info); //Saving all information about this appointment to Sharepoint Meeting Workspace in SPWeb.Properties

(Basically we are doing in this function something like below:
       info.RequestSentDate = DateTime.Now;             
       web.Properties.Add(info.MeetingIdentifier, MeetingInfo.Serialize(info));                     
       web.Properties.Update(); )

PART 2:
How to send Real Meeting Request from Sharepoint 2010 – part 2

Here is the some useful resources:

Exchange Server Developer Center
http://msdn.microsoft.com/en-us/exchange/aa731543

Working with Authentication in Microsoft Exchange Online
http://msdn.microsoft.com/en-us/library/gg194011(v=exchg.140).aspx

MSDN SPMeeting Class definition
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.meetings.spmeeting.aspx

Sharepoint Top 10 Codeplex project for Developers

Hi Everyone,

Here is my top 10 sharepoint codeplex project for Developers :

1)  Sharepoint 2010 Fluent Ribbon Api:
Fluent API for Ribbon creation in SharePoint 2010. Create and manage your ribbon without unpredictable xml or typo-prone “magic strings”
http://spribbon.codeplex.com/

2)  jQuery Library for SharePoint Web Services
This is a jQuery library which abstracts SharePoint’s Web Services and makes them easier to use. It also includes functions which use the various Web Service operations to provide more useful (and cool) capabilities. It works entirely client side and requires no server install.
http://spservices.codeplex.com/

3) SharePoint Developer Tools for Visual Studio 2010
this project extends the Visual Studio 2010 SharePoint Project system with advanced templates and tools. Using these extensions you will be able to find relevant information easily without leaving Visual Studio. You will have an easier time developing SharePoint components and you will have broader capabilities to deploy them on your test environment.
http://sharepointdevtools.codeplex.com/

4) SP List Kit for SharePoint 2010
SP List Kit for SharePoint 2010 is rich feature set to enhance usability of all SharePoint Lists. It supports SharePoint 2010. All of SP List Kit support Sandboxed Solutions and SharePoint Online for Office 365
http://splistkit.codeplex.com/

5) Sharepoint Form Generator for (2007)
The SharePoint Form Generator
allow all users to add entries to the list, and can be used to generate rich UI forms with field validation to be embed in your pages. The Web Part supports all types of columns used in SharePoint lists.
http://sfg.codeplex.com/

6)  Sharepoint Search Service Tool
The SharePoint Search Service Tool is a rich web service client that allows a developer to explore the scopes and managed properties of a given SharePoint Search SSP, build queries in either Keyword or SQL Syntax, submit those queries and examine the raw web service results. This tool can be useful in troubleshooting and verifying the behavior and configuration of a SharePoint environment.
http://sharepointsearchserv.codeplex.com/

7) Show or Hide SharePoint 2010 ribbon based on SharePoint Groups
This SharePoint 2010 solution allow site administrator to define who can or cannot see the SharePoint ribbon.
http://spribbonvisibility.codeplex.com/

8) Useful Sharepoint Designer Custom Workflow Activities
This project takes aim at making it easier to create advanced workflows using Sharepoint Designer by providing a set of custom workflow activities
Send Email with HTTP File attachment ,Send Email with List Item attachments ,Start Another Workflow ,Grant Permission on Item ,Delete List Item Permission Assigment ,Reset List Permissions Inheritance,Is User a member of a SharePoint group ,Is Role assigned to User ,Lookup user info
http://spdactivities.codeplex.com/ 

9) My Masters Sample Project for Sharepoint 2010
The feature stapling example project which is provide to deploy custom master page to personel sites on Sharepoint 2010
The solution is anwering fallowing questions :
* How to deploy a custom master page ?
* How to customize a masterpage ?
* How to attach custom master page to personal sites using stapling feature ?
* How to set wellcome page programmatically ?
* How to add document library as a web part to a page ?
http://mymasters.codeplex.com/

10) SharePoint 2010 Search Results Customization 
By using this XSLT code, You can customize the SharePoint 2010 Search results from regular format to Tabular format.
http://sharepoint2010search.codeplex.com/