Skip to main content

Karine Bosch

Go Search
Karine Bosch
  

The Silverlightness of SharePoint

Karine Bosch > Categories
Creating a Calendar View with PowerShell

Some days ago someone asked me if it is possible to create a calendar view on a SharePoint list. And yes, it is possible.

First let’s take a look at the .NET code to create a calendar view.

using (SPSite site = new SPSite("http://wss.u2ucourse.com"))
{
    using (SPWeb web = site.OpenWeb())
    {
        SPList sourcelist = web.Lists["Course Calendar"];

        string querystring =
            "<OrderBy><FieldRef Name='Title' /></OrderBy>"
          + "<Where><DateRangesOverlap><FieldRef Name=\"EventDate\" />"
          + "<FieldRef Name=\"EndDate\" /><FieldRef Name=\"RecurrenceID\" />"
          + "<Value Type=\"DateTime\"><Week /></Value></DateRangesOverlap></Where>";

        SPView newview = sourcelist.Views.Add("DemoCalView", null,
               querystring, 3, false, false,
               SPViewCollection.SPViewType.Calendar, false);
                        

        newview.ViewFields.Add(sourcelist.Fields["Title"]);
        newview.ViewFields.Add(sourcelist.Fields["Start Time"]);
        newview.Update();

    }
}

 

If you go to your SharePoint site and inspect this new view you will see that only the entries for this week are visible because of the DataRangesOverlap query that is set to weekly, but that it shows the data in a monthly view. This is because of the calendar scope that you can set in the user interface, but how to create a calendar view with a weekly scope programmatically?

Now to PowerShell. To create that same view with PowerShell you have to execute the following commands:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$siteUrl = "
http://wss.u2ucourse.com"
$site = new-object Microsoft.SharePoint.SPSite($siteurl)
$web = $site.OpenWeb()
$list = $web.Lists["Course Calendar"]
$querystring = "<OrderBy><FieldRef Name='Title' /></OrderBy>"
$querystring += "<Where><DateRangesOverlap>"
$querystring += "<FieldRef Name='EventDate' /><FieldRef Name='EndDate' />"
$querystring += "<FieldRef Name='RecurrenceID' />"
$querystring += "<Value Type='DateTime'><Week /></Value>"
$querystring += "</DateRangesOverlap></Where>"
$newview = $list.Views.Add("DemoCalView", $null, $querystring, 3, $false, $false, "CALENDAR", $false)
$titlefield = $list.Fields["Title"]
$newview.ViewFields.Add($titlefield)
$datefield = $list.Fields["Start Time"]
$newview.ViewFields.Add($datefield)
$newview.Update()

I hope to have helped someone out :)

Retrieving Items from a SharePoint List with Powershell and the SharePoint Lists.asmx

There is not yet much information on the net on how to combine Powershell with the SharePoint web services. One of the most used methods of the Lists.asmx, which is a standard SharePoint web service, is the GetListItems method. With this method you can retrieve all list items but also a subset of data when you use a CAML query. You can also limit the number of columns returned if you use a ViewFields node.

If you read previous posts and saved the necessary environment variable declarations in your profile, the only thing you should do to start is:

$listservice = New-Object Lists

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

Otherwise you have to go back to my post and execute the first steps to declare the environment variables and compile and load the lists dll.

In its most simple form, you can retrieve all list items of a certain list:

$result = $listservice.GetListItems("Customers", $null, $null, $null, $null, $null, $null)

$result is an xml node containing the following:

image

It's the data element that contains the list items.

If you execute something like the following, you will get the last name of each customer in the result set:

$result.data.row | foreach ($_.ows_Title)

image

When working with the Lists.asmx SharePoint web service, all fields are prefixed with ows_.

If you want to retrieve a subset of list items you have to pass a CAML query to the GetListItems method. For example, if you want to retrieve all customers living in the city Bendigo, you have to create following CAML query:

<Query><Where><Eq><FieldRef Name='WorkCity' />

<Value Type='Text'>Bendigo</Value></Eq></Where></Query>

You execute the GetListItems method as follows:

$query = "<Query><Where><Eq><FieldRef Name='WorkCity' /><Value Type='Text'>Bendigo</Value></Eq></Where></Query>"

$result = $listservice.getlistitems("Customers", $null, $query, $null, $null, $null, $null)

image

You can always build your more complex queries with the U2U Caml Query Builder which exists in windows version (download) and feature version (download). Consult my blog or the U2U web site for more detailed information about building CAML queries with the tools. 

Another way to limit the number of rows returned is specifying a row limit, with or without a query:

$result = $listservice.getlistitems("Customers", $null, $query, $null, 3, $null, $null)

If you want to view the complete content of each row, you can execute the following:

image

You can also limit the number of columns returned in the result set by specifying a ViewFields node. Lets only retrieve the Title and Email for customers living in Bendigo:

[xml]$viewfields = "<ViewFields><FieldRef  Name='Title' /><FieldRef Name='EMail' /></ViewFields>

$result = $listservice.getlistitems("Customers", $null, $query, $viewfields, $null, $null, $null)

As you view the result you will notice that indeed the Title and the Email field are returned but also another bunch of fields. These are the system fields and will always be returned, even if you use the IncludeMandatoryColumns element of the QueryOptions (because this only works for custom fields defined as required). For completeness, you define QueryOptions as follows:

[xml]$queryoptions = "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns></QueryOptions>"

$result = $listservice.getlistitems("Customers", $null, $query, $viewfields, $null, $queryoptions, $null)

You can read more about the GetListItems method on the msdn site.

If you need extra information about this method or about other method on other SharePoint web services, you can leave me a comment.

Nick, now you owe me a beer!

Iterating through the columns of a list with Powershell and the SharePoint Lists.asmx web service

Yesterday I got a question on how to iterate through the columns of a list by using Powershell and the SharePoint Lists.asmx web service.

If you read previous post and saved the necessary environment variable declarations in your profile, the only thing you should do to start is:

$listservice = New-Object Lists

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

Otherwise you have to go back to my last post and execute the first steps to declare the environment variables and compile and load the lists dll.

You can get access to the list by executing the GetList method on the Lists.amx web service. The required argument is the name of the list:

$list = $listservice.GetList("Employees")

You can view the title of the list:

$list.Title

Or the Guid:

$list.ID

image

You can get access to the fields (or columns) defined on your list by storing the field collection into a variable:

$fieldsnode = $listservice.GetList("Employees").Fields

But the return value of this Fields collection is an xml node. You can view the content of the field collection by executing the $fieldsnode.get_OuterXml() method but this returns you more than a page full of xml. But Powershell is smart enough to be able to handle the child nodes as objects. You can  view the different fields by executing f.e. the $fieldsnode.get_ChildNodes().

And now we come to iterating through the field collection. A field exposes properties like Name (which is the InternalName when working with the SharePoint object model), the ID, the DisplayName, Type and a lot of other properties. You can iterate through the field collection and retrieve the internal name as follows:

$fieldsnode.get_ChildNodes() | foreach-object { $_.Name }

image

 

Nick this one is for you! Thanks for reading my blog.

Update a SharePoint List remotely with PowerShell

Yesterday I got a comment on my blog post Update a SharePoint List with PowerShell asking if it is possible to remotely update a SharePoint list. This means that you have to execute the UpdateListItem method of the Lists.asmx web service of SharePoint.

It is possible to work with the SharePoint web services from within SharePoint. There are already some good posts around:

- Calling a Web Service from PowerShell which explains the steps to take before you can consume a Web Service

- Consuming SharePoint Web Services from PowerShell which explains how to get a list from the Lists Web Service.

In this post I'll explain the steps how to execute the UpdateListItem method.

First load the Visual Studio tools into your Powershell environment:

$env:VSINSTALLDIR="C:\Program Files\Microsoft Visual Studio 8"

$env:VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 8\VC"

$env:DevEnvDir="$env:VSINSTALLDIR\Common7\IDE"

$env:FrameworkSDKDir="$env:VSINSTALLDIR\SDK\v2.0"

$FrameworkPath=$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())

$env:FrameworkDir=$(split-path $FrameworkPath -Parent)

$env:FrameworkVersion=$(split-path $FrameworkPath -Leaf)

$env:PATH="$env:VSINSTALLDIR\Common7\IDE;$env:VCINSTALLDIR\BIN;$env:VSINSTALLDIR\Common7\Tools;$env:VSINSTALLDIR\Common7\Tools\bin;$env:VCINSTALLDIR\PlatformSDK\bin; $env:FrameworkSDKDir\bin;$env:FrameworkDir\$env:FrameworkVersion;$env:VCINSTALLDIR\VCPackages;$env:PATH"

$env:INCLUDE="$env:VCINSTALLDIR\ATLMFC\INCLUDE; $env:VCINSTALLDIR\INCLUDE;$env:VCINSTALLDIR\PlatformSDK\include;$env:FrameworkSDKDir\include;$env:INCLUDE"

$env:LIB="$env:VCINSTALLDIR\ATLMFC\LIB; $env:VCINSTALLDIR\LIB;$env:VCINSTALLDIR\PlatformSDK\lib;$env:FrameworkSDKDir\lib;$env:LIB"

$env:LIBPATH="$FrameworkPath; $env:VCINSTALLDIR\ATLMFC\LIB"

As explained in other posts, you can put this in your profile so that these tools are loaded each time you run Powershell.

Then execute the following commands to compile the Lists web service:

PS>wsdl http://[site url]/_vti_bin/Lists.asmx

PS>csc /t:library Lists.cs

PS>[Reflection.Assembly]::LoadFrom("Lists.dll")

Once this is done you can place the following statement in your profile so that it is executed each time you run Powershell:

[void][Reflection.Assembly]::LoadFrom("Lists.dll")

Instantiate the lists web service:

PS> $listservice = New-Object Lists

You have to be authenticated to contact the web service:

$listservice.Credentials=[System.Net.CredentialCache]::DefaultCredentials

My example uses a computers list:

powershell updatelistitems before

There is a mistake in the title of the second item, which need to be corrected.

The method you need to use to update a list item is the UpdateListItems. This method asks for 2 arguments: the name of the list and a batch query. First a string is build with the CAML needed to update the list item and then the UpdateListItems method is executed:

PS>$query = "<Batch OnError='Continue'><Method ID='1' Cmd='Update'><Field Name='ID'>2</Field><Field Name='Title'>Laptop 2</Field></Method></Batch>"

PS>$listservice.UpdateListItems("Computers", $query)

In fact the second argument of the UpdateListItems method is an xml node but if the query string contains valid xml, it is implicitly converted into an xml node before it is passed to the UpdateListItems method. If you want to explicitly use an xml node you can write the following:

PS>[xml]$query = "<Batch OnError='Continue'><Method ID='1' Cmd='Update'><Field Name='ID'>2</Field><Field Name='Title'>Laptop 2</Field></Method></Batch>"

And here is the result of the udpate:

powershell updatelistitems after

For more information about working with xml nodes, i refer to the post of Dan Sullivan.

As you can see I can use CAML in a lot of different ways :)

SharePoint PowerShell for Beginners - continued

In my first post on PowerShell for SharePoint developers I described how you could use the SPSite and SPWeb object to get information on its object model. In this post I will explain a few methods and properties of SPList.

Perhaps some of you know the featue I wrote last summer to view all properties of a SharePoint list. One of the things that you could inspect with this feature is the fields that are defined on the list. It shows you its name, internal name, id and data type. For more information see my post on the List Properties feature.

Today I will show you how to get this information by using PowerShell.

To get to the list you want to investigate, you need to perform some preliminary tasks:

Load the SharePoint assembly:

[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”)

Open the SharePoint web:

$siteUrl = "your sharepoint site url"

$webName = "your webname"

$spSite = new-object Microsoft.SharePoint.SPSite($siteurl)

$spWeb = $spSite.OpenWeb($webName)

Instantiate the SharePoint list: 

$listName = "your listname"

$spList = $spWeb.Lists[$listName]

The fields of a list are defined in its Fields collection property. You could execute the following but it will return you a long list of all fields with all of its properties.

$spList.Fields

View column properties of a SharePoint list

So if your interested in only a few properties you could first inspect the metadata of the field object. A field is of type SPField. As we are not able to create a new object of type SPField from a default constructor, we will get an instance of the first field of the list. To view the different properties defined on SPField, execute the following statement:

$spList.Fields[0] | gm -membertype property

Following screenshot shows you the result.

image

So, if you want to view a few properties like display name, internal name, id and data type of all fields on a list, use the following syntax:

$spList.Fields | ft Title, InteralName, Id, TypeAsString

This returns you the requested data in table format. If not all information like f.e. the Id is completely visible, you could customize the columns of the table or use the fl formatter, which stands for format-list.

Add a column to a SharePoint list

The second task is to add a column to a SharePoint list. We will create a field with name "Extra column" and of type string. First of all, you need to know which method you need to execute on the list object and what are the arguments you need to specify.

Execute $spList.Fields.Add to get an overview of the different overloads of the Add mehtod:

image

As you can see, there are 2 overloads to add a new item to a SharePoint list. The overload we are going to use is the one that needs a column name, a field type and the required boolean. Execute the following:

$spList.Fields.Add("Extra column", "Microsoft.SharePoint.SPFieldType.Text", 0)

This returns you the following error:

image

As you can see in the error message returned by PowerShell, we didn't specify a correct value for the field type. If you tak a good look at the error message you will notice that PowerShell returns all possible values for that argument in the error message!

Specify boolean values as 0 and 1. If you pass the string "false", it is accepted as "different from false" and your field will be added as a required field.

Following statement will add the column to the list:

$spList.Fields.Add("Extra column", "Text", 0)

In addition, PowerShell returns you the internal name of the column you just added, i.e. Extra_x0020_column

Return to Internet Explorer and browse to the Settings Page of your list. You will see that the column is added to the list:

image

You can add it to the default view as you want.

 

In a next post I will explain how you can write a function that adds a column to a SharePoint list. You will be able to use this function for adding columns to each different type of list.

Update a SharePoint List with PowerShell

Some time ago I wrote an introductary post on Powershell and SharePoint 2007. Based on that post I recently got a question on how to run a WMI query to determine the IP address of a server and place the result in an IP field of a custom SharePoint list.

WMI stands for Windows Management Instrumentation and is the management infrasturcture for the Windows operating system. It also has an object model that you can use within a .NET application, but also from within PowerShell. A good starting point for using WMI within Powershell is the following tutorial:

http://www.powershellpro.com/powershell-tutorial-introduction/powershell-tutorial-scripting/

To test my sample code of this blog post I created a custom list with name "Servers" and some additional fields like IPAddress and CPUSpeed. 

When opening the PowerShell command prompt, the first thing you have to do is load the SharePoint assembly:

[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”)

To get an instance of a certain SharePoint list, you could use Powershell code like the following: 

$siteUrl = "your sharepoint site url"

$webName = "your webname"

$spSite = new-object Microsoft.SharePoint.SPSite($siteurl)

$spWeb = $spSite.OpenWeb($webName)

$spList = $spWeb.Lists["Servers"]

For querying WMI with PowerShell you use the get-wmiobject method. To get information about the computer processor you need to query the WMI namespace Win32_Processor. This namespace returns information about architecture, availability, name, cpu status, processor speed, devices, manufactures, etc.

$computername = "your computer name"

$processor = get-wmiobject Win32_Processor -computername $computername

To get information about the IP Adress you need to query the WMI namespace Win32_NetworkAdapterConfiguration. This namespace returns information about DHCP, the IP Address, DNS domain and service name of the queried server. 

$configs = get-wmiobject Win32_NetworkAdapterConfiguration -computername $computername

As for the calculation of the CPU speed, you can use the CurrentClockSpeed or the MaxClockSpeed property of the processor instance. As the data type of these properties are both unsigned integers, it will need some formatting before storing it in the SharePoint list:

"{0:0.##}" -f ($processor.MaxClockSpeed/1000) + " GHz"

As the CPU speed is also part of the processor name, you can also strip it out from the $processor.Name string.

Adding a new item to a SharePoint list using PowerShell is not so different from using the SharePoint object model from within a .NET application:

$spitem = $spList.Items.Add()

$spitem["Title"] = $config.HostName

$spitem["IPAddress"] = $config.IPAddress

$spitem["CPUSpeed"] = $cpuspeed

$spitem.Update()

When using the above syntax, pay attention that you use the internal name of the field. F.e. if you see in the SharePoint list view a column with title "CPU Speed", chances are great that the internal name of this field is "CPU_x0020_Speed".

Now putting it all together, the sample code looks like the following. You can place it within a foreach loop to loop through a list of all servers.

$siteUrl = "http://yoursharepointsite"

$webName = "yourweb" 

$spSite = new-object Microsoft.SharePoint.SPSite($siteurl)

$spWeb = $spSite.OpenWeb($webName)

$listName = "your list name"

$spList = $spWeb.Lists[$listName]

$computername = "yourcomputername"

$processor = get-wmiobject Win32_Processor -computername $computername

$configs = get-wmiobject Win32_NetworkAdapterConfiguration -computername $computername

foreach ($config in $configs)

{

   $spitem = $spList.Items.Add()

   $spitem["Title"] = $config.ServiceName

   $ipaddress = $config.IPAddress | out-string

   $spitem["IPAddress"] = $config.IPAddress + "" 

   $spitem["CPUSpeed"] = "{0:0.##}" -f ($processor.MaxClockSpeed/1000) + " GHz"

   $spitem.Update()

}

 This is a screenshot of my test list after execution of previous code:

image

I hope this example is helpful. In case of questions, don't hesitate to post a comment.

SharePoint PowerShell for Beginners

This is a first post of a series on how you can use PowerShell on the SharePoint object model and its web services. This post will give you an introduction on how to work with the SPSite and SPWeb objects.

Open a PowerShell command prompt. As we are going to explore the SharePoint object model, you need to have PowerShell installed on a machine where you installed SharePoint.

The first step is to load the SharePoint assembly:

[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”)

Instantiate an SPSite object:

$siteurl = "http://boske.litwareinc.com"

$mysite=new-object Microsoft.SharePoint.SPSite($siteurl)

Now you have a variable mysite, which contains an instance of type SPSite:

You can explore the content of the mysite variable by executing following command:

$mysite

Or to have the information listed per page:

$mysite | more 

To list all the members of the site object:

$mysite | get-member | more 

or the shorter notation:

$mysite | gm | more 

You can also list only the properties of the site object:

$mysite | gm -membertype property | more 

To view the content of a property of the site object:

$mysite.AllWebs

But this shows the whole content of all webs in the site collection. If you want to see only a few properties of each web, you could execute the following:

$mysite.AllWebs | format-table Url, ID, Name, AllUsers

or the shorter version

$mysite.AllWebs | ft Url, ID, Name, AllUsers

To get the webs ordered by the last time that the contents have been changed:

$mysite.AllWebs | sort LastItemModifiedDate | ft Url, ID, Name, LastItemModifiedDate  

To loop through all webs of the site object and show the web Url and the Title of each list:

$mysite.AllWebs | foreach { $_.Lists | ft $_.Url, Title}

You should see something similar like this:

You can also execute a methods of objects. Just for fun, I will show you how to execute a CAML query:

$mytestweb = $mysite.OpenWeb("testsite")

$listguid = new-object System.Guid("f0715075-5159-43d7-99b7-3897824fbbff")

$productlist = $mytestweb.Lists[$listguid]

$query = new-object Microsoft.SharePoint.SPQuery();

$query.Query = "<Where><BeginsWith><FieldRef Name='ProductModel' /><Value Type='Text'>Mountain</Value></BeginsWith></Where><OrderBy><FieldRef Name='ProductModel' /></OrderBy>"

$productlist.GetItems($query) | ft Name

You can also view all static members of the SPSite class:

[Microsoft.SharePoint.SPSite] | get-member -static 

If you want to execute a static member:

[Microsoft.SharePoint.SPSite]::MaxWebNameLength 

I hope you liked the introduction on how to use PowerShell in combination with the SharePoint object model.