Hey, Scripting Guy! Tell Me About SharePoint Remoting with Windows PowerShell 2.0 and WinRM

Hey, Scripting Guy! Tell Me About SharePoint Remoting with Windows PowerShell 2.0 and WinRM

  • Comments 6
  • Likes

Bookmark and Share

(Note: Today's Hey, Scripting Guy! Blog post was written by guest scripter, Tome Tanasovski. Tome is a manager of a team of server engineers in New York City. He is a Microsoft Certified Trainer who specializes in SQL Server, SharePoint, and VMWare. He is a contributor to the Windows PowerShell forum and the Hey, Scripting Guy! forum. Tome is a part-time blogger, and is currently organizing the inaugural meeting of a Windows PowerShell User Group in New York City. Thanks, Tome!)

----------

Frustration. Dictionary.com’s fourth definition is “a feeling of dissatisfaction, often accompanied by anxiety or depression, resulting from unfulfilled needs or unresolved problems.”

I think that sums up my early experiences working with the Microsoft Office SharePoint object model interfaces. When Microsoft Office SharePoint Server (MOSS) 2007 was released, I was eager to play. The new workflow engine, cooler searching, and a more flexible structure sounded like perfect new toys. I dove headfirst into lists and automation, but eventually found that I wanted to do some very simple things such as consume the data from my workstation using my own code. I quickly learned what everyone learns when they try to do this: It doesn’t work that way.

In order to use the SharePoint object model, you must run your code on the SharePoint Web interface that is hosting the site you want to access. Thinking that this was completely useless for my needs, I started looking into how to use the Web services to get to the data. Attempting to do this with Windows PowerShell proved to be not only difficult, but also tedious and ineffective for what I wanted. Frustrationdissatisfaction accompanied by depression resulting from unfulfilled needs. Sigh.

Then along came Windows PowerShell 2.0 and WinRM.


Elation
. Dictionary.com’s only definition: “a feeling or state of great joy or pride; exultant gladness, high spirits.”

Unfortunately, it wasn’t all immediate elation, but I knew it was within my reach. The concept is simple: Using Windows PowerShell remoting, I should be able to use the Office SharePoint object model interfaces from any computer. After installing Windows PowerShell 2.0 with WinRM on the SharePoint server and connecting to a remote session, I found that I could indeed load the Microsoft.SharePoint namespace. However, I would soon find that the same problem existed when trying to use the class remotely.

The end result of my tinkering was to find that you could make this work using CredSSP authentication. The one pitfall here is that CredSSP does not work on Windows Server 2003. Here are the steps required to get Windows PowerShell remoting to work between my Windows 7 workstation and a Windows Server 2008 workstation running Microsoft Office SharePoint Services 2007.

1.     Install Windows PowerShell 2.0 with WinRM on the SharePoint server.

2.     Enable Remoting on the SharePoint server:

a.  Enable-PSRemoting

3.     Enable CredSSP on the server:

a.  Enable-WSManCredSSP -Role server

4.     Enable CredSSp on the client:

a.  Enable-WSManCredSSP -Role client -DelegateComputer server1

5.     On the client, you also need to configure your policy by running gpedit.msc and enabling “Allow Delegating Fresh Credentials” located in the Credentials Delegation folder:

a.       Image of Credentials Delegation folder

6.     You will need to add WSMAN/server.fqdn to the list or use a wildcard character as follows:

b.      Image of adding WSMAN/server.fqdn with use of wildcard character

After you have completed the above steps, you can begin to explore the very elegant world of the SharePoint object model from your workstation using the -Authentication CredSSP parameter in Invoke-Command. Let’s look at how easy it is to access data from a calendar and export it to a CSV file on a network share:

$script = {

    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Sharepoint")

    $site = New-Object Microsoft.SharePoint.SPSite("http://server1")

    $web = $site.OpenWeb("")

    $list = $web.Lists["Calendar"]

 

    $exportlist = @()

    $list.Items |foreach {

        $obj = New-Object PSObject -Property @{

            Title = $_["Title"]

            StartTime = $_["Start Time"]

            Location = $_["Location"]

        }

        $exportlist += $obj   

    }

    $exportlist |Export-Csv -path '\\tome-pc\share$\Calendar.csv'

}

Invoke-Command -ComputerName server1 -scriptblock $script -Authentication Credssp

 

Let’s create a new Web site:

 

$script = {

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

    $site = New-Object Microsoft.SharePoint.SPSite("http://server1")

    $web = $site.OpenWeb("")

    $web.Webs.Add("NewSite", "NewSite", "NewSite Desc",[Convert]::ToUInt32(1033), $web.WebTemplate, $false, $false)

}

Invoke-Command -ComputerName server1 -scriptblock $script -Authentication Credssp

 

And let’s do some folder and file manipulation. In this script we browse to the Shared Documents folder, create an archive folder, and then copy all of the contents into it:

 

$script = {

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

    $site = New-Object Microsoft.SharePoint.SPSite("http://server1")

    $web = $site.OpenWeb("")

    $folder = $web.GetFolder("Shared Documents")

    $folder.SubFolders.Add("Archive")

    $folder.Files|foreach {

        $_.CopyTo(("Shared Documents/Archive/" + $_.Name))

    }

}

Invoke-Command -ComputerName server1 -scriptblock $script -Authentication CredSSP

 


Of course you are not limited to using script blocks. All of the remoting methods are available to you. You can create the script locally and use the -FilePath parameter of Invoke-Command to execute the script:

 

Invoke-Command -ComputerName -FilePath .\script.ps1 -Authentication CredSSP

 


Or you can enter a session and interact with the objects directly with Enter-PSSession using the -Authentication CredSSP parameter:

 

Enter-PSSession server1 -Authentication CredSSP

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

$site = New-Object Microsoft.SharePoint.SPSite("http://server1")

$site|Get-Member

 

 

With the SharePoint object model at your remoting fingertips, you finally have the flexibility to do things with SharePointfrustration free. Happy remoting!

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • PowerShell 2.0 way to load an assembly:

    Add-Type -AssemblyName Microsoft.SharePoint

  • Hi i am using above commands to connect to Web Front end having Sharepoint Server 2007 and Windows Server 2008 but i am getting the error unable to connect to server ...server name is not correct..but the servername is correct..

  • Are we running above commands on Client or Sharepoint Server.

  • Steps 2 and 3 are on the server

    4,5,6 are on the client you are connecting from

    The scripts are run from the client.  You can test the script line-by-line interactively by using:

    Enter-PSsession -computername [servername] -Authentication CredSSP

    Once you are in the session, you can run each command within $script one at a time.  It's also worth noting that Sharepoint 2010 has introduced a whole slew of cmdlets that wrap a lot of what I am doing in the $script.  At the time this article was written those cmdlets were just rumors and whispers.  The technique for configuring remoting to use the new cmdlets, however, is still valid and necessary even with the new Sharepoint cmdlets.

  • Hi,

    I have used powershell script to copy(runtime) library contents across webapplications in the same farm.

    Can i used the concept of remoting to copy(runtime) the library contents across webapplications in different farms?

    Your inputs in this regard would be most appreciated.

    Regards,

    Tony

  • Ed/Tome-
    Great article! Not being familiar enough with how remoting cmdlets like Enter-PSSession or Invoke-Command handle the TLS Handshake, I've seen blogs stating that you're limited to Invoke-Command "because (Enter-PSSession) CredSSP can't use cached credentials". I don't see anything that supports this claim and haven't been able to test it myself as the client I'm remoting from is experiencing general issues with double-hop to our PROD SharePoint environment. Both remoting cmdlets obviously work in our DEV SharePoint environment where double-hop authentication isn't a factor (single-server install).
    Interested to hear your experience and any other issues (such as security risks) to consider when executing remote commands against SharePoint.