Tuesday, 7 June 2016

Use PowerShell to Create and Manage Users and Groups in SharePoint Online

Use PowerShell to Create and Manage Users and Groups in SharePoint Online 

I have an upcoming talk at TechEd 2014 and part of it will be spent showing you how you can manage users with PowerShell in SharePoint Online.  I thought, I would give a little preview and show you some of the ways you can manage users.  If you are using Office 365, this post will get you started, creating, deleting, and adding users to groups.   You'll also learn how to set permissions on groups as well as promote site collection administrators.  You'll need to install SharePoint Online Management Shell, if you haven't already. 
Get started by opening a session using Connect-SPOService and the full URL to the admin site of your tenant.  You can see my first SharePoint Online PowerShell post for the syntax.
You'll need to know the URL to the site collection you are working with for all of these commands. 

Getting a list of users

We can start by getting a simple list of all users on a site using Get-SPOUser.
Get-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection
SPOPOwerShellGetSPOUser
This will give you a list of all users, the login name, and what groups each user belongs to.  If you look all the way down the list, you'll even notice some internal hidden users such as the cache, crawl, and system accounts.
SPOPOwerShellGetSPOUser2
Even with a small list, you'll notice that this cmdlet takes a while to execute.  You can filter it by specifying a specific user or group.  For example, to retrieve the user information for our user, Sara Davis, we use the same cmdlet with the -LoginName parameter.  Keep in mind you have to specify the full login name.
Get-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -LoginName user@mytenant.onmicrosoft.com
SPOPOwerShellGetSPOUserLoginName
To view all of the users in a group, use the -Group parameter.
Get-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection - Group "My Group"
SPOPOwerShellGetSPOUserGroup
You'll notice there are not any commands to add new users.  Those are handles at the Office 365 level.  If the user requires a brand new account, you create the user there and then add them to the appropriate groups.

Getting a list of groups

We can retrieve a list of groups on a given site using Get-SPOSiteGroup.
Get-SPOSiteGroup -SiteName https://mytenant.sharepoint.com/sites/mysitecollection
SPOPowerShelGetSPOSiteGroup
This will show you the name of the group, the roles of the group, and what users are in it.  You may want to use FormatTable to make the results easier to read.
Get-SPOSiteGroup -SiteName https://mytenant.sharepoint.com/sites/mysitecollection | FT Title, Roles -AutoSize
SPOPowerShelGetSPOSiteGroupFormatTable
You can also request a specific group by name, with the -Group parameter
Get-SPOSiteGroup -SiteName https://mytenant.sharepoint.com/sites/mysitecollection -Group "My Group"
SPOPowerShellGetSPOSiteGroupByName

Creating a group

To create a Group, we use the New-SPOSiteGroup cmdlet.  You will need to pass the name of the group using the -Group parameter as well as the site collection.  In the -PermissionLevels attribute, you pass the name of a known permission level such as Contribute, Design, or Full Control.
New-SPOSiteGroup -Site https://mytenant.sharepoint.com/sites/mysitecollection -Group "Group Name" -PermissionLevels "Contribute"
SPOPowerShellNewSPOSiteGroup
This cmdlet tends to take a while.  Once it's done, it will return information about your group.  If you assign the return value of this cmdlet to a variable, you can then pass it to Add-SPOUser to add a user to the group.

Adding a user to a group

Once you create a group, you will probably want to add a user to it.  We can do that with Add-SPOUser.
Add-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Group "Group Name" -LoginName user@mytenant.onmicrosoft.com
SPOPowerShellAddSPOUser
Using Get-SPOUser, like we showed earlier, we can verify our new users is in the group.
SPOPowerShellGetSPOUserGroup2

Removing a user from a group

As you might guess, removing a user from a group takes the same three parameters with the Remove-SPOUser cmdlet.  However, the Group is optional.  Include it to remove the user from a specific group or omit it to remove the user from the site entirely.
Remove-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Group "Group Name" -LoginName user@mytenant.onmicrosoft.com
SPOPowerShellRemoveSPOUserGroup

When successful, no output will be returned.

Adding a permission level to a group

To change permissions on a group, we use the Set-SPOSiteGroup  To add a permission level to a group, use the -PermissionLevelsToAdd parameter.  Note this cmdlet uses the -Identity parameter instead of -Group.
Set-SPOSiteGroup SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Identity "Group Name" -PermissionLevelsToAdd "Design"
SPOPowerShellSetSPOSiteGroupAddPermissions

Removing a permission level from a group

We can also use Set-SPOSiteGroup to remove a permission level as well using the -PermissionLevelsToRemove parameter.
Set-SPOSiteGroup SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Identity "Group Name" -PermissionLevelsToRemove "Contribute"
SPOPowerShellSetSPOSiteGroupRemovePermissions
You can also use Set-SPOSiteGroup to rename it with the -Name parameter as well as change the owner with the -Owner parameter.

Removing a group

To remove the group, use the Remove-SPOSiteGroup.  For some reason, this cmdlet uses the -Identity parameter instead of -Group so pass the name there.
Remove-SPOSiteGroup SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Identity "Group Name"
SPOPowerShellRemoveSPOSiteGroup

Make a user a site collection administrator

We can give users site collection administrator rights, but the functionality is buried in Set-SPOUser.  Set the -IsSiteCollectionAdmin command to $true to make the user a site collection administrator.
Set-SPOUser -Site https://mytenant.sharepoint.com/sites/mysitecollection -Group "Group Name" -LoginName user@mytenant.onmicrosoft.com -IsSiteCollectionAdmin $true
SPOPowerShellSetSPOUser
To remove site collection administrator rights, simple set IsSiteCollectionAdmin to $false.

Get a list of site collection administrators

If you want to see who all of the site collection administrators are, you can find the value on the IsSiteAdmin property of the user object returned from Get-SPOUser.  You just have to display it.  In the example below, we select the column using Format-Table (ft).
SPOPowerShellGetSPOUsersSiteCollectionAdmin

We'll be covering this and a lot more at my PowerShell talk at TechEd next week.  If you are there, be sure and attend.

Using PowerShell to Manage SharePoint 2013 Online

Getting Started

Before you can start working with the SharePoint Online cmdlets you must first download those cmdlets. Having the cmdlets as a separate download (separate from SharePoint on-premises that is) allows you to use any machine to run the cmdlets. All we have to do is make sure we have PowerShell V3 installed along with the .NET Framework v4 or better (required by PowerShell V3). With these prerequisites in place simply download and install the cmdlets from Microsoft: http://www.microsoft.com/en-us/download/details.aspx?id=35588.
Once installed open the SharePoint Online Management Shell by clicking Start > All Programs > SharePoint Online Management Shell > SharePoint Online Management Shell.  Just like with the SharePoint Management Shell for on-premises deployments the SharePoint Online Management Shell is just a standard PowerShell window. You can see this by looking at the target attribute of the shortcut properties:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking;"
As you can see from the shortcut, a PowerShell module is loaded: Microsoft.Online.SharePoint.PowerShell. Unlike with SharePoint on-premises, this is not a snap-in but a module, which is basically the new, better way of loading cmdlets. The nice thing about this is that, like with the snap-in, you can load the module in any PowerShell window and are not limited to using the SharePoint Online Management Shell. (The -DisableNameChecking parameter of the Import-Module cmdlet simply tells PowerShell to not bother checking for valid verbs used by the loaded cmdlets and avoids warnings that are generated by the fact that the module does use an invalid verb – specifically, Upgrade). Note that unlike with the snap-in, there’s no need to specify the threading options because the cmdlets don’t use any unmanaged resources which need disposal.

Getting Connected

Now that you’ve got the SharePoint Online Management Shell installed you are now ready to connect to your tenant administration site. This initial connection is necessary to establish a connection context which stores the URL of the tenant administration site and the credentials used to connect to the site. To establish the connection use the Connect-SPOService cmdlet:
Connect-SPOService -Url https://contoso-admin.sharepoint.com -Credential gary@contoso.com

Running this cmdlet basically just stores a Microsoft.SharePoint.Client.ClientContext object in an internal static variable (or a sub-classed version of it at least). Future cmdlet calls then use this object to connect to the site, thereby negating the need to constantly provide the URL and credentials. (The downside of this object being internal is that we can’t extend the cmdlets to add our own, unless we want to use reflection which would be unsupported). To clear this internal variable (and make the session secure against other code that may attempt to use it) you can run the Disconnect-SPOService cmdlet. This cmdlet takes no parameters.
One tip to help make loading the module and then connecting to the site a tad bit easier would be to encapsulate the commands into a single helper method. In the following example I created a simple helper method named Connect-SPOSite which takes in the user and the tenant administration site to connect to, however, I default those values so that I only have to provide the password when I wish to get connected. I then put this method in my profile file (which you can edit by typing “ise $profile.CurrentUsersAllHosts”):
function Connect-SPOSite() {
    param (
        $user = "gary@contoso.com",
        $site = "https://contoso-admin.sharepoint.com"
    )
    if ((Get-Module Microsoft.Online.SharePoint.PowerShell).Count -eq 0) {
        Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
    }
    $cred = Get-Credential $user
    Connect-SPOService -Url $site -Credential $cred
}

SPO Cmdlets

Now that you’re connected you can finally do something interesting. First let’s look at the cmdlets that are available. There are currently only 30 cmdlets available to us and you can see the list of those cmdlets by typing “Get-Command -Module Microsoft.Online.SharePoint.PowerShell”. Note that all of the cmdlets will have a noun which starts with “SPO”. The following is a list of all the available cmdlets:
  • Site Groups
  • Users
    • Add-SPOUser – Add a user to an existing Site Collection Site Group.
    • Get-SPOUser – Get an existing user.
    • Remove-SPOUser – Remove an existing user from the Site Collection or from an existing Site Collection Group.
    • Set-SPOUser – Set whether an existing Site Collection user is a Site Collection administrator or not.
    • Get-SPOExternalUser – Returns external users from the tenant’s folder.
    • Remove-SPOExternalUser - Removes a collection of external users from the tenancy's folder.
  • Site Collections
    • Get-SPOSite – Retrieve an existing Site Collection.
    • New-SPOSite – Create a new Site Collection.
    • Remove-SPOSite – Move an existing Site Collection to the recycle bin.
    • Repair-SPOSite – If any failed Site Collection scoped health check rules can perform an automatic repair then initiate the repair.
    • Set-SPOSite – Set the Owner, Title, Storage Quota, Storage Quota Warning Level, Resource Quota, Resource Quota Warning Level, Locale ID, and/or whether the Site Collection allows Self Service Upgrade.
    • Test-SPOSite – Run all Site Collection health check rules against the specified Site Collection.
    • Upgrade-SPOSite – Upgrade the Site Collection. This can do a build-to-build (e.g., RTM to SP1) upgrade or a version-to-version (e.g., 2010 to 2013) upgrade. Use the -VersionUpgrade parameter for a version-to-version upgrade.
    • Get-SPODeletedSite – Get a Site Collection from the recycle bin.
    • Remove-SPODeletedSite – Remove a Site Collection from the recycle bin (permanently deletes it).
    • Restore-SPODeletedSite – Restores an item from the recycle bin.
    • Request-SPOUpgradeEvaluationSite  - Creates a copy of the specified Site Collection and performs an upgrade on that copy.
    • Get-SPOWebTemplate – Get a list of all available web templates.
  • Tenants
    • Get-SPOTenant – Retrieves information about the subscription tenant. This includes the Storage Quota size, Storage Quota Allocated (used), Resource Quota size, Resource Quota Allocated (used), Compatibility Range (14-14, 14-15, or 15-15), whether External Services are enabled, and the No Access Redirect URL.
    • Get-SPOTenantLogEntry – Retrieves company logs (as of B2 only BCS logs are available).
    • Get-SPOTenantLogLastAvailableTimeInUtc – Returns the time when the logs are collected.
    • Set-SPOTenant – Sets the Minimum and Maximum Compatibility Level, whether External Services are enabled, and the No Access Redirect URL.
  • Apps
  • Connections
It’s important to understand that when working with all of the cmdlets which retrieve an object you will only ever be getting a simple data object which has no ability to act upon the source object. For example, the Get-SPOSite cmdlet returns an SPOSite object which has no methods and, though some properties do have a setter, they are completely useless and the object and its properties are not used by any other cmdlet (such as Set-SPOSite). This also means that there is no ability to access child objects (such as SPWeb or SPList items, to name just a couple).
The other thing to note is the lack of cmdlets for items at a lower scope than the Site Collection. Specifically there is no Get-SPOWeb or Get-SPOList cmdlet or anything of the sort. This can be potentially be quite limiting for most real world uses of PowerShell and, in my opinion, limit the usefulness of these new cmdlets to just the initial setup of a subscription and not the long-term maintenance of the subscription.
In the following examples I’ll walk through some examples of just a few of the more common cmdlets so that you can get an idea of the general usage of them.

Get a Site Collection

To see the list of Site Collections associated with a subscription or to see the details for a specific Site Collection use the Get-SPOSite cmdlet. This cmdlet has two parameter sets:
Get-SPOSite [[-Identity] <SpoSitePipeBind>] [-Limit <string>] [-Detailed] [<CommonParameters>]
Get-SPOSite [-Filter <string>] [-Limit <string>] [-Detailed] [<CommonParameters>]
The parameter that you’ll want to pay the most attention to is the -Detailed parameter. If this optional switch parameter is omitted then the SPOSite objects that will be returned will only have their properties partially set. Now you might think that this is in order to reduce the traffic between the server and the client, however, all the properties are still sent over the wire, they simply have default values for everything other than a couple core properties (so I would assume the only performance improvement would be in the query on the server). You can see the difference in the values that are returned by looking at a Site Collection with and without the details:
PS C:\> Get-SPOSite https://contoso.sharepoint.com/ | select *
LastContentModifiedDate   : 1/1/0001 12:00:00 AM
Status                    : Active
ResourceUsageCurrent      : 0
ResourceUsageAverage      : 0
StorageUsageCurrent       : 0
LockIssue                 :
WebsCount                 : 0
CompatibilityLevel        : 0
Url                       :
https://contoso.sharepoint.com/
LocaleId                  : 1033
LockState                 : Unlock
Owner                     :
StorageQuota              : 1000
StorageQuotaWarningLevel  : 0
ResourceQuota             : 300
ResourceQuotaWarningLevel : 255
Template                  : EHS#1
Title                     :
AllowSelfServiceUpgrade   : False

PS C:\> Get-SPOSite https://contoso.sharepoint.com/ -Detailed | select *
LastContentModifiedDate   : 11/2/2012 4:58:50 AM
Status                    : Active
ResourceUsageCurrent      : 0
ResourceUsageAverage      : 0
StorageUsageCurrent       : 1
LockIssue                 :
WebsCount                 : 1
CompatibilityLevel        : 15
Url                       :
https://contoso.sharepoint.com/
LocaleId                  : 1033
LockState                 : Unlock
Owner                     : s-1-5-21-3176901541-3072848581-1985638908-189897
StorageQuota              : 1000
StorageQuotaWarningLevel  : 0
ResourceQuota             : 300
ResourceQuotaWarningLevel : 255
Template                  : STS#0
Title                     : Contoso Team Site
AllowSelfServiceUpgrade   : True

Create a Site Collection

When we’re ready to create a Site Collection we can use the New-SPOSite cmdlet. This cmdlet is very similar to the New-SPSite cmdlet that we have for on-premises deployments. The following shows the syntax for the cmdlet:
New-SPOSite [-Url] <UrlCmdletPipeBind> -Owner <string> -StorageQuota <long> [-Title <string>] [-Template <string>] [-LocaleId <uint32>] [-CompatibilityLevel <int>] [-ResourceQuota <double>] [-TimeZoneId <int>] [-NoWait] [<CommonParameters>]
The following example demonstrates how we would call the cmdlet to create a new Site Collection called “Test”:
New-SPOSite -Url https://contoso.sharepoint.com/sites/Test -Title "Test" -Owner "gary@contoso.com" -Template "STS#0" -TimeZoneId 10 -StorageQuota 100

Note that the cmdlet also takes in a -NoWait parameter; this parameter tells the cmdlet to return immediately and not wait for the creation of the Site Collection to complete. If not specified then the cmdlet will poll the environment until it indicates that the Site Collection has been created. Using the -NoWait parameter is useful, however, when creating batches of Site Collections thereby allowing the operations to run asynchronously.
One issue you might bump into is in knowing which templates are available for your use. In the preceding example we are using the “STS#0” template, however, there are other templates available for our use and we can discover them using the Get-SPOWebTemplate cmdlet, as shown below:
PS C:\> Get-SPOWebTemplate
Name                     Title                         LocaleId  CompatibilityLevel
----                     -----                         --------  ------------------
STS#0                    Team Site                         1033                  15
BLOG#0                   Blog                              1033                  15
BDR#0                    Document Center                   1033                  15
DEV#0                    Developer Site                    1033                  15
DOCMARKETPLACESITE#0     Academic Library                  1033                  15
OFFILE#1                 Records Center                    1033                  15
EHS#1                    Team Site - SharePoint Onl...     1033                  15
BICenterSite#0           Business Intelligence Center      1033                  15
SRCHCEN#0                Enterprise Search Center          1033                  15
BLANKINTERNETCONTAINER#0 Publishing Portal                 1033                  15
ENTERWIKI#0              Enterprise Wiki                   1033                  15
PROJECTSITE#0            Project Site                      1033                  15
COMMUNITY#0              Community Site                    1033                  15
COMMUNITYPORTAL#0        Community Portal                  1033                  15
SRCHCENTERLITE#0         Basic Search Center               1033                  15
visprus#0                Visio Process Repository          1033                  15

Give Access to a Site Collection

Once your Site Collection has been created you may wish to grant users access to the Site Collection. First you may want to create a new SharePoint group (if an appropriate one is not already present) and then you may want to add users to that group (or an existing one). To accomplish these tasks you use the New-SPOSiteGroup cmdlet and the Add-SPOUser cmdlet, respectively.
Looking at the New-SPOSiteGroup cmdlet you can see that it takes only three parameters, the name of the group to create, the permissions to add to the group, and the Site Collection within which to create the group:
New-SPOSiteGroup [-Site] <SpoSitePipeBind> [-Group] <string> [-PermissionLevels] <string[]> [<CommonParameters>]
In the following example I’m creating a new group named “Designers” and giving it the “Design” permission:
$site = Get-SPOSite https://contoso.sharepoint.com/sites/Test -Detailed
$group = New-SPOSiteGroup -Site $site -Group "Designers" -PermissionLevels "Design“
(Note that I’m seeing the Site Collection to a variable just to keep the commands a little shorter, you could just as easily provide the string URL directly).
Once the group is created we can then use the Add-SPOUser cmdlet to add a user to the group. Like the New-SPOSiteGroup cmdlet this cmdlet takes three parameters:
Add-SPOUser [-Site] <SpoSitePipeBind> [-LoginName] <string> [-Group] <string> [<CommonParameters>]
In the following example I’m adding a new user to the previously created group:
Add-SPOUser -Site $site -Group $group.LoginName -LoginName "tessa@contoso.com"

Delete and Recover a Site Collection

If you’ve created a Site Collection that you now wish to delete you can easily accomplish this by using the Remove-SPOSite cmdlet. When this cmdlet finishes the Site Collection will have been moved to the recycle bin and not actually deleted. If you wish to permanently delete the Site Collection (and thus remove it from the recycle bin) then you must use the Remove-SPODeletedSite cmdlet. So to do a permanent delete it’s actually a two step process, as shown in the example below where I first move the “Test” Site Collection to the recycle bin and then delete it from the recycle bin:
Remove-SPOSite "http://contoso.sharepoint.com/sites/test" -Confirm:$false
Remove-SPODeletedSite -Identity "http://contoso.sharepoint.com/sites/test" -Confirm:$false

If you decide that you’d actually like to restore the Site Collection from the recycle bin you can simply use the Restore-SPODeletedSite cmdlet:
Restore-SPODeletedSite http://contoso.sharepoint.com/sites/test
Both the Remove-SPOSite and the Restore-SPODeletedSite cmdlets accept a -NoWait parameter which you can provide to tell the cmdlet to return immediately.

 

Use the SharePoint Web Controls



Use the SharePoint Web Controls

SharePoint brings its own controls, which can be used to display list items. In this article I want to show you how to use them in a Webpart. It took me a while to figure this out, because the documentation is kind of incomplete L
OK. Lets start. First lets find out which SharePoint Web Control belongs to which data type in SharePoint.





SharePoint Web Control

SharePoint data type
SharePoint Web Control
Single line of text
TextField
Multiple lines of text
 
PlainText
NoteField
Rich Text
RichTextField
Enhanced Rich Text
RichTextField
Choice
 
Dropdown
DropDownChoiceField
Radio Button
RadioButtonChoiceField
Number
NumberField
Currency
CurrencyField
Date and Time
DateTimeField
Lookup
 
Single Item
LookupField
Multiple Items
MultipleLookupField
Yes/No
BooleanField
Person or Group
UserField
Hyperlink or Picture
UrlField
Calculated
UrlField
Business data
 
How do we find which control belongs to the data type? We can simply look up this information on each field:
string siteUrl = "http://sharepoint";
string webUrl = "spscontrols";
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.AllWebs[webUrl])
{
SPList list = web.Lists["ControlTest"];
foreach (SPField field in list.Fields)
{
Console.WriteLine(field.Title + " – " + field.FieldRenderingControl);
}
}
}

SPControlMode

You can the controls in different Control Modes:
  • SPControlMode.Edit behaves like in an editform page of a list
  • SPControlMode.Display shows the data without the ability to change the values

Use the Controls

So how do we use these controls? The answer to this question is simple: Just use them like "normal" System.Web Controls.
RichTextField rtf = new RichTextField();
rtf.ID = "MultilineRichText";
rtf.ListId = list.ID;
rtf.ItemId = item.ID;
rtf.FieldName = "MultilineRichText";
rtf.ControlMode = SPControlMode.Edit;
this.Controls.Add(rtf);
In this case the RichTextField shows the content from the "MultilineRichText" field from our list, and our listitem in the Editmode. ID and FieldName are the Displayname from our field. You have to set the List, Item and FieldName for the Control, because usually the SharePoint Controls will use the SPContext content (remember: the controls are used in the editform, newform.. pages of every SharePoint List).
With some lines of code, you can display all fields e.g. from the DefaultView of a SharePoint List:
Table table = new Table();
TableRow row;
TableCell cell;
for (int i = 0; i < list.DefaultView.ViewFields.Count; i++)
{
string fieldName = list.DefaultView.ViewFields[i];
SPField field = list.Fields.GetField(fieldName);
row = new TableRow();
cell = new TableCell();
cell.Text = field.Title;
row.Cells.Add(cell);
cell = new TableCell();
// Add a control from RH.SharePoint.SharePointWebControls
Control cntrl = SharePointWebControls.GetSharePointControls(field, list, item, SPControlMode.Display);
// if the control is null (because it can not be rendered with a SharePoint Control) return if (cntrl == null) continue;
cell.Controls.Add(cntrl);
row.Cells.Add(cell);
cell = new TableCell();
cell.Controls.Add(SharePointWebControls.GetSharePointControls(field, list, item, SPControlMode.Edit));
row.Controls.Add(cell);
table.Rows.Add(row);
}
this.Controls.Add(table);

Use a generic control

Instead of finding a specific control for each SPField, you can use the BaseFieldControl. The advantage is, that it doesn’t matter which field you want to render. The right control will be used.





 

Creating fields using CSOM

Creating fields using CSOM

When creating a field, whether you are using CAML, server-side object mode, or one of the client-side object models, you typically specify the following attributes:
  • The ID of the fied, which is a GUID
  • The Name, which is the internal name of the field
  • The StaticName, which is the static name of the field
  • The DisplayName, which is display name of the field
  • The Type attribute which indicates the data type of the field
Only the attributes ID, Name and Type are required. You also have a number of other attributes that you set in order to indicate whether the field is required, whether the field can be used in a sort order, etc. You can find a detailed list of possible attributes and a detailed description in this MSDN reference article.
The order in which you specify the attributes is of no importance, but I always have the habit of specifying the ID first, then the internal name, display name and data type (except in this post where the focus lays on the different data types that can be used:) ). Setting the internal name is required, while the defining the static name is optional. The difference between the two fields is that the internal name needs to be unique within the site collection, and SharePoint can change this name at creation time to guarantee uniqueness. Static name must not be unique and will therefore not be changed by SharePoint.  Therefore it can be practical to specify both Name and StaticName attributes and set them to the same value.
Another point of interest is the SourceID attribute. You can set it, but you don’t have to. Out of the box SharePoint fields all have the SourceID set to http://schemas.microsoft.com/sharepoint/v3,  and a lot of developers have the habit set their own custom fields to this same value. But you don’t have to do this. If you look more closely at a field manually created by a user directly on a list, the sourceID is set to {$ListId:Lists/Demo List;}. A good practice is for example to build your SourceID as follows:
http://schemas.<company&gt;.com/<name of the application>/<release>
for example:
http://schemas.biwug.be/camldesigner/v1
This post gives you an overview of the different field types that you can create through CSOM.

Create a Text field

A simple text field can be created as follows:
string schemaTextField = "<Field ID='<GUID>' Type='Text' Name='LastName' StaticName='LastName' DisplayName='Last Name' />";
Field simpleTextField = demoList.Fields.AddFieldAsXml(schemaTextField, true, AddFieldOptions.AddToDefaultContentType);
clientContext.ExecuteQuery();
Written like this, SharePoint will ignore the internal name you specified, and will apply the display name. To make sure your internal name is applied, you have to add the AddFieldOptions.AddFieldInternalNameHint:
string schemaTextField = "<Field Type='Text' Name='LastName' StaticName='LastName' DisplayName='Last Name' />";
Field simpleTextField = demoList.Fields.AddFieldAsXml(schemaTextField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
You can find the (only) explanation of the AddFieldOptions enumeration here.
Know that this enumeration has the FlagsAttribute to allow a bitwise combination, meaning that you can combine the different values:
Field simpleTextField = demoList.Fields.AddFieldAsXml(schemaTextField, true, AddFieldOptions.AddInternalNameHint | AddFieldOptions.AddToAllContentTypes);

Creating an indexed field

While creating a field, you can also index it.
Field f = list.Fields.GetByInternalNameOrTitle(fieldName);
clientContext.Load(f);
clientContext.ExecuteQuery();
f.Indexed = true;
f.Update();
clientContext.ExecuteQuery();

Create a multi line field

You can create different types of multi line fields:
  • a plain text field
  • a rich text field
  • an enhanced text field

A plain multi line text field

string schemaMultilineTextField = "<Field ID='<GUID>' Type='Note' Name='Comments' StaticName='Comments' 
DisplayName='Comments' NumLines='6' RichText='FALSE' Sortable='FALSE' />" 
Field multilineTextField = demoList.Fields.AddFieldAsXml(schemaMultilineTextField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

A rich multi line text field

string schemaRichTextField = "<Field ID='<GUID>' Type='Note' Name='Comments' StaticName='Comments'
DisplayName='Comments' NumLines='6'  RichText='TRUE' Sortable='FALSE' />" 
Field multilineTextField = demoList.Fields.AddFieldAsXml(schemaRichTextField , true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

An enhanced multi line text field

string schemaRichTextField = "<Field ID='<GUID>' Type='Note' Name='Comments' StaticName='Comments' 
DisplayName='Comments' NumLines='6' RichText='TRUE' RichTextMode='FullHtml' IsolateStyles='TRUE' Sortable='FALSE' />" 
Field multilineTextField = demoList.Fields.AddFieldAsXml(schemaRichTextField , true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Create a boolean field

In the SharePoint user interface this is called a Yes/No field.
string schemaBooleanField = "<Field Type='Text' Name='Married' StaticName='Married' DisplayName='Married' />";
Field booleanField = demoList.Fields.AddFieldAsXml(schemaBooleanField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
If you want to set a default value, you have to specify a 0 for false or a 1 for true:
string schemaBooleanField = "<Field Type='Boolean' Name='Married' StaticName='Married' DisplayName='Married'>"
    + "<Default>0</Default></Field>;
Field booleanField = demoList.Fields.AddFieldAsXml(schemaBooleanField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Create a DateTime field

A DateTime field is created in a similar way, but you can set additional properties, like the Format property. In case of a DateTime field, the format attribute will indicate whether you want to create a date only field, or a date time field.

Date only field

string schemaBirthDate = "<Field ID='<GUID>' Type='DateTime' Name='BirthDate' StaticName='BirthDate' 
   DisplayName='Birth date' Format='DateOnly' >"
   + "<Default>[Today]</Default></Field>";
Field birthDateField = demoList.Fields.AddFieldAsXml(schemaBirthDate, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
The Default node is optional. The sample code snippet indicates that today’s date will be suggested to the user. If nothing is specified, no date will be sugested to the user.

Date and time field

string schemaArrivalField = "<Field ID='<GUID>' Type='DateTime' Name='ArrivalDateTime' StaticName='ArrivalDateTime' 
   DisplayName='Arrival' Format='DateTime'>"
   + "<Default>[Now]</Default></Field>";
Field birthDateField = demoList.Fields.AddFieldAsXml(schemaBirthDate, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
As in previous code sample, the Default node is optional. This sample code snippet indicates that the current date and time will be suggested to the user. If nothing is specified.

Create a Number field

With this type of field, you have to specify the different choices on beforehand. You can also choose if you want to show the different options within a dropdown list or with radio buttons.
string schemaNumberField = "<Field ID='<GUID>' Type='Number' Name='NbrOfEmployees' StaticName='NbrOfEmployees' 
   DisplayName='Number of employees' />";
Field birthDateField = demoList.Fields.AddFieldAsXml(schemaBirthDate, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
Previous code snippet will create a standard number field where the user can set positive and negative numbers, and where the number of decimals is generated automatically. If you want to declare a number field that only allows positive numbers, you will have to declare it this way:
string schemaPosNumberField = "<Field ID='<GUID>' Type='Number' Name='NbrOfEmployees' StaticName='NbrOfEmployees' 
   DisplayName='Number of employees' Min='0' />";
And if you want to restrict the range of values that can be entered by the user, you have to declare the number field the following way:
string schemaNumberField = "<Field ID='<GUID>' Type='Number' Name='NbrOfEmployees' StaticName='NbrOfEmployees' 
   DisplayName='Number of employees' Min='0' Max='5000'/>";
You can also define the number of decimals:
string schemaNumberField = "<Field ID='<GUID>' Type='Number' Name='NbrOfEmployees' StaticName='NbrOfEmployees' 
   DisplayName='Number of employees' Min='0' Decimals='0' />";
You can also create a percentage field by using the Number type. In that case you have to add an addition attribute Percentage, which you have to set to true:
string schemaPercentageField = "<Field ID='<GUID>' Type='Number' Name='NbrOfEmployees' StaticName='NbrOfEmployees' 
   DisplayName='Number of employees' Percentage='True' Decimals='2' />";

Create a Choice field

With this type of field, you have to specify the different choices on beforehand. You can also choose if you want to show the different options within a dropdown list or with radio buttons.

Dropdown list

string schemaChoiceField = "<Field ID='<GUID>' Type='Choice' DisplayName='Menu CHoice' Name='MenuChoice' StaticName='MenuChoice' 
   Format='Dropdown'>"
   + "<Default>Meat menu</Default>"
   +         "<CHOICES>"
   +         "    <CHOICE>Fish menu</CHOICE>"
   +         "    <CHOICE>Vegeterian menu</CHOICE>"
   +         "</CHOICES>"
   + "</Field>";
Field choiceField = demoList.Fields.AddFieldAsXml(schemaChoiceField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Radio buttons

string schemaChoiceField = "<Field ID='<GUID>' Type='Choice' Name='SideDishesChoice' StaticName='SideDishesChoice' 
   DisplayName='Side dishes' Format='RadioButtons'>"
   + "<Default>Patatoes</Default>"
   +         "<CHOICES>"
   +         "    <CHOICE>Fresh vegetables</CHOICE>"
   +         "    <CHOICE>Beans</CHOICE>"
   +         "</CHOICES>"
   + "</Field>";
Field choiceField = demoList.Fields.AddFieldAsXml(schemaChoiceField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Create a Picture field

If you want to create a picture field, you have to set the field type to URL. An additional attribute Format will indicate that you want to create a picture field:
string schemaPictureField = "<Field ID='<GUID>' Type='URL' Name='EmployeePicture' StaticName='EmployeePicture' 
   DisplayName='Employee Picture' Format='Image'/>";
Field pictureField = demoList.Fields.AddFieldAsXml(schemaPictureField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Create a URL field

If you want to create a field to contain an hyperlink, you also have to define a field of type URL, but in that case you set the Format attribute to Hyperlink:
string schemaUrlField = "<Field ID='<GUID>' Type='URL' Name='BlogUrl' StaticName='BlogUrl' DisplayName='Blog URL' Format='Hyperlink'/>";
Field urlField = demoList.Fields.AddFieldAsXml(schemaPictureField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Create a Lookup field

You typically create a lookup field when the value needs to be looked up in another SharePoint list. When creating a Lookup field, you also need to specify the necessary attributes to indicate the lookup list and the field that is shown when a value is selected:
string schemaLookupField = "<Field ID ='<GUID>' Type='Lookup' Name='Country' StaticName='Country' DisplayName='Country' 
    List='Countries' ShowField='Title' />"
Field lookupField = demoList.Fields.AddFieldAsXml(schemaLookupField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
If you want to show another field from the lookup list, instead of the Title, you can set the ShowField attribute to another field.
You can also define how the relationship with the lookup field must behave.  But in that case the field needs to be indexed:
string schemaLookupField = "<Field ID ='<GUID>' Type='Lookup' Name='Country' StaticName='Country' DisplayName='Country' 
    List='Countries' ShowField='Title' RelationshipDeleteBehavior='Restrict' Indexed='TRUE'/>"
If you want to create a multi-select lookup field, you have to use the type LookupMulti, and you have to set an additional attribute Mult (and not Multi):
string schemaMultiLookupField = "<Field ID ='<GUID>' Type='LookupMulti' Name='Country' StaticName='Country' DisplayName='Country' 
    List='Countries' ShowField='Title' Mult='TRUE'/>"

Create a User field

A field of type User is defined as follows:
string schemaUserField = "<Field ID ='<GUID>' Type='User' Name='Employee' StaticName='Employee' DisplayName='Employee' />"
Field userField = demoList.Fields.AddFieldAsXml(schemaUserField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
You can set different attributes:
  • UserSelectionMode: this attribute can be set to PeopleOnly or to PeopleAndGroups
  • UserSelectionScope: this attribute can be set to limit the selection of possible users to a certain group. The value must be an integer value that indicates the ID of group
Following code sample defines a user field that allows selection of multiple users from the site member group:
string schemaUserField = "<Field ID ='<GUID>' Type='UserMulti' Name='Employee' StaticName='Employee' DisplayName='Employee' 
   UserSelectionMode='PeopleOnly' UserSelectionScope='7' Mult='TRUE'/>"

Create a Managed Metadata field

The creation of a managed metadata field requires a bit more than just defining the CAML. I’ll add it here for completeness, but credits are for Waldek Mastykarz with his post Programmatically creating Site Columns and Content Types using the App Model
string schemaTaxonomyField = "<Field ID ='<GUID>’ Type='TaxonomyFieldType' Name='ProductCategory' StaticName='ProductCategory' 
    DisplayName='ProductCategory' />"
Field field = demoList.Fields.AddFieldAsXml(schemaTaxonomyField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();
Of course, this is not enough; you also have to bind this field to a termset or term in the term store:
Guid termStoreId = Guid.Empty;
Guid termSetId = Guid.Empty;
GetTaxonomyFieldInfo(clientContext, out termStoreId, out termSetId);
 
// Retrieve the field as a Taxonomy Field
TaxonomyField taxonomyField = clientContext.CastTo<TaxonomyField>(field);
taxonomyField.SspId = termStoreId;
taxonomyField.TermSetId = termSetId;
taxonomyField.TargetTemplate = String.Empty;
taxonomyField.AnchorId = Guid.Empty;
taxonomyField.Update();
 
clientContext.ExecuteQuery();
In case you want to create a multi-select managed metadata field, you have to define a field of type TaxonomyFieldTypeMulti.

Create a Calculated field

Calculated fields can be created in a number of flavors. The following code snippet generates a calculated field that will show employee data as follows:
Karine Bosch (id 82176)
string formula = "<Formula>=FirstName&amp; \" \" &amp;LastName&amp; \" (id: \" &amp;EmployeeID&amp; \" \"</Formula>"
      + "<FieldRefs>"
      + "<FieldRef Name='FirstName' />"
      + "<FieldRef Name='LastName' />"
      + "<FieldRef Name='EmployeeID' />"
      + "</FieldRefs>";

string schemaCalculatedField = "<Field ID='<GUID>' Type='Calculated' Name='FullName' StaticName='FullName' 
   DisplayName='Full Name' ResultType='Text' Required='TRUE' ReadOnly='TRUE'>" + formula + "</Field>";
Field fullNameField = demoList.Fields.AddFieldAsXml(schemaCalculatedField, true, AddFieldOptions.AddInternalNameHint);
clientContext.ExecuteQuery();

Represents user properties



Represents user properties



var object = new SP.UserProfiles.PersonProperties()

The PersonProperties object has the following members.

Constructor

The PersonProperties object has the following constructor.
Constructor
Description
PersonProperties

Methods

The PersonProperties object has the following methods.
Method
Description
initPropertiesFromJson
This member is reserved for internal use and is not intended to be used directly from your code.

Properties

The PersonProperties object has the following properties.
Property
Description
accountName
Gets the user's account name.
directReports
Gets the account names of the user's direct reports.
displayName
Gets the user's display name.
email
Gets the user's email address.
extendedManagers
Gets the account names of the user's manager hierarchy.
extendedReports
Gets the account names of the user's extended reports.
isFollowed
Gets a Boolean value that indicates whether the user is being followed by the current user.
latestPost
Gets the user's latest microblog post.
peers
Gets the account names of the user's peers.
personalUrl
Gets the absolute URL of the user's personal site.
pictureUrl
Gets the URL of the user's profile picture.
title
Gets the user's title.
userProfileProperties
Gets user profile properties for the user.
userUrl
Gets the URL of the user's profile page.

Gets user profile properties for the user

Gets user profile properties for the user


var value = SP.UserProfiles.PersonProperties.get_userProfileProperties()
 
Get Picture URL:
var value = SP.UserProfiles.PersonProperties.get_pictureUrl()
 
Get Account Name:
var value = SP.UserProfiles.PersonProperties.get_accountName()

Get Personal Url
var value = SP.UserProfiles.PersonProperties.get_personalUrl()

  
 
Property name keys for user profile properties
 
AboutMe
SPS-LastKeywordAdded
AccountName
SPS-Locale
ADGuid
SPS-Location
Assistant
SPS-MasterAccountName
CellPhone
SPS-MemberOf
Department
SPS-MUILanguages
EduExternalSyncState
SPS-MySiteUpgrade
EduOAuthTokenProviders
SPS-O15FirstRunExperience
EduPersonalSiteState
SPS-ObjectExists
EduUserRole
SPS-OWAUrl
Fax
SPS-PastProjects
FirstName
SPS-Peers
HomePhone
SPS-PersonalSiteCapabilities
LastName
SPS-PersonalSiteInstantiationState
Manager
SPS-PhoneticDisplayName
Office
SPS-PhoneticFirstName
PersonalSpace
SPS-PhoneticLastName
PictureURL
SPS-PrivacyActivity
PreferredName
SPS-PrivacyPeople
PublicSiteRedirect
SPS-ProxyAddresses
QuickLinks
SPS-RegionalSettings-FollowWeb
SID
SPS-RegionalSettings-Initialized
SISUserId
SPS-ResourceAccountName
SPS-AdjustHijriDays
SPS-ResourceSID
SPS-AltCalendarType
SPS-Responsibility
SPS-Birthday
SPS-SavedAccountName
SPS-CalendarType
SPS-SavedSID
SPS-ClaimID
SPS-School
SPS-ClaimProviderID
SPS-ShowWeeks
SPS-ClaimProviderType
SPS-SipAddress
SPS-ContentLanguages
SPS-Skills
SPS-DataSource
SPS-SourceObjectDN
SPS-Department
SPS-StatusNotes
SPS-DisplayOrder
SPS-Time24
SPS-DistinguishedName
SPS-TimeZone
SPS-DontSuggestList
SPS-UserPrincipalName
SPS-Dotted-line
SPS-WorkDayEndHour
SPS-EmailOptin
SPS-WorkDayStartHour
SPS-FeedIdentifier
SPS-WorkDays
SPS-FirstDayOfWeek
Title
SPS-FirstWeekOfYear
UserName
SPS-HashTags
UserProfile_GUID
SPS-HireDate
WebSite
SPS-Interests
WorkEmail
SPS-JobTitle
WorkPhone
SPS-LastColleagueAdded
 

Using Rest Services in Workflow

Using Rest Services in Workflow:
 
Let's start with SharePoint Designer workflow which accesses the SharePoint List data using REST call i.e Web Service Call

SharePoint List


The following is a list structure which we are referencing for our application.



Figure 1: SharePoint

Step 1: Create Site Workflow

Using SharePoint Designer create site workflow. Make sure you select SharePoint 2013 Workflow as the platform type.



Figure 2: Workflow

Step 2: Create Workflow Stage.

Let’s start by creating a new stage.



Figure 3: Stage

Workflow Stages

Stage 1: Workflow Initialization: The following variables get initialized at this stage:

ServiceURL: Here's the URL.



Figure 4: Initialized

Index: Create Index variable of type Integer & set it to 0.


Figure 5: Index

Service Call Header: Next, we add a Dictionary variable (Build a Dictionary action), call it requestHeaders and initialize it as this:



Figure 6: Header

Both “Accept” and “Content-Type” entries are of the String type and they both contain the value “application/json;odata=verbose”. SharePoint REST API understands this and sets the response content type appropriately as JSON. If we don’t pass these values, the output would come as XML.



Figure 7: Accept

Stage 2: Web Service Call
Add a Call as HTTP Web Service action and set its properties. The request will be the url variable:



Figure 8: Webservice

Set workflow variable "ServiceURL" as Web Service URL.

HTTP method as "GET".



Figure 9: Get

Response content will go to a new variable called responseContent.(type - Dictionary).

Response headers will go to a new variable called responseHeaders.(type - Dictionary).

Response code will go to a new variable called responseCode.(type - Dictionary ).

Then we set the request headers to be the requestHeaders variable we created just now, by clicking on the properties for the Call on HTTP Web Service action:



Figure 10: Call set variable as needed.



Figure 11: Variable

Process Web Service Response

Now, create a new stage, call it " Process Web Service Response".

At the end of the " Web Service Call" add a Go to Process Web Service Response stage.
  1. Add a Get an Item from a Dictionary action, set the item as d/results, the source variable reponseContentand the output to a new variable of type Dictionary called List.
  2. Then count items from this list variable using a Count Items in Dictionary action and store the result in a new Integer variable called TotalListItem. This variable will tell us how many times we have to loop.
  3. Finally, create a new Integer variable called index and set it to 0 (Set Workflow Variable), this will be the loop index.


Figure 12: Loop





List Item Looping
  1. Add a loop (Loop n Times), call it Loop Task Items, and set the loop variable to TotalListItem variable.
  2. Inside the loop, get value d/results([%Variable: index%]) using a Get an Item from a Dictionary action from responseContent and store it in a new Dictionary variable called CurrentItem.
  3. Get some fields (Get an Item from a Dictionary) from the CurrentItem variable, such as Title and store them in appropriate variables and do whatever you want with them, like logging its contents (Log).
  4. Its Time to increment the loop counter: add a Do Calculation action and in it increment the index variable into a new Integer variable called IncrementCounter.
  5. Then set the index variable to be the IncrementCounter(Set Workflow Variable).
  6. Finally exit the loop and set the workflow status (Set Workflow Status action) to Finished.
  7. At the end of the stage, select Go to End of Workflow.


Figure 13: TaskItem



Figure 14: String



Figure 15: item



Figure 16: listitem

Final Workflow



Figure 17: Workflow1



Figure 18: wk2



Figure 19: wk3



Figure 20: wk4

Check Workflow Execution

Add some list item's.




Figure 21: newitem

Follow below steps



Figure 22: follow

  • go to site content
  • Click Site Workflow
  • Select Appropriate workflow
  • Click it
  • Workflow started.
Output

Reference:

 http://www.c-sharpcorner.com/UploadFile/58e23e/call-http-web-service-using-sharepoint-designer-2013-spd/