Skip to content

Powershell commands with Claims Authentication

December 19, 2011

The new Claims Authentication model is very powerful and allows many more ways to authenticate into SharePoint web applications.

With every new power comes new complexity, and the one that comes with Claims Authentication will cause new and exciting ways for scripts, which were working just fine, to fail in the new environment.  Luckily, “There is a command for that” (should be PowerShell new mojo line..)

Specifically, commands that previouly (using good old NTLM) worked just fine when fed a user ID, now need a little TLC.  To help myself I created the following snippet:

$m = [Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager]::Local
Add-PSSnapin Microsoft.SharePoint.PowerShell -ea silentlycontinue 
Function Get-SPClaim {
    param ([string]$user)
    $claim = New-SPClaimsPrincipal -identity $user -IdentityType "WindowsSamAccountName"
    return $m.EncodeClaim($claim)
}

The function above accepts a Windows user account name (like usa\annoying.user) creates a claim token for it using the New-SPClaimsPrincipal commandlet and returns the encoded claim (i:o#.w|usa\annoying.user, for example).

with the returned encoded claim you can now run a whole host of SharePoint PowerShell command that will not execute correctly otherwise.  Here is one for creating default groups after running New-SPSite (a new site collection created manually will do this automatically, but not the PowerShell command .  I’m sure there is a good explanation for this [not]..)

$spWeb = Get-SPWeb -identity $url
$owner = get-SPClaim("usa\Ive.gotthepower)
$admin = get-SPClaim("usa\me2")
$spWeb.CreateDefaultAssociatedGroups($owner,$admin, "Power Rangers”)
$spWeb.Update()
Advertisements
9 Comments
  1. Shaggydog permalink

    Hi, thank you, this seems pretty close to what I need to achieve.
    We have a bunch of scripts that upload and download documents to and from a SharePoint site, (as mere users, not administrators) We used the following code:

    $Credentials = Get-Credential

    ​….

    Download-File -Url $fileUrl -Destination $Destination -Credentials $Credentials

    Get-Credentials would cause a username/password dialog to pop up, and that was enough to get authenticated.
    But the provider of the site switched to Claims authentication, and now our authentication is failing. I see that you create a claim, but I’m not sure how to use this in my script. Where does the password come into it? How do I cause the dialog to be displayed? How do I use the resulting claim to authenticate me on the site?

    Thanks in advance.

    • bernoulli permalink

      The short answer is that you should be able to use the same technique.
      a “claim” is a way to separate the authentication token from the system that produced it. EncodeClaim function (bad name. Should be called EncodeClaimToken,) converts a login name to a token, and is used in places that require a string with a user name.
      The Get-Credential cmdlet behaves the same way under Claims Auth. SharePoint calls the claim provider (c2wts in the case of NTLM claims) to authenticate and issue a claim. SharePoint uses the claim to authorize the logged in user in the site.
      If users are no longer able to get the right permissions after the change to Claims Authentication then you need verify that their records were correctly migrated (MigrateUsers, move-SPUser, etc.)
      Hope that’s helpful.

      • Shaggydog permalink

        Hi, thanks for your answer. Unfortunately, this doesn’t help me at all. We might be a SharePoint dev team, but as far as this server is concerned, we are mere users. The servers are maintained by another part of the company on another continent, it was them who changed the authentication method. They have also demonstrated a “talk to the hand” approach to our requests.
        My credentials seem to work properly, when I go trough the web interface (as was intended) they work without any problems.

      • bernoulli permalink

        Get-Credential method returns a PSCredential object. Since you are passing it to your Download-file function, I assume that somewhere in that function you pass it along to a SharePoint function, which would have to convert it to a NetworkCredential object for authentication.
        You can do that explicitly and then modify the user name:
        $netcreds = $credentials.GetNetworkCredentials()
        $netcreds.UserName = Get-SPClaim -user $netCreds.UserName

        Download-File … -Credentials $netCreds

        Or, if you must convert back to PSCredentials
        $cred = new-object -typename System.Management.Automation.PSCredential `
        -argumentlist (Get-SPClaim -user $Credentials.UserName), $Crendentials.Password

      • Shaggydog permalink

        That’s one of the first things I tried. However, I’ve figured out the problem, and it has little to do with Claims, and everything to do with how authentication is implemented now. I used Fiddler to track the communication that occurs when I use the browser, and it goes something like this:
        When I make a request for a file on the sharepoint server, this is what happens:
        1. I get redirected to websso.mycompany.com/somethingsomething, where I am provided with a combo box that lets me select which part of my behemoth corporation I hail from. When I click submit,
        2. I get redirected to a page with a username and password input field. I can skip step 1, if (and only if) I replicate the request step 1 results in, down to every header parameter and weird hash codes in the request body. Sending a request with my user name and password will result in the server responding with a cookie that contains some security information.
        3. I take the data from the cookie, and make a request to mycompany.com/_trust/
        4. _trust/ sends back another cookie with another security token, which I can finally use to make a request for the file (I hope)

        Right now I’m working on mocking this in powershell. If you’re interested, I’ll let you know how it went.

      • bernoulli permalink

        You are describing a typical claims scenario for Forms-based authentication. For NTLM or ADFS the login screen is no necessary.
        I have written a C# applications that accomplish a task similar to what you are trying to do.
        You may want to explore SecureStore service to provide similar functionality without a need for each user to type their credentials into your application..

        Good luck,

        Shahar

      • shaggydog permalink

        Hi, sorry for the late reply, I was kinda swamped. I have learned that what I was facing was the typical claims authentication handshake, but only after I had implemented it as a low-level solution – actually crafting the postdata in Powershell and sending the requests to the appropriate url’s, then parsing the response. I’ve learned a lot from this experience, but I’m still wondering why just about every blog and how-to I read on the topic stated that “my code should work exactly as it did before, no change required”, when obviously I had to do all the request-response-cookie tango.
        To reply to your latest comment, I’m not yet familiar with NTLM or ADFS, I’ll read up on them when I have time. But since you suggest I could get by without the login screen, I’ll assume you want me to get the system to use the users’ Windows credentials to log in to the site? Because the users’ Windows credentials are completely independent from the ones they use to login to the SharePoint site.
        In any case, I was able to finish my task, I can now download from the site. I even managed to make uploads work using the SharePoint Client Object Model. Good thing I mined the raw cookie, cause all I had to do was just slap it onto the SharePoint context.
        I do have, however, another problem: uploading files through SharePoint Client Object Model fails for files larger than 3MB. I’ve been looking into ways of getting around this. One of the things that could provide a solution are web services. But how would I authenticate a web service using Claims? What do I stick the cookie onto?
        If you could shed some light on this, it would be much appreciated.

      • bernoulli permalink

        That’s a whole different post that I hope to get to very soon

  2. shaggydog permalink

    I’ve actually managed to upload big files by sticking the cookie on a PUT web request and executing it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: