Here is a sample PowerShell code which creates a list (Document Library) in SharePoint online.
Before running this code make sure SharePoint Online Client Components SDK and SharePoint Online Management Shell is installed on your machine. 
#Import the required DLL
Import-Module 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll'
#OR
#Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll'

#Mysite URL
$site = 'https://yoursite.sharepoint.com/'

#Admin User Principal Name
$admin = 'admin@tenant.onmicrosoft.com'

#Get Password as secure String
#$password = Read-Host 'Enter Password' -AsSecureString
$password = ConvertTo-SecureString "YourPassword" -asplaintext -force
#Get the Client Context and Bind the Site Collection
$context = New-Object Microsoft.SharePoint.Client.ClientContext($site)

#Authenticate
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin , $password)
$context.Credentials = $credentials
$listCreationInformation = New-Object Microsoft.SharePoint.Client.ListCreationInformation
$listCreationInformation.Title = "My Documents"
$listCreationInformation.Description = "Library created through PowerShell"
$listCreationInformation.TemplateType = 101
$list = $context.Web.Lists.Add($listCreationInformation)
$context.Load($list)
$context.ExecuteQuery()
If you want to prompt the user for password use $password = Read-Host 'Enter Password' -AsSecureString instead of $password = ConvertTo-SecureString "YourPassword" -asplaintext -force.

Library


Suppose the default.aspx page of a a site has been customized (unghosted) and needs to be reset. Following code shows how this can be done using SPFile.RevertContentStream()
using (SPSite site = new SPSite("http://aissp2013/sites/Team/"))
{   
    using(SPWeb web in site.RootWeb)
    {
        SPFile file = web.GetFile(web.Url + "/default.aspx");
        if (file.Exists)
        {
            file.RevertContentStream();
        }                      
    }
} 

Here is a PowerShell script to re-order fields in a List Content Type:

$web = Get-SPWeb http://aissp2013/sites/TestSite
$list = $web.Lists["MyList"]
$contentType = $list.ContentTypes | where {$_.Name eq "MyTestCT"}
$ctFields = "Title","ColumnA","ColumnB","ColumnD","ColumnC"
$contentType.FieldLinks.Reorder($ctFields)
$contentType.Update()

SharePoint 2013: Strings.js

Posted by Nadeem Yousuf | 21:52 | | 0 comments »

Ever wondered where the text like "drag files here" in Document Library or "edit this list" come from.

Drag Files Here

Edit This List

There is a JavaScript file named strings.js file which contains these values. It is stored in TEMPLATE\LAYOUTS\LCID, where LCID is the language identified. For English it is 1033. Here, you will also find a debug version of this file named strings.debug.js. Even though actual changes if needed are to be done in strings.js file but since it is minified reading it becomes quite difficult. The debug version is easy to read and understand. This is how "drag files here" is defined:
Strings.STS.L_SPAddNewAndDrag='{0} or drag files here';

The code in this post will show how to create recursive calendar events. The data about the Recurrence is stored in a field named "RecurrenceData". It is xml based data. One of the easy ways to determine what the value of "RecurrenceData" should be is to create an a recurrence item in the list from UI, get that item from code and find the data. Example:
SPList cal = web.Lists["Cal"];
SPListItem item = cal.GetItemById(1);
string data = item["RecurrenceData"].ToString();
Here is sample recurrence xml data
<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><weekly tu="TRUE" weekFrequency="1" /></repeat><repeatInstances>2</repeatInstances></rule></recurrence>
This is how it shows in UI. It is a weekly recurrence:

Weekly Recurrence

There are few other fields which need to be updated when creating a Recurrence event apart from "RecurrenceData". "EventType" which needs to be set to 1,"UID" which takes a GUID and "Recurrence" which is set to true. Here is a sample code which creates a Recurrence event.
static void Main(string[] args)
{
    using (SPSite site = new SPSite("http://aissp2013/sites/Team1/"))
    {
        SPWeb rootWeb = site.RootWeb;
        SPList cal = rootWeb.Lists["AIS Calendar"];
        SPListItem newItem = cal.AddItem();
        newItem["Title"] = "IDC Townhall";
        newItem["Location"] = "WAR Room 13";
        newItem["EventDate"] = new DateTime(2015,2,10, 10,0,0);
        newItem["EndDate"] = new DateTime(2015, 2, 10, 11, 0, 0);
        newItem["Recurrence"] = true;
        newItem["RecurrenceData"] = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><weekly tu='TRUE'" +
        " weekFrequency='1' /></repeat><repeatInstances>2</repeatInstances></rule></recurrence>";
        newItem["EventType"] = 1;
        newItem["UID"] = System.Guid.NewGuid();
        newItem.Update();
        cal.Update();
    }
}
Here is the Recurrence event in the UI created as a result of above code:

Recurrence Event


I recently found a bug in one of my codeplex projects Export Version History. A user was able to see the Export Version History option in Edit Control block aka ECB menu even if the user did not have ViewVersions permissions.

ECB Menu

Notice that in the above screenshot 'Export Version History' menu item is available whereas the out of the box 'Version History' menu item is correctly not available as current user does not have ViewVersions permissions. Also note that versioning is on in the list. 
One of my previous posts shows how a delegate control can be used to conditionally show menu item in ECB Menu. Time to revisit that code and see how this bug can be fixed. Following is the code from that post. It checks verEnabled property of Out of the box ctx object and if it is present it shows the ECB menu.
<script type="text/javascript">
    function Custom_AddListMenuItems(m, ctx) {
        AddECBMenuItems(m, ctx);  
    }

    function Custom_AddDocLibMenuItems(m, ctx) {
        AddECBMenuItems(m, ctx);
    }

    function AddECBMenuItems(m, ctx) {
        var pageUrl = ctx.HttpRoot + "/_layouts/NY.ExportVersionHistory/ExportVersionHistory.aspx?ID=" + currentItemID + "&amp;List=" + ctx.listName;
        if (ctx.verEnabled) {
            CAMOpt(m, "Export Version History", "window.open('" + pageUrl + "');", "/_layouts/images/NY.ExportVersionHistory/Excel_Small.png");
            CAMSep(m);
        }
    }
</script>
Now we need to check whether current user has ViewVersions permissions on the current item. So, I thought of writing the code in SharePoint JavaScript client object model. As client object model code runs asynchronously, it was obvious that ECB menu will be rendered before the async call is completed. Therefore, I started to write client object model code using JQuery deferred/Promises and came up with the following code:
function AddECBMenuItems(m, ctx) {
    var pageUrl = ctx.HttpRoot + "/_layouts/NY.ExportVersionHistory/ExportVersionHistory.aspx?ID=" + currentItemID + "&amp;List=" + ctx.listName;
    getItemPermissions(ctx.listName, currentItemID).then(
    function (permissions) {
        if (permissions.has(SP.PermissionKind.viewVersions)) {
            if (ctx.verEnabled) {
                CAMOpt(m, "Export Version History", "window.open('" + pageUrl + "');", "/_layouts/images/NY.ExportVersionHistory/Excel_Small.png");
                CAMSep(m);
            }
        }
    },
    function (sender, args) {
        console.log('An error occured while retrieving list item:' + args.get_message());
    });    
}

var getItemPermissions = function (listId, itemId) {
    var deferred = $.Deferred();
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getById(listId);
    var item = list.getItemById(itemId);
    context.load(item, 'EffectiveBasePermissions');
    context.executeQueryAsync(
       Function.createDelegate(this,
           function () {
               var permissions = item.get_effectiveBasePermissions();
               deferred.resolve(permissions);
           }),
       Function.createDelegate(this,
           function (sender, args) { deferred.reject(sender, args); }));

    return deferred.promise();
};
Putting above code to test, I was surprised to see that that Export Version History menu item was not available even if the list had versioning enabled and current user had ViewVersions permissions on the list item. It turns out that ECB menu is immediately rendered as can be seen from the following screenshot. By the time code in the if statement is hit, ECB is already created.

But the question is how come OOB Version History is working properly. The answer to this question is present in SharePoint JavaScript file CORE.js. This file contains functions for creating ECB and it resides in Layouts folder. open the debug version of this file named CORE.debug.js as opposed to minified version as reading the latter file can be difficult. Find a function named AddVersionsMenuItem. This function is used by SharePoint to decide whether to show OOB Version History menu item or not. Here is the code of this function.
function AddVersionsMenuItem(m, ctxt, url) {
    if (currentItemID != null) {
        var strCurrentItemID = currentItemID.toString();

        if (strCurrentItemID.indexOf(".0.") >= 0)
            return;
    }
    var fixedItemId = currentItemID;

    if (currentItemIsEventsExcp) {
        if (currentItemID.indexOf(".") != -1)
            fixedItemId = (currentItemID.split("."))[0];
    }
    if (!HasRights(0x0, 0x40))
        return;
    var strDisplayText = Strings.STS.L_Versions_Text;
    var strAction = "NavigateToVersionsAspxV4(event, '" + ctxt.HttpRoot + "', 'list=" + ctxt.listName + "&ID=" + fixedItemId + "&FileName=" + url + "')";
    var strImagePath = ctxt.imagesPath + "versions.gif";
    var menuOption = CAMOpt(m, strDisplayText, strAction, strImagePath, null, String(800));

    CUIInfo(menuOption, "ViewVersions", ["ViewVersions"]);
    menuOption.id = "ID_Versions";
}
As can be see a call is made to HasRights function with two parameters. The first parameter is a hex representation of EmptyMask permission and second is the hex representation of ViewVersions.   
This page has hex and decimal values of SharePoint base permissions. So the simple change which needs to be done in order to fix the bug is to make a call to HasRights function to check the permissions. 
Finally, the updated code:
<script type="text/javascript">
    function Custom_AddListMenuItems(m, ctx) {
        AddECBMenuItems(m, ctx);  
    }

    function Custom_AddDocLibMenuItems(m, ctx) {
        AddECBMenuItems(m, ctx);
    }

    function AddECBMenuItems(m, ctx) {
        var pageUrl = ctx.HttpRoot + "/_layouts/NY.ExportVersionHistory/ExportVersionHistory.aspx?ID=" + currentItemID + "&amp;List=" + ctx.listName;
        if (ctx.verEnabled && HasRights(0x0, 0x40)) {
            CAMOpt(m, "Export Version History", "window.open('" + pageUrl + "');", "/_layouts/images/NY.ExportVersionHistory/Excel_Small.png");
            CAMSep(m);
        }
    }
</script>

My SharePoint CodePlex Projects

SharePoint 2010 Autocomplete Lookup Field

Export Version History Of SharePoint 2010 List Items to Microsoft Excel.