SharePoint 2013 Design Packages: Export with PowerShell (Part 1 of 2)

Last night I search for “export import sharepoint 2013 design packages powershell”. No luck there. – So I created two functions for this purpose. It works nicely 🙂

The functions only use public methods of the SharePoint (Server) Object Model. No reflection, et cetera. The most important class in this context is “Microsoft.SharePoint.Publishing.DesignPackage”. It has two methods: Export and Install. This I used to create to PowerShell functions: Export-SPDesignPackage and Import-SPDesignPackage. Both are able to work in PowerShell pipeline context. This gives you the possibility to export a bunch of Design Packages from several sites using PowerShell.

You can download the scripts here:

http://gallery.technet.microsoft.com/Export-and-Import-0f41b376

You can use the scripts as PowerShell modules or by copying the content to your own PowerShell script files. But please be careful: By now it’s only tested in my dev environment!!

The scripts use the SharePoint Server Object Model. So they have to be executed on a SharePoint farm server! You also need an priviledged account that has rights to export (or import) SharePoint Design Packages.

Today I’ll describe the export function. Tomorrow or the day after tomorrow I’ll publish a description of the import function. Here is the import part: https://blog.kenaro.com/2013/02/18/sharepoint-2013-design-packages-import-with-powershell-part-2-of-2/

Export-SPDesignPackage

Here are some samples:

$site1=get-spsite"http://sharepoint.local/publishing" 
$site2=get-spsite"http://sharepoint.local/sites/publishing2"

 

#First Sample

 

$cred=new-objectSystem.Management.Automation.PSCredential( "domain\spfarm", (ConvertTo-SecureString-AsPlainText"Passw0rd"-Force))

$site1, $site2 | Export-SPDesignPackage -UseTempFileForExportWithExtension ".wsp" -DownloadCredentials $cred -PackageName "test"#Second Sample

 

$site1, $site2 | Export-SPDesignPackage -ExportFileName "C:\temp\Package.wsp" -UseExportFileNumbering -IncludeSearchConfig -DisposeSiteObject -OverwriteExistingFiles

#Third Sample

 

(
    @{PackageName="P1"; ExportFileName="C:\temp\p1.wsp"; SiteUrl="http://sharepoint.local/publishing"},
    @{PackageName="P2"; ExportFileName="C:\temp\p2.wsp"; SiteUrl="http://sharepoint.local/sites/publishing2"}
) | New-ObjectFromHashtable | Export-SPDesignPackage

 

#Fourth Sample

 

$site2 | Export-SPDesignPackage -ExportFileName "C:\temp\publishing2.wsp"  -IncludeSearchConfig -DisposeSiteObject -OverwriteExistingFiles

The first sample uses two SPSite objects as (pipeline) input and tells the function to export the design packages to temp files with auto generated names. For the download of the packages from the sites you can specify “download credentials”.

The second sample exports the same two SPSites. The export file name is specified. By using “UseExportFileNumbering” a number is inserted into the file name like this: “c:\temp\package-1.wsp”. So both export packages have different file names.

The third sample exports two sites  with individual export settings for each site. This is possible by “parameter binding by property name” where PowerShell binds the input object’s property to the function / cmdlet input parameters by name matching. But this does not work with hashtables. Therefore I created a helper function “New-ObjectFromHashtable” that creates a PowerShell object (“PSObject”). This function is generic. (It’s also included in the script files.)

The fourth sample exports just one site.

Parameters

The function has the following parameters. All can be bound by “parameter binding by property name”!

Parameter Name Parameter Set Name Mandatory? Position Description
SiteUrl Default Yes 0 Url of Site Collection as System.String
Site Site Yes 0 SPSite-object
ExportFileName Default

Site

No 1 Name for the exported file in the file system. The folder must exist!

Cannot be used together with “ExportFolder” and “UseTempFileForExportWithExtension”!

ExportFolder Default

Site

No 1 Name of the folder for the exported design packages. The file name will be created through the SharePoint Server Object Model.

Cannot be used together with “ExportFileName” and “UseTempFileForExportWithExtension”!

UseTempFileForExportWithExtension Default

Site

No 1 When specified the function will create a file name automatically by using "System.IO.Path.GetTempFileName()”. But it adds the extension you specify here. You should use “.wsp” by default.
PackageName Default

Site

No 2 Name of the export package. This is not a file name but an internal name that is used inside the design package. This is optional. The Object Model can handle it for you.
IncludeSearchConfig Default

Site

No 3 http://msdn.microsoft.com/en-us/library/jj862342.aspx
DisposeSiteObject Site No If you use SPSite objects as input you can specify whether the function should dispose it or not. Default: TRUE = “Please dispose it for me”!
DownloadCredentials Default

Site

No You can specify credentials for the download of the generated package. The package is stored in the the solution gallery of the site collection. It’s downloaded by the function by using System.Net.WebClient with “DefaultNetworkCredentials” if no credentials are specified.
OverwriteExistingFiles Default

Site

No If specified it overwrites the export file if it exists. If not specified it skips the export. But in the case nevertheless the design package will be created .
UseExportFileNumbering Default

Site

No If you use “ExportFileName” you can specify this parameter to insert numbers into the given file name as described above.

 

The function returns an object for each processed (or not processed) site collection:

image

This objects can be used in pipelines or … as you like.

Object Property Description
Site Url Url of the processed site
Success TRUE = Export successful, export file created.
SiteFound The site collection was found
ExportError $null = OK

System.Exception = Error occurred

PackageFileName Name of the Package created by the Object Model
PackageName Name of the Package created by you OR the Object Model
PackageMajorVersion …created by Object Model during export
PackageMinorVersion …created by Object Model during export
ExportFileOverridden If “TRUE” the export file did exist but was overridden during export. If “OverwriteExistingFiles” parameter was NOT specified this property will always be FALSE.
DownloadError $null = OK

System.Exception = Error during download

 

Some Additions

The design package will be stored in the solution gallery of the site collection that can be found here: <site-collection-url>/_catalogs/solutions. It’s the same location as for the sandboxed solutions. It interesting: sandboxed solutions are deprecated but in this case they use at least the same storage for a new functionality.

After the package is created you can download it from the solution gallery. No big deal.

Gimmick: Write To SharePoint Log using PowerShell functions

In preparation for a deployment project I wrote some PowerShell functions to write messages to the SharePoint ULS.

You can download the PowerShell script here: http://gallery.technet.microsoft.com/Write-Messages-to-b59565bf

There are some samples in the package.

image

This is what it looks like in ULSViewer:

image

Red = Area or “Product” in ULSViewer

Green = Category

Blue = Severity Level

Purple = Message

 

You can use the script file “SPLogging.ps1” as PowerShell module. In the following sample the SPLogging.ps1 file is stored in the same location as “SPLoggingDemo.ps1”. Or you copy the content of “SPLogging.ps1” to your own file.

Import-Module "$(split-path $MyInvocation.MyCommand.Path)\SPLogging.ps1"

Here are some samples about how to create “Areas”

 

Add-SPDiagnostigLoggingArea -AreaName "TestArea"

"PowerShell", "PS1", "PS2" | Add-SPDiagnostigLoggingArea 

This is how you create categories:

Add-SPDiagnostigLoggingAreaCategory -AreaName "TestArea" -CategoryName "Category1" -TraceSeverityDefault High

Add-SPDiagnostigLoggingAreaCategory "TestArea\Category2" -TraceSeverityDefault High

"Test1", "Test2", "Test3" | Add-SPDiagnostigLoggingAreaCategory -AreaName "PowerShell" 
"Test1", "Test2", "Test3" | Add-SPDiagnostigLoggingAreaCategory -AreaName "PS1" 

You can add new categories by specifiying the area and the new category name seperatly or as formatted string: <area><backslash><category>

The following snipped shows you how to query the areas and categories you created in your PowerShell session.

Get-SPDiagnosticLoggingCategory -CategoryName "PowerShell\Test1"

Get-SPDiagnosticLoggingCategory -AreaName "PowerShell"

Get-SPDiagnosticLoggingCategory 

You have only access to your own areas and categories!!

Finally here are some examples of how to write messages to the SharePoint ULS. You can use PowerShell pipelining!

Write-SPDiagnosticLogging -CategoryName "PowerShell\Test1" -Message "Hello 1!" 

"Hello 2!" | Write-SPDiagnosticLogging -CategoryName "PowerShell\Test1" 

"Hello 3!", "Current date/time: {0}" | Write-SPDiagnosticLogging -CategoryName "PowerShell\Test2" -MessageArguments @(([DateTime]::Now)) -TraceSeverity "High"

 

Writing to the Windows Event Log is not supported at this moment.

Create Provider Hosted High Trust App for SharePoint 2013 (Short Guide)

About this topic there are several guides. I can’t say that I have to add anything new 😉 But… as always… this blog is a kind of notebook for me. So I post this small guide.

1. You need to have or create a certificate that is used as “security token issuer”. This certificate can be created using IIS Manager or any other tool.

I use “XCA” (http://xca.sourceforge.net/). With that tool you can create your own Certification Authority. (Of course you can use the Windows Server Certification Authority.) – I use XCA because it’s easy to manage this kind of certificates there and I use the certificates on several dev machines.

If you do so too you need to create a root certificate for your Certification Authority and install it in the “Trusted Root Certification Authrities” of your Local Computer (not only your personal cert store).

image

2. The first step is to register (or create) the certificate within IIS Manager:

Right click on the server node and choose “Server Certificates”.

image

Use “Import” to apply an existing certificate. Or use “Create Self-Signed Certificate” to create a new certificate.

image

This are the steps to create a new self-signed certificate:

image

After commit (“OK”) you need to export the certificate with private key and a second time without private key.

image

image

image

image

image

image

image

image

3. Open Visual Studio 2012. Create a new project:

image

image

image

For “Issuer ID” you need to create a GUID using Visual Studio or PowerShell. Here is the PowerShell way:

Start PowerShell.

image

Enter:

[guid]::newguid().tostring().tolower()

image

Copy to output into the dialog in Visual Studio 2012.

image

4. Open a Windows PowerShell ISE, create a new PowerShell script file and copy the following code to it. Most of the code comes from here: http://msdn.microsoft.com/en-us/library/fp179901.aspx. With some additions from Steve Peschka’s Blog articles: http://blogs.technet.com/b/speschka/archive/2012/09/27/another-apps-for-sharepoint-tip-with-the-error-quot-the-issuer-of-the-token-is-not-a-trusted-issuer-quot.aspx and http://blogs.technet.com/b/speschka/archive/2012/11/01/more-troubleshooting-tips-for-high-trust-apps-on-sharepoint-2013.aspx.

###http://msdn.microsoft.com/en-us/library/fp179901.aspx

$publicCertPath = "C:\root\High_Trust_App_1.cer"

#$issuerId = [System.Guid]::NewGuid().ToString()
$issuerId = ([Guid]"4729b8e2-073a-47f0-8538-105ec865f3d2").ToString()

$spurl ="http://sharepoint.local"

$spweb = Get-SPWeb $spurl

$sc = Get-SPServiceContext $spweb.site

$realm = Get-SPAuthenticationRealm -ServiceContext $sc

$certificate = Get-PfxCertificate $publicCertPath

$fullIssuerIdentifier = $issuerId + '@' + $realm

New-SPTrustedSecurityTokenIssuer -Name $issuerId -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier –IsTrustBroker

iisreset

write-host "Full Issuer ID: " -nonewline
write-host $fullIssuerIdentifier -ForegroundColor Red
write-host "Issuer ID for web.config: " -nonewline
write-host $issuerId -ForegroundColor Red

#Disable OAuth HTTPS requirement FOR DEV!!

$serviceConfig = Get-SPSecurityTokenServiceConfig
$serviceConfig.AllowOAuthOverHttp = $true
$serviceConfig.Update()


New-SPTrustedRootAuthority -Name "$($certificate.Subject)_$($certificate.Thumbprint)" -Certificate $certificate 

Be sure to change any parameter that does not fit your environment. After that the script should look like this:

image

 

The following script lines are needed in order to get it working using a SharePoint site without SSL!!

$serviceConfig = Get-SPSecurityTokenServiceConfig

$serviceConfig.AllowOAuthOverHttp = $true

$serviceConfig.Update()

If you use SSL (e.g. https://sharepoint.local) you can skip this.

No other steps are required. I’ve tested this several times with always fresh SP 2013 environments because I had some difficulties to get this set up.

5. At this point I have not changed anything in Visual Studio after creating the project(s) (there are two) through the wizard.

Check the “web.config” file in you web project.

image

There you find the issuer ID again.

6. Now run the project. You need to trust the app.

image

image

image

Short Note About Error While Creating Search Service Application for SharePoint 2013 by PowerShell: “Value cannot be null. Parameter name: indexLocation”

Today I got an error while creating a Search Service Application for SharePoint 2013:

PS C:\> $SearchSA = New-SPEnterpriseSearchServiceApplication –Name “Enterprise Search Service Application” –ApplicationPool “Search App Pool” –DatabaseName “Search”

New-SPEnterpriseSearchServiceApplication : Value cannot be null.
Parameter name: indexLocation

To resolve this I just started the Search Service Instance on each (search) server in the farm and set it’s “DefaultIndexLocation” property.

After that I could create the Search Service App.

PS snippet:

"SearchServer1", "SearchServer2" | % {
    $svcInst = (Get-SPServer -Identity $_).serviceinstances | ? { $_.GetType().FullName -eq "Microsoft.Office.Server.Search.Administration.SearchServiceInstance" }
    $svcInst.DefaultIndexLocation = $defaultIndexLocation
    $svcInst.Update()
    $svcInst.Provision()
}

This did it.

How To: Use Git for small dev projects with “private” GIT repositories based on cloud storage providers such as SugarSync or DropBox

In some small dev projects in the last months I was looking for a source control system. I liked to use Microsoft’s Team Foundation Services. But I was and I am not able to use them with my current VS 2010. I cannot use the final version (http://tfs.visualstudio.com) because of a bug in (my?) Visual Studio. (Forum thread related to this problem: http://social.msdn.microsoft.com/Forums/en-US/TFService/thread/1b6673ec-8c42-4896-9049-49f17b85bf65)

Anyway…

So I wonder if I could use Git. – It’s a “[…] a distributed revision control and source code management (SCM) system with an emphasis on speed.” (Source: Wikipedia).

There is GitHub.com where you can host public visible projects for free. For “private” projects you have to pay (https://github.com/plans). The pricing is fair! But I was looking for a cost opportunity.

For cloud storage purpose I’m using this cloud storage providers:

(For data protection on cloud storage I use BoxCryptor.)

For this article I use SugarSync.

In my scenario I have some source code to share between me and other project members. We like to code together. And we need some source control features… With a cloud storage provider I can share local folders with other people… So now:

My aim is to create a cloud storage based source code repository for a small project and share the repository with other developers to work on the same project. My aim *is not* to describe the basics of and the need for source control in software development. (And I do not describe why to do all the steps 😉 )

This are the step to do so:

  1. Download and install Git for Windows: http://code.google.com/p/msysgit/downloads/list: “Full installer for official Git for Windows 1.8.0 Featured Beta”
  2. Download and install Git Extensions: http://code.google.com/p/gitextensions/downloads/list: “Git Extensions 2.43 Windows installer”. This are some very usefull “GUI” extensions for Git.
  3. Download and install Git Source Control Provider for Visual Studio (2012, 2010, 2008): http://visualstudiogallery.msdn.microsoft.com/63a7e40d-4d71-4fbb-a23b-d262124b8f4c
  4. Download and install – if you like – PowerShell extensions for Git: https://github.com/dahlbyk/posh-git
  5. Register for a cloud storage, e.g. SugarSync.
  6. Download and install the cloud storage software on your dev machine and log in.
  7. Open Visual Studio and create your project as normal. Or open an existing project. It’s the same procedure in both situations.

    image

  8. Right click on the project node or solution node in the Solution Explorer and click “Create Git Repository”

    image

  9. Right click on the project and “commit” the changes.

    image

    image

    image

  10. Open Git Shell (PowerShell or Bash), navigate to the project source folder.

    image

    Here you can see that to source folder is recognized as Git enabled folder.

  11. The next step is to create the connection to the repository that is shared between project members.
  12. Create a local folder for your Git repository and map the folder to your cloud storage.

    image

    image

  13. Create an empty folder inside the local repository folder. In this folder the project repository will be created.

    image

  14. Open Git Extensions and create a new repository:

    image

  15. Now you need to connect the local project folder with the repository.
    • git remote add origin “//localhost/c$/github/test project 1”

      image

  16. The next steps are to create a remote branch and to connect the local branch (“master”) with the remote branch
    • git push origin master:refs/heads/master

      image

    • git branch -u origin/master master

      image

  17. Now you can use “git push” to upload local changes to the repository and “git pull” to download changes from the repository to the local project folder.
  18. The final step is to share the cloud storage hosted folder with other project members:

    image

    image

That’s it for the publisher.

The next step is that an invited project member needs to sync the repository folder to it’s local drive and do the following steps:

  1. I simulate this by creating a new local project directory “c:\source\test project 1 other member”.

    image

  2. Then initialize the directory with “git init

    image

  3. Now you need to connect the local project folder with the repository.
    • git remote add origin “//localhost/c$/github/test project 1”

      image
    • git pull origin master:refs/heads/master 

      image

  4. The last step is to set the local branch to “track” the remote branch.

    image

That’s it, again. This are the basics about how to create a local project, a cloud hosted repository, how to share the repository and how to connect to it on a project members site.

SQL Server Alias management with PowerShell and WMI – Update for SQL Server 2012

In 02/2011 I created a PowerShell script to set / get / remove SQL Server aliases:

https://blog.kenaro.com/2011/02/09/enumerate-add-update-and-remove-sql-server-aliases-by-using-powershell/

Today I updated it for SQL Server 2012 and tested it on Windows Server 2012 and Windows Server 2008 R2.

You can download it here:

http://gallery.technet.microsoft.com/SQL-Server-2008-2012-Alias-baf05737

PowerShell Script to Migrate FBA Users from SharePoint 2007 to 2010 *Including FBA Roles*

This days I did some migration work. For experimental purpose I configures my old MOSS 2007 demo machine to use ASP.NET SQL FBA including MySites and profiles for the FBA users.

First I migrated the old Shared Service Provider config db as new User Profile Service App profile DB.

1.

Then I migrated the content databases of a demo web app and the dedicated mysites web app.

After that I configured FBA for both web apps.

The next step was to migrate the “old” user accounts to claims accounts.

Look at the content databases. This is how the “UserInfo” table look before migration:

image

On this point I need to ensure that the web application is already set up to use FBA. The role provider and membership provider names *must* be the same as in 2007!!!!!!!!!

Therefore I executed

$webApp.MigrateUsers($true)

on both web apps. ($webApp is an object that I retrieved by using cmdlet Get-SPWebApplication).

After that the content databases UserInfo table looks like this:

image

THERE IS A PROBLEM!!!! Look at this claim login for example:

image

According to Wictors description of the claim structure:

The SharePoint 2010 claim encoding format

http://www.wictorwilen.se/Media/Default/Windows-Live-Writer/How-Claims-encoding-works-in-SharePoint-_14813/image_10.png

… this is WRONG!!! “i:0#.f” indicates a user logon name. But “allfbausers” is a FBA role!

The “i:0#.f” must be translated to “c:-.f” which means:

c: . f
Other Claim is a role datatype is string claim is forms AuthN

 

It must be migrated manually by using this PowerShell script:

image

If you do not do this step your “old” FBA roles will not work as expected!!! This was my big issue the last days until I figured out that roles are translated to claims the same way as user identities… This was of course not correct.

After executing the script the content database looks like this:

 

image 

2.

The next step is to migrate the profiles in the User Profile Service App…

Before migration the UserProfile_Full table of the User Profile Service Apps “Profile” database looks like this:

image

Then I executed the “MigrateFormsLegacyUsersToFormsClaims” on the User Profile Service Application using PowerShell.

$upa = Get-SPServiceApplication | where-object {$_.Name -eq $upaName} 
$upa.MigrateFormsLegacyUsersToFormsClaims()
$upa.Upgrade()

$upaName contains the name of the existing User Profile Service App.

If you get an error in the ULS log like this:

image

Error messages:

  • Exception occured while connecting to WCF endpoint: System.ServiceModel.Security.SecurityAccessDeniedException: Access is denied.
  • UserProfileApplicationProxy.InitializePropertyCache: Microsoft.Office.Server.UserProfiles.UserProfileException: System.ServiceModel.Security.SecurityAccessDeniedException
  • Failure retrieving application ID for User Profile Application Proxy ‘User Profile Service Application Proxy’: System.NullReferenceException: Object reference not set to an instance of an object.
  • Failure retrieving application ID for User Profile Application Proxy ‘User Profile Service Application Proxy’: System.NullReferenceException: Object reference not set to an instance of an object.
  • MigrateFormsLegacyToFormsClaims.Migrate: User: AspnetSqlMembers:employee1, Failed to migrate to: i:0#.f|aspnetsqlmembers|employee1, Exception: System.ArgumentNullException: Value cannot be null. Parameter name: userProfileApplicationProxy

…you need to assign “Full Control” permissions to the User Profile Service App for the executing user!  Otherwise you are not able to convert the users!

After executing the script above the database looks like this:

image

3.

I’ve assembled all scripts for this article in one PowerShell script. You can download it here:

http://gallery.technet.microsoft.com/PowerShell-script-to-25b971ba

PowerShell Script to Add Account to “Allow Logon Locally” privilege on Local Security Policy

As you know the SharePoint Farm Account must have privileges to logon locally for getting “User Profile Service Application” to work.

Today I created a PowerShell script that adds the given account to the “Allog Logon Locally” privilege in the Local Security Policy.

1. My account is “DOMAINsp_farm”

2. I start “secpol.msc” (“Local Security Policy”) on the local farm server

image

3. I’m looking for “Allow Logon Locally”. The account “sp_farm” is not in this setting.

image

4. I execute the script to add the account.

image

5. Then I reload the “Local Security Policy” or close and reopen the MMC.

image

6. Now the account in in the setting:

image

You can download the script here:

http://gallery.technet.microsoft.com/PowerShell-script-to-add-b005e0f6

This is the script:

image

New Demo Project Released: SharePoint Web Change Log – An Alternate Notification Feature

I created an alternated notification feature for SharePoint 2010. It’s a demo project for SharePoint 2010. I’ve done it for some practice in SharePoint development and just for fun 🙂

It’s intended to replace the default notification feature of SharePoint 2010 where you can subscribe to notifications list based. – With my feature a user can subscribe to all changes of a SharePoint Web by using a menu entry in the Personal Actions menu.

The notification mail is send to any subscribing user once a day. (Please notice that at the moment there is no security trimming for the notification mail!)

Project site: http://spwebchangelog.codeplex.com

 

How it works:

1. There is a web scoped feature and a farm scoped feature.

2. The web scoped feature is responsible for the Personal Actions menu entry and the change log at web scope.

image

3. The farm scoped feature deploys a timer job that scans each web every day and sends the notification mail if there are any changes in the web.

image

4. The job can be scheduled as you like.

5. On each web where the web scoped feature is active, there are two hidden lists:

image

This list contains an list item for each user that has subscribed for notifications. If a users unsubscribes the list item is removed.

image

6. If the web feature is active the “Change Log” list will contain a list item for each change in other lists of the web.

A list event receiver recognizes each list level change: Created lists, deleted lists.  It adds list item event receivers to each list in the web.

A list item event receiver creates items in the “Change Log” list for each list item action: add, update, delete.

7. If the web scoped feature is deactivated the list event receiver and all list item event receivers are removed. If the feature gets activated the list event receiver and a list item event receiver for each existing list are registered.

8. The farm scoped feature deploys a timer job that scans each web of a specific web application. If the web feature is active in a web the timer job looks for the change log list and for subscribers. If there are at least one subscriber and at least one one change since the last job run the notification mail is send.

image

9. It’s localized for german and english. The notification mail text is part of a resource file. But the resource file value for the mail text can be replaced by using a Web Property.

image

10. The notification mail is not security trimmed! That’s important for use in a production environment!

11. It’s tested in both a german and an english SharePoint system with both language packs, with multiple site collections and multiple webs and sub webs. I’d like to hear your experiences. Please report any bug. Feel free to modify it but please send me your improvements!

New Tool to Manage Users and Roles for ASP.NET Membership Provider Based Form Based Authentication (FBA)

It’s a nightmare to create users for FBA, isn’t it? – There are several tools out there, but some does not work as expected oder you need to install .NET 4 on a server just to run a simple ASP.NET app that does this job.

In the last 32 minutes ( 😉 ) I created a simple .NET 3.5 based command line tool that enables me (and you) to create and “manage” users for Form Based Authentication.

You can use the tool in the classic command shell, in a batch or in a PowerShell script. – I’ll translate it to plain PowerShell.

 

There is no syntax check of special error handling!

 

After download you need to modify the “ikfbatool.exe.config” file and modify this line:

<add name="aspnetdb" connectionString="Data Source=sps2010;Integrated Security=SSPI;Initial Catalog=aspnetdb"/>

 

Commands:

Action Command Parameter
Create User cu <username> <password> <email> <question> <answer>
Create Role cr <rolename>
List Users lu (none)
List Roles lr (none)
Add User to Role au <username> <rolename>
List User Roles ur <username>
Remove User from Role rr <username> <rolename>
Delete Uer du <username>
Delete Role dr <rolename>
Reset Password rp <username> [<answer>]
Unlock User un <username>

 

Usage samples:

image

 

You can download the VS 2010 project here:

http://gallery.technet.microsoft.com/sharepoint/Tool-to-Manage-Users-and-c75591c4

 

Or you create your own Visual Studio 2010 Console Application project (.NET 3.5) and past the following code into “program.cs”. You need to add a reference to System.Web.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;

namespace ik.SharePoint2010.fbatool
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if( args.Length < 1 )
                {
                    Console.WriteLine(@"
WRITTEN BY INGO KARSTEIN 
No warranty. Provided as ""as is"". Use it at your own risk!

-------------------------------------------------------------------
#create user
cu username password email question answer 

-------------------------------------------------------------------
#create role
cr rolename

-------------------------------------------------------------------
#list users
lu

-------------------------------------------------------------------
#list roles
lr

-------------------------------------------------------------------
#add user to role
ar username rolename

-------------------------------------------------------------------
#list user roles
ur username

-------------------------------------------------------------------
#delete user
du username

-------------------------------------------------------------------
#delete role
dr rolename

-------------------------------------------------------------------
#delete user from role  (""role remove"")
rr username rolename

-------------------------------------------------------------------
#reset password
rp username 

-------------------------------------------------------------------
#unlock user (""UNlock user"")
un username
");

                    return;
                }

                if( args[0] == "cu" )
                {
                    MembershipCreateStatus status;
                    Membership.CreateUser(args[1], args[2], args[3], args[4], args[5], true, out status);
                    Console.WriteLine(status.ToString());
                }

                if( args[0] == "cr" )
                {
                    Roles.CreateRole(args[1]);
                }

                if( args[0] == "lu" )
                {
                    foreach( MembershipUser u in Membership.GetAllUsers() )
                    {
                        Console.WriteLine(u.UserName);
                    }
                }

                if( args[0] == "au" )
                {
                    Roles.AddUsersToRole(new string[] { args[1] }, args[2]);
                }

                if( args[0] == "ur" )
                {
                    foreach( var u in Roles.GetRolesForUser(args[1]) )
                    {
                        Console.WriteLine(u);
                    }
                }

                if( args[0] == "du" )
                {
                    Membership.DeleteUser(args[1]);
                }

                if( args[0] == "dr" )
                {
                    Roles.DeleteRole(args[1]);
                }

                if( args[0] == "rr" )
                {
                    Roles.RemoveUserFromRole(args[1], args[2]);
                }

                if( args[0] == "rp" )
                {
                    if( string.IsNullOrEmpty(args[2]) )
                        Console.WriteLine(Membership.GetUser(args[1]).ResetPassword());
                    else
                        Console.WriteLine(Membership.GetUser(args[1]).ResetPassword(args[2]));
                }

                if( args[0] == "un" )
                {
                    Membership.GetUser(args[1]).UnlockUser();
                }

                if( args[0] == "lr" )
                {
                    foreach( var u in Roles.GetAllRoles() )
                    {
                        Console.WriteLine(u);
                    }
                }

            }
            catch( Exception ex )
            {
                var c = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                Console.ForegroundColor = c;
            }
        }
    }
}

Now you need to add and configure a “Application Config File” (app.config) with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings/>
  <connectionStrings>
    <add name="aspnetdb" connectionString="Data Source=sps2010;Integrated Security=SSPI;Initial Catalog=aspnetdb"/>
</connectionStrings> <system.web> <membership defaultProvider="MembershipProvider"> <providers> <clear/> <add name="MembershipProvider" connectionStringName="aspnetdb" passwordAttemptWindow="10" enablePasswordRetrieval="false" enablePasswordReset="true" applicationName="/" passwordFormat="Hashed" minRequiredNonalphanumericCharacters="0" passwordStrengthRegularExpression="" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" minRequiredPasswordLength="3" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </providers> </membership> <roleManager enabled="true" defaultProvider="RoleManager" > <providers> <clear/> <add name="RoleManager" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a" connectionStringName="aspnetdb" applicationName="/"/> </providers> </roleManager> </system.web> </configuration>

 

You need to manipulate the yellow marked line to meet your system configuration.

The “aspnetdb” you have previously created with “aspnet_regsql.exe”. – You should be able to use any other ASP.NET MemberShip provider.