Category Archives: Visual Studio 2013

Tip: Create New List in SharePoint Online Using Exception Handling Scope and Set Properties | PowerShell | CSOM

Summary

While presenting about SharePoint Online Client Side Object Model a question popped up “Hey! How can I create a new list if it’s not exist and change properties if exists?”. Not a difficult one. However, we need to build codes with best practise suggested by Microsoft. In short answer is available here.

Requirement

  • Create a List if it’s not existing.
  • Change Properties if it exists.
  • Allow to create multiple lists in one run
  • Allow users to choose the list template.

Solution

Build a binary cmdlet using C# and meet your needs by parameterizing the code. Look at the code below.

using System;
using System.Management.Automation;
using Microsoft.SharePoint.Client;
namespace xSharePointOnline
{
    [Cmdlet(VerbsCommon.New, "SPOList")]
    public class NewSPOList : PSCmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
        public Uri SPOurl;
 
        [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ValueFromPipeline = true)]
        public string SPOListName;
 
        [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
        public ListTemplateType SPOListTemplateType;
 
        [Parameter(Mandatory = true)]
        [Credential]
        public PSCredential SPOCredential;
 
        protected override void ProcessRecord()
        {
            base.ProcessRecord();
            using (ClientContext SPOClientContext = new ClientContext(SPOurl))
            {
                SPOClientContext.Credentials = new SharePointOnlineCredentials(SPOCredential.UserName, SPOCredential.Password);
                ExceptionHandlingScope Scope = new ExceptionHandlingScope(SPOClientContext);
                using (Scope.StartScope())
                {
                    using (Scope.StartTry())
                    {
                        List oList = SPOClientContext.Web.Lists.GetByTitle(SPOListName);
                        oList.Update();
                    }
                    using (Scope.StartCatch())
                    {
                        ListCreationInformation oListInformation = new ListCreationInformation();
                        oListInformation.Title = SPOListName;
                        oListInformation.TemplateType = (int)SPOListTemplateType;
                        List oList = SPOClientContext.Web.Lists.Add(oListInformation);
                    }
                    using (Scope.StartFinally())
                    {
                        List oList = SPOClientContext.Web.Lists.GetByTitle(SPOListName);
                        oList.Hidden = true;
                        oList.Description = "PowerShell Rocks!";
                    }
                }
                SPOClientContext.ExecuteQuery();
            }
        }
    }
}

How to use it?

  • Create a C# Class Library
  • Copy and paste the code. If required change the parameters as required.
  • Build it to get the DLL (Binary)
  • Using Import-Module load the binary DLL E.G. Import-Module C:\Location\Solution.DLL
  • Run the cmdlet New-SPOList -SPOUrl -SPOListName -SPOListTemplateType -SPOCredential

Here the SPOListTemplate populate the enum values of List Template – So, we can choose the one we need by tab completion

How it works?

We have used Exception handling scope which makes one call to the server and that means a lot of performance improvement. All three Try, catch and finally executes at one time.
Try
This code simply checks the existence of the list and if exists it will update the hidden and description properties.
Catch
If try catch throws exception it will create a new list – If in case of the list not existing.
Finally
Update the lists properties.

Screen Shot

2746.123

SharePoint Online PowerShell Tip: Conditional Scope – Binary Module

SharePoint Online PowerShell Tip to throw exception while connecting to Tenant.

Introduction

Recently one of our customer requested us to share a code which should throw an exception while connecting to SharePoint Online if in case of credential invalid or not connecting to tenant site. Well, they have a binary module delivered by some suppliers which is pretty straight forward and simple. If all set to good code will execute if not exception thrown in other cmdlet. The module they use has bunch of cmdlets which are more or less mock up of SharePoint Online cmdlets. Connect-SPOService throws exception if credential are invalid and they need custom error message for the custom built cmdlet Connect-SPOTenant

Requirement

  • Connect-SPOTenant : The sign-in name or password does not match one in the Microsoft account system
  • Connect-SPOTenant : Current site is not a tenant administration site.

PowerShell Code

Below is the PowerShell code shared by our client.

function global:Connect-SPOSite {
 [CmdletBinding()]
 param (
 [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
 $Url
 )
 
 begin {
 [System.Reflection.Assembly]::LoadFile("C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll") | Out-Null
 [System.Reflection.Assembly]::LoadFile("C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll") | Out-Null
 }
 process {
 if ($global:spoCred -eq $null) {
 $cred = Get-Credential -Message "Enter your credentials for SharePoint Online:"
 $global:spoCred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred.UserName, $cred.Password)
 }
 $ctx = New-Object Microsoft.SharePoint.Client.ClientContext $Url
 $ctx.Credentials = $spoCred
 
 if (!$ctx.ServerObjectIsNull.Value) {
 Write-Host "Connected to site: '$Url'" -ForegroundColor Green
 }
 return $ctx
 }
 end {
 }
}

Solution

Indeed, the above code will not throw any exception because the ClientContext Object is instantiated and will not validate the credential but returns the ClientContext Object as output. More over Microsoft.SharePoint.Client.ClientContext doesn’t have ServerObjectIsNull property. No matter we supply wrong password the host shows Connected to Site!

Conditional Scope

C# code with conditional scope is below. This is just a demo so we haven’t used any scope methods or properties

using System;
using System.Management.Automation;
using Microsoft.SharePoint.Client;
using Microsoft.Online.SharePoint.TenantAdministration;
namespace xSharePointOnline
{
 [Cmdlet(VerbsCommunications.Connect, "SPOTenant")]
 
 public class ConnectSPOTenant : PSCmdlet
 {
 [Parameter()]
 public Uri SPOUrl;
 
 [Parameter()]
 [Credential]
 public PSCredential SPOCredential;
 protected override void ProcessRecord()
 {
 using (ClientContext SPOClientContext = new ClientContext(SPOUrl))
 {
 SPOClientContext.Credentials = new SharePointOnlineCredentials(SPOCredential.UserName, SPOCredential.Password);
 Tenant oTenant = new Tenant(SPOClientContext);
 ConditionalScope Scope = new ConditionalScope(SPOClientContext, () => oTenant.ServerObjectIsNull.Value != true);
 SPOClientContext.ExecuteQuery();
 }
 }
 }
}

Screen Shot

1

2

Converting JSON Time Format in SharePoint Document Library Metadata


The SharePoint farm has a Document Library and a List which are linked for some requirements, while querying information we received some data which are not in proper format. Challenge is to split, remove characters and count the total which is little tedious

Example- The Field3 in CSV yields [“\/Date(1444995273796)\/”,”\/Date(1444996968515)\/”]

It’s a JSON format and the time format is EPOCH (UNIX format) – With Reference to the link MSDN My advice to customer was to use below code snippet to break the mystery!

To get the count: (Unfortunately, this is what customer need!) – No Fun in it because this kills the actual flavor of SharePoint development and data.

(@"
["\/Date(1444995273796)\/","\/Date(1444996968515)\/"]
"@ | ConvertFrom-Json).Count

#Output
#2

The reason for the SPContext Code by developer is unknown. So here comes the ConvertFrom-JSON power in Windows PowerShell Version 3+ 🙂 🙂 🙂

To get the information about the data in JSON: [We will deep dive in Part 2 of this Blog]

@"
["\/Date(1444995273796)\/","\/Date(1444996968515)\/"]
"@ | ConvertFrom-Json

#Output

#Friday, October 16, 2015 11:34:33 AM
#Friday, October 16, 2015 12:02:48 PM

The file which is generated as report is done using C# and CSOM – So, in next blog post (Part 2) we will cover Binary Module using C# Class Library, PowerShell Module, String Manipulation and Data consolidation.

Enjoy PowerShell !

Show or Hide SharePoint List Using CSOM | C# | PowerShell

Disclaimer: This is pretty old topic just remade it using CSOM and PowerShell at my client work place.

During SharePoint due diligence many suggested to use SharePoint Manager Tools, CAML Query Builder etc. It’s better to keep tools handy but gathering and executing the client requirement is better than the best.

Environment: Client has WSS 3.0, MOSS 2007 and SharePoint 2010 platforms, they want to organize the structure and keep the contents similar. An ideal goal is to move to upgraded versions.

During this big discussion development team suggested to make a script which reads the web, site, lists and document library properties and set the same in each farm. Dude! writing script is easy and deploying is very easy as well. But, before we do that let’s know why properties are set differently ? Who made the decision? Business Justification is much more important so I suggested Power Users or SharePoint L1 to decide and deploy the solution.

How? Power Users like GUI based solutions they don’t want to execute console applications or scripts. As usual we picked up a call and I was shocked by listening to content manager requirement – “Need one liner cmdlet and we will create Lists and Set it’s Property. It may be one or many!” It’s that simple PowerShell reached to content managers as well. 🙂 I was happy because I am going to meet their needs in short span of time!

To kick on the demo in a catchy way. I showed them how PowerShell one liner looks like 🙂

Get-EvenNumbers -From 1 -To 10

It’s that simple to use, I haven’ t used any validation in this function very simple code which prints the even number using range operators. The function code is below

Function Get-EvenNumbers
{
    param(
    [Parameter(Mandatory = $true)]
    $From,
    [Parameter(Mandatory=$true)]
    $To
    )

    ($From..$To).ForEach({if($_ %2 -eq 0){$_}})
}
Get-EvenNumbers -From 1 -To 10

Solution for Content Managers:

Consume CSOM and build binary module using Class Library 🙂 🙂 🙂 This time I used Visual Studio 2013 just for a change 🙂

using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Net;
using System.Management.Automation;
using Microsoft.SharePoint.Client;

[Cmdlet(VerbsCommon.Set,"SPListVisibility")]
public class SetSPListVisibility : Cmdlet
{
    [Parameter(Mandatory = true)]
    public string SPUrl;

    [Parameter(Mandatory = true)]
    public string SPListName;

    [Parameter(Mandatory = true)]
    public bool ListVisibility;
    protected override void ProcessRecord()
    {
        ClientContext ctx = new ClientContext(SPUrl);
        NetworkCredential credentials = CredentialCache.DefaultNetworkCredentials;
        ctx.Credentials = credentials;

        List list = ctx.Web.Lists.GetByTitle(SPListName);
        ctx.Load(list);

        list.Hidden = ListVisibility;
        list.Update();
        ctx.ExecuteQuery();
        ctx.Dispose();
    }
}

Usage (Just for Demo):

Import-Module C:\Scripts\Module\CSOM_Demo.Dll
#Hide the List
Set-SPListVisibility -SPUrl http://weburl -SPListName "PowerShell" -ListVisibility $false

#Show the List
Set-SPListVisibility -SPUrl http://weburl -SPListName "PowerShell" -ListVisibility $true

In next my next blog I will share the complete module! It’s that’s easy ! Happy SharePointing and Enjoy PowerShell 🙂 🙂 🙂

Reason: Content manager need this kind of solution for re usability. Smart Guy!

Create your own ISE Addon using Visual Studio 2013

Windows PowerShell discussion with System Administrators and Developers: Feedback – ISE has no good Add-On’s. Many uses ISE Steroids which is an excellent add-on for PowerShell ISE. We do have script browser and analyzer now.

Comparing ISE with Visual Studio is not fair 🙂 Why do you want to do that? WMF 5.0 and it’s features are far better than earlier versions. So, indeed PowerShell ISE is also grown up 🙂

We don’t have commands to meet all our needs in Windows PowerShell so we create a function , Proxy Functions, Workflow, Class or modules for various needs. Similarly, we can create our own add on for ISE. Let us see a quick demo of it using Visual Studio 2013.

We can easily create this using with the available VSIX if not you can opt for WPF Control Library and create a add-on as required by adding Microsoft.PowerShell.GPowerShell. In this article we will make our job easy by using VSIX – Click to download .

Read the documentation and install the VSIX as required. Now, we will create a simple CustomAddon which will insert a code or some string into the current ISE file.

Open Visual Studio 2013 and choose Visual C# and select PowerShell ISE Add-on for VS2013. Name it as required! In our case I have named it as CustomAddOn as shown below

1

Now open up the UserControl1.xaml.cs code – Just double click it and the below will be the default code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.PowerShell.Host.ISE;

namespace CustomAddOn
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : IAddOnToolHostObject
    {
        public UserControl1()
        {
            InitializeComponent();
        }

     <strong>   public ObjectModelRoot HostObject
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }</strong>
    }
}

Okay, we have the pseudo code – let’s do some modification and test the ISE add-on to insert a code or some string in ISE. To do that first we need to comment the below lines and just add get and set like shown below

public ObjectModelRoot HostObject
        {
            //get
            //{
            //    throw new NotImplementedException();
            //}
            //set
            //{
            //    throw new NotImplementedException();
            //}
            get;
            set;
        }

Now, it’s time for us to add the controls and code as required. For, testing let us add a button and trigger an event which inserts code or string in ISE current file.

So, I have added a button in XAML file and the code looks like below

<UserControl x:Class="CustomAddOn.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="Insert Code" HorizontalAlignment="Left" Margin="32,57,0,0" VerticalAlignment="Top" Width="215" RenderTransformOrigin="-0.846,-0.893" Name="code" Click="click_insert"/>

    </Grid>
</UserControl>

Just make a note – I have made the name of the button as code and created a click event but haven’t did any code for event firing. so, to do that we will jump back to CS file and code as given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.PowerShell.Host.ISE;

namespace CustomAddOn
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : IAddOnToolHostObject
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void click_insert(object sender , RoutedEventArgs e)
        {
            HostObject.CurrentFile.Editor.InsertText("Get-Service");
        }

        public ObjectModelRoot HostObject
        {
            //get
            //{
            //    throw new NotImplementedException();
            //}
            //set
            //{
            //    throw new NotImplementedException();
            //}
            get;
            set;
        }
    }
}

Do right click on the CustomAddon in solution explorer and Build your solution then spin up your PowerShell ISE and execute the below piece of code

Import-Module C:\Temp\CustomAddOn\CustomAddOn\bin\Debug\CustomAddOn.dll
$psISE.CurrentPowerShellTab.VerticalAddOnTools.Add("CustomAddOn" , [CustomAddOn.UserControl1] , $true)

🙂 🙂 🙂 🙂 🙂 Tada! We have our Custom Add on in ISE

2

In PowerShell we can do the same using below one liner 🙂

3

That’s it for now ! We will see more WPF controls and building ISE Add-On’s using Visual Studio 2013!

Cheers! Enjoy PowerShell!