Monday, December 2, 2013

Moving a SharePoint site (not site collection), list, or library from DEV to Production


If you want to know how to move a SharePoint site (not site collection) then continue reading. You can also use it to move a list or library.
NOTE: You can use this technique to change the path of a site on the same server or move it to an entirely new server and different path. 

If you are trying to move an entire site collection click here for details on how to do that.

  1. First we need to open up SharePoint 2010 Management Shell (in Start Menu )
  2. Type something like the following to export your site.
    PS> Export-SPWeb https://mysp/abc -Path "c:\temp\abc.cmp" -IncludeUserSecurity -IncludeVersions all
    This will create a file at c:\temp\abc.cmp
  3. Move the file to the new server. For example you can move it from DEV to Production.
  4. (Optional) Go to new server and open up SharePoint 2010 Management Shell (in Start Menu)
  5. Create a subsite at the desired destination url. You MUST use the SAME template that the source site uses. This is the url where you will replace with what you previously backed up. If you try to restore without an existing url it will give you an error.
  6. Type something like the following to import your site to the path specified.
  7. PS> Import-SPWeb http://mysp2/abc2 -Path "c:\temp\abc.cmp" -UpdateVersions Overwrite -IncludeUserSecurity
    This will replace the site at the url http://mysp2/abc2 with the site that we backed up earlier to c:\temp\abc.cmp
The nice thing about this technique is that it keeps the last modified dates as well. 

Wednesday, November 20, 2013

Permission issue with subsite when using FBA with SharePoint

I recently ran into an issue with my SharePoint 2010 (though it appears to be an issue in 2013 as well) site that is using FBA (Forms Based Authentication). Here is the scenario. I have a SharePoint site that is root in FBA Web Application. I don't want to have to do all the configuration for each site I add so I want to create subsites for each new site I want to add. I want to have the root site not accessible to average users. I will give the users of each subsite the direct url to their site. They will not know the root site exists unless they hack the url in the browser. I am using the SharePoint 2010 FBA Pack, but I don't think that really matters (though I have not tried without it being installed). Regardless, the problem I am having is that when I add a user to one of the subsites it doesn't allow the user to log in and instead tells them access denied.

The problem is that the Master Page Gallery for the site collection needs to have the permissions changed. You can verify that this is the problem by

  1. Navigate to your Master Page Gallery (http://yourSPhostHere/_catalogs/masterpage/Forms/AllItems.aspx). 
  2. Once there you can get permissions on that library. Next Click the Check Permissions button and enter the user that is being denied access. If you see that they don't have access then this is likely your problem. 


The solution is simple. From the permissions for the Master Page Gallery do the following:

  1. Click the Grant Permissions button. 
  2. For Users/Groups textfield enter: All Authenticated Users
  3. For Grant Permissions  select Add users to a SharePoint group (recommended)
  4. Select Style Resource Readers from the drop down list.
  5. Click the OK button.
  6. Try to login again. This time it should work.

Tuesday, November 19, 2013

ASP.NET Code Generators Reviewed for the novice or Business Analyst

Requirement

Advanced enough for a ASP.NET developer to do whatever they need to do, but simple enough that a business analyst could create a simple application based on a database schema (done by a DBA or developer). Ideally embrace standard and newer technologies such as Linq, Entity Framework, JSON, WCF. It would be nice to have the ability to create a SharePoint application.

Xomega 3/5 stars

Website: http://www.xomega.net
Xomega uses a Visual Studio Plug-in instead of a full proprietary IDE. Leverages the entity framework and WCF. Generates end-to-end web and desktop applications. Uses Webforms or Silverlight or WPF to implement UI. They have created a new type of VS2013 solution type. Separate projects / assemblies are created in Visual Studio for each layer (ClientObjects, Client.Web, Entities, Model, Services). Configurations are done via XML files using Visual Studios standard tools and navigation. All generation is based on what is in the xml files. Can rename generated files to prevent changes from being overwritten. Partial classes are also used in some cases to implement additional functionality. The generated UI is clean. No coding needed to generate basic UI, but requires a bit of configuration with the XML. Appears to not have a date picker built in. This tool is definitely for someone that is comfortable with Visual Studio and would not be suitable for someone like a Business Analyst. Its strength is that it embraces new Microsoft technologies. Overall I like this generation tool for the more technically proficient developer, but maybe not a beginner that doesn't really understand the different layers and how they fit together.

radarc 3/5 stars

radarc sounds very promising for MVC4 code generation (a rare feature) and multiple mobile phone app generation (Android, iPhone, Windows Phone 8) also. When doing phone app generation it creates the backend REST services as well. It just came out of beta this week. The demo video looks great. I had some issues with basic functionality of the generator working. Based on that, I can't say that this is ready for real production use and should still be in beta. However, I am very excited by the quality of code that it generates. It doesn't use stored procedures and instead its own model and includes a model to do Model first design. I appears to use LINQ or something modeled after it (I need to look closer at that). I get the impression you are locked into the application it generates and that it is a generate-once kind of design. I don't see that many options as far as options / configuration, but I'm sure that will improve as the product matures. I can't give this a excellent status yet, but I hope in time it will mature into a great product. The biggest issue I see is that there is a lack of documentation, I can't change the views that are generated (as far as I can tell) without affecting the ability to regenerate the pages. It suggests that there are extension points for changing views, but I have not figured out where that is. This is a great start once you have your model figured out, and are okay with a generate-once application that you can then customize. 

SoftFluent 2/5 stars

The model is continuously generated from the model (CodeFluent Entities). Supports new technologies such as WCF, JSON, It is not an end-to-end code generation tool. It does do the plumbing for you. Think of it as doing the data access layer and the business layer, but not the presentation layer. It is model-first code generator. It does support many types of applications (ASP.NET MVC, WebForms, SharePoint, Silverlight, Windows Phone, WPF, etc. However, they are not full CRUD applications, they are instead empty applications with the model already to go. Has a concept of Producer for each type of application it creates and allows you to extend it as well. The idea is that it leaves you to do important things like the UI since you have essentially created an API to connect to your UI. I don't really see the cost-benefit of using this since this can more or less be done with the entity framework and domain services which are standard .NET components. 

ASPRunner.NET 3/5 stars

This is a pretty nice end-to-end code generation tool. It seems more like you configure it how you want and then generate once. The WYSIWYG editor is pretty limited and I'm not super impressed. It has many nice themes (colors) and gives you options to change the color on top of that. It doesn't create drop downs for foreign key columns with friendly name, but instead showed numbers. Maybe that was somewhere in the config, but it wasn't automatically done. It generates Microsoft MVC code using Razor. The project is using .NET 4.0. I don't see master-detail layouts by default, but I do see they can be added relatively easy. The data Model appears to be non-existent. There is a Data Access layer that handles most any query you can through at it, but it doesn't use the MS Entity framework or LINQ. Each Controller is VERY heavy because there is code for every option that you MAY want to use on the page. So, the code is MVC, it doesn't really follow the best practice of having a fairly lightweight controller. I'm not sure how, but the UI for the generated apps feel very PHP like. In general it feels a bit clunky. I was hoping for more AJAX /HTML 5 interactions.I want to like this because it is only MVC end-to-end generator I have found, but I just don't like the UI it generates and the controllers are so heavy.

Code4Green 1/5 stars

Website: http://www.code4green.com
Code4Green is a web based code generation tool. It is actually pretty nice if you like the way they do things. You must manually type in your table definitions and it then generates a stored procedures, .aspx, code-behind, data objects, data mapper, etc. You must then copy and paste each of these individually into Visual Studio (after you create the files in Visual Studio). It doesn't use LINQ or Entity Framework or really any of the new UI objects. It generates ASP.NET 1.1 style code. While it isn't bad if you have nothing else, it isn't what I am looking for due to not being able to point it at a database and it generating an application. I also want it to generate more modern code and UI. It reminds me of some simple snippet tools. It does generate some interesting SharePoint code that may be worth looking at further.


LayerCake Generator 2/5 stars

While the architecture looks good for this application it is a new effort. It has only been around since Feb 2013 and the web site is a bit light on content, details, and in general just a polished look that is well thought out.. I tried to run the Cooker application and couldn't get past the first screen. I found it very strange that I have to specify a database that does NOT exist yet. I decide to instead just look through the step by step tutorials. What I see from the tutorial is the following. The primary keys and foreign keys must follow a very specific naming convention. The column names must contain the table name then an underscore then the actual column name. I don't like that at all. I like that it creates contracts and WCF Services. It uses specific table format to handle translations. I think using a table instead of a resource file could have serious performance implications. I like that it support unit tests well. It doesn't appear based on the tutorial that any UI is generated. This looks like an interesting tool, but I think falls short in the end-to-end generator category due to strict database naming rules and no UI generation.

OutSystems Platform 3.5/5 stars

This is a very nice piece of software. I know it must cost a lot because there is no price on the site and you can't get a trial edition without giving them your contact info and then they want you to talk to their sales team. Despite that, it is not so much a code generator as it it is a RAD IDE. It does as they say generate well architected code for ASP.NET or Java, but that could mean anything, so I can't really comment on  it. The IDE is VERY polished. I like the idea of it. Pages and applications look like they can be created quickly using default created when you drag tables onto the screen. You can also do more of a manual page creation. It seems to be quite intelligent and would allow for faster development and easier understanding of application flow because much of the tooling is graphical in nature. Being able to do Java as well is a plus. I have to subtract some stars because it doesn't appear to just generate the full application, and I don't know how easy it is to do a lot of things in the tooling. I don't have all the details I need to properly evaluate the tool, but I have a feeling it is a nice tool that will do what I require AND the price will be way too high. It also suffers from a complete new IDE and paradigm and doesn't use Visual Studio. I see these as pretty major drawbacks if you are looking to keep .NET developers happy.

CodeOnTime 3.5/5 stars

It generates ASP.NET Web Forms application. I think this is a pretty good tool overall for end-to-end application generation and I like the SharePoint-like UI that it generates. However, it just doesn't feel natural to work in this tool. For instance, I don't understand why they have a tab with EVERY field in the database, a tab for All the comands, all fields, all controllers, and all pages. Then when I open any one of these items it is just predefined questions about generation. It appears you can do custom layouts, but it is through a little editor window and just doesn't really make sense to me why I would want to work in that manner. The code it generates looks clean enough, but everything is abstracted away so much I find it difficult to find my concrete classes. For instance, if I have a table called Person and I want to find the methods, pages, etc related to that I can't easily find it. I took stars away from this one because in general I just feel like I get lost in all the pages of code generation options when what I want is to modify fields, pages, controllers, etc.

Microsoft Lightswitch 4/5 stars

Lightswitch generates Silverlight applications which are very nice visually, and are very customizable and extensible. Lightswitch is built into Visual Studio 2013. It uses new technologies like WCF, LINQ, Entity Framework, and good design patterns. Granted you are pretty much locked into their architecture, but that is the case with all these code generators. There is a bit of a learning curve for Lightswitch if you want to extend it heavily. Lightswitch was actually my first choice except that it is based on Silverlight. I was very excited when Microsoft came out with a HTML version. Unfortunately, the HTML version is really heavily geared towards mobile access and really isn't good for a full browser experience. 

Microsoft Dynamic Data 4/5 stars

Microsoft Dynamic Data is a project type built into Visual Studio 2010 and newer that is actually very customizable and generates decent UIs. It can use lots of different technologies, but most importantly it can use LINQ and Entity Framework. The cool thing is that it is all template driven at runtime so you can customize it to whatever you want. You can add any custom pages you want, or have a particular table or page for a table be completely custom. There is really not that much code that is generated compared to some code generators. I have successfully extended the base application into very nice applications, so I know it is extensible. That is not to say that it is quicker than standard ASP.NET to develop, but it does allow you to have all your basic CRUD screens right there and create custom pages for the stuff that doesn't fit that mold. It is worth a look and considering it as a real solution. This is a great platform if you want a starting point for making a company standard for all applications and don't mind working a bit to make it just how you want it. Word of warning: you can spend an enormous amount of time extending (more than just customizing) Dynamic Data Applications. For example, to add security to it and add support for only showing certain fields on a page can take a lot of work.

CodeSmith 3.5/5 stars


Out of the box, CodeSmith is really about allowing you to create your own templates to generate your own code. However there are hundreds of templates to help speed up development. One example that allows the generation of an entire application is  .netTiers. Based on a database schema it creates separate Logical layers for entity, dal, business, web, forms, web service. It uses stored procedures or parameterized sql for dal. The UI is reasonable, but a bit dated in look and feel. The good news is this is 100% customizable. CodeSmith would be a good option if you want to completely customize the kind of application that gets generated. It is a reasonable option if you combine it with .netTiers for generating an application with the click of a button

NOTE: There is a open source product called TaHoGen that executes CodeSmith templates, but has no UI.

MVC Scaffolding using Razor and Entity Framework 2.5/5 stars

While scaffolding in ASP.NET MVC projects in Visual Studio 2012 is very cool and extensible (yes you can customize the generated scaffolding). However, there is no ability to maintain the changes and have to be done manually or regenerate the scaffolding. It is also far from point and click to generate the application. For an experiences MVC developer and a polished database, a basic application could be done fairly quickly, but in days and weeks and longer to develop something similar to a polished application. The upside is that the code is very clean and the html pages sent to the browser are generally very light because they are MVC, not WebForms. While I can't recommend this scenario for a business analyst, I would recommend it for developers. Hence, my poor rating for it. Please not I love MVC, but it doesn't fit these requirements. As a tool for a developer I give it 4.5/5.

Iron Speed 4.5/5 stars  THE WINNER

Iron Speed specializes in end-to-end generation of ASP.NET WebForms based applications using its own data, business, and presentation layers, and stored procedures or inline SQL. It excels at picking up changes to the database and maintaining your application. It is not a generate once kind of generation tool. It gives you the tools to edit your application. In general it has an IDE that gives you everything you need to maintain the application. However, there are thimes when you will want to use Visual Studio such as to get Intellisense support if you are writing lots of code. You do not need Visual Studio, but you can use it. However, do NOT edit the .aspx pages. Instead you must use the Excel like editor to manipulate the page. Alternatively, you can make changes via code. There are event handlers for everything, you can override methods, etc It has a concept of formula that work like Excel and are great for doing calculations, manipulations, and in general most customizations you will need to do. It has great transaction support. For example, if you have a master-detail page the all the details rows can be edited at the same time AND the master (parent) is editable all without even saving. This allows for Excel like editing in grids. Filters are trivial to add. Moving columns and layouts is all graphical and trivial. The UI is very polished looking. You can create your own ASP.NET theme to change the look and feel of the application. There are many different kinds of layouts. Training is readily available through videos or through live training classes which include Q&A. Security is trivial as well. Just define if you FBA, Windows authentication, FBA with Active Directory as backend, etc and then set permissions on each page and even field if yo u prefer using the graphical UI. It does NOT use Entity Framework or LINQ, but it does use well written stored procedures and has a data layer. The data layer basically maintains itself. The business layer does too for the most part. This IDE is suitable for a techie Business Analyst or beginning developer. It deploys to SharePoint 2007 and 2010, but not SharePoint 2013. If Iron Speed had support for Entity Framework and LINQ and MVC I would give it a 5/5.

NOTE: I have been using this tool for a few months now and support on the tool is also good. I have not found anything I can't do with it or anything functionality I can't implement in it. I have a deep understanding of ASP.NET, but it is by no means necessary to use this tool. In my mind, this is the best choice for my needs. Depending on your needs you may choose differently. There are lots of good choices and cheaper solutions.











Thursday, October 17, 2013

Use Cases for Reporting Services

Overview

  • Report Viewer Control
  • Reporting Services (Standalone)
  • Reporting Services (SharePoint-Integration)
  • Reporting Builder

Types of files used


.RDLC

  • No Reporting Services installation required
  • Takes .NET DataSet (object in code) as a data source / dataset.
  • Code change required to update DataSet.
  • Report is generated by the hosted application
  • Can be referenced by Report Viewer Control
  • Requires .NET application
  • Use newest version of Visual Studio to create report
  • User Parameter GUI is manually created by developer on page.


.RDL

  • Requires Reporting Services installation
  • DataSet is defined using GUI, not code
  • No code changes required to update DataSet.
  • Report is generated by Reporting Services
  • Can be referenced by Report Viewer Control
  • .NET application is optional
  • Use Business Intelligence Studio to create report.
  • User Parameter GUI is automatically generated by Reporting Server or manually on page.

Report Viewer Control


  • Generates a preview of the report for users
  • Allows user to print or save reports in different formats including PDF, HTML, DOC, etc
  • Requires a .NET application to host the ASP.NET Server control
  • Can use .rdlc and .rdl

Reporting Services (Standalone)


  • Useful when wanting to add Reporting Services to a .NET application because permissions can be managed using Active Directory groups/users or using service account (and delegating permissions to the .NET application).
  • Serves up .RDL files.
  • Generates preview of .RDL files
  • Provides UI to manage
    • Permissions on report
      • Individual accounts
      • Active Directory Groups
    • Schedule delivery of report
    • DataSource

Reporting Services (SharePoint Integration)

  • Useful when wanting to add Reporting Services to a SharePoint site because permissions can be managed using SharePoint groups instead of Active Directory groups as with the standalone installation of Reporting Services.
  • Serves up .RDL files still done by Reporting Services
  • Generates preview of .RDL files still done by Reporting Services
  • SharePoint provides the following UI (instead of Reporting Services) to manage
    • Permissions on report
    • Schedule delivery of report
    • DataSource

Report Builder

  • Report Builder can be used to edit .RDL files (not .RDLC)
  • Report Builder is almost identical in functionality to BIDS (Business Intelligence Development Studio). 
  • The most noticeable difference is the lack of Intellisense.
  • The UI is also more geared to be more end user vs. developer friendly.
  • Report Builder is available as an install or as a ClickOnce installation.




Tuesday, October 8, 2013

How to work around issue with using Visual Studio 2012 / Web Application to create a .rdlc report using Report Viewer Control

I don't know what I am missing, but as far as I can tell the Report Viewer in Visual Studio 2012 does NOT work properly when using a ASP.NET Web Forms Application. Notice I said APPLICATION, not Web SITE. To clarify, there is no issue you create a ASP.NET Web Forms Site Here is the scenario I will propose a work around to.

  1. Open Visual Studio 2012
  2. Create a new ASP.NET Web Forms Application (This is the critical choice to make this break)
  3. Create a report and call it Report1.rdlc
  4. Open your default page. The master page should have a Script Manager on it already. If it doesn't then you will need to add it.
  5. Drag the ReportViewer control from the Toolbox to the content area on the Default page (or other page).
  6. Use the SmartTag (the little box with a triangle in it on the upper right corner of the ReportViewer control to choose your report. This will create an ObjectDataSource with the improper configured.
  7. You can verify the ObjectDataSource is configured improperly by clicking the Refresh Schema task on the Smart Tag of the ObjectDataSource. It will generate an error similar to:

    The 'AdventureWorks2008R2DataSetTableAdapters.SalesOrderDetailTableAdapter' could not be loaded. If the type is located in teh App_Code folder, please check that it compiles. If the type is located in a complied assembly, please check that the assembly is referenced by the project.

    The type 'AdventureWorks2008R2DataSetTableAdapters.SalesOrderDetailsTableAdapter' could not be found'
  8. Reconfigure the ObjectDataSource and you will see that the problem is that it should have the namespace before the type (that it can't find). It is as if the Microsoft developer that did this functionality didn't realize the ObjectDataSource that would be created is different depending if you are using a ASP.NET Web Forms Application or a ASP.NET Web Forms Site.

  9. Run the application and you will get an error similar to this:

    An error occurred during local report processing.The report definition for report 'Report1' has not been specified Object reference not set to an instance of an object.
  10. To fix that issue, you need to select the Report Viewer and look at the Properties pane. 
  11. Scroll down to where it says LocalReport and expand that area using the Plus sign (+).
  12. Set the ReportPath property to Report1.rdlc (or whatever the filename is of your report).
  13. Run the application again. This time it will hopefully work. 

Alternatives
  1. Do everything in code.
  2. Don't use the smart tag - Create the ObjectDataSource first and make the bindings to the Collection and ReportPath yourself using the Properties panel (not the smart tag since the bug seems to be in the Smart Tag of the ReportViewer).

Tuesday, September 10, 2013

SSRS in SharePoint integration mode gets HTTP status 401: Unauthorized error on only one server

My environment has two web front ends for SharePoint. We have SSRS (SQL Server Reporting Services) installed on one of them. I have used Central Administration to integrate the two. If I access a SSRS report using a load balanced url, about 50% of the time I get the following error (in the SharePoint logs).


Exception encountered for SOAP method GetSystemProperties: System.Net.WebException: The request failed with HTTP status 401: Unauthorized.     at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SetConnectionProtocol()     at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)

System.Net.WebException: The request failed with HTTP status 401: Unauthorized.    at Microsoft.ReportingServices.SharePoint.UI.RSConnectionInfo.get_SPManagementProxy()     at Microsoft.ReportingServices.SharePoint.UI.RSItemPickerNavigator.ListParents(String item)     at Microsoft.ReportingServices.SharePoint.UI.RSItemPickerNavigator.GetParentItemUrl(String enumerableLocation)     at Microsoft.ReportingServices.SharePoint.UI.ItemSelectorDialogControl.ValidatePath(String unvalidatedPath, Boolean useFallbackPath, String& itemPathParent, String& itemPathGrandparent, String& invalidReason)     at Microsoft.ReportingServices.SharePoint.UI.ItemSelectorDialogControl.OnPreRender(EventArgs e)     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Control.PreRenderRecursiveInternal()     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

If I use a url that goes directly to one of the servers, I soon see that predictably I get the error for only one of the servers. How weird. I also found that if I add the Reporting Services web part to a page and then try to select a report I get the same error. The good thing is that I then got a correlation id which I could then use to find the exact error in the SharePoint logs.

So I verified a bunch of things:
  • Changed Reporting Services to be a single server deployment instead of a scaled out deployment (just to make things easier to troubleshoot).
  • The patch level is the same for the servers
  • The files are identical on both servers
  • Tried using the IP address of the reporting server instead of the host name in Central Admin | Reporting Services Integration | Report Server Web Service URL.
  • Changing logging in Reporting Services to verbose. Click here for instructions.
  • Disable loopback check. Click here for instructions and security risks.
  • Selected Authentication Mode to Trusted Account in Central Admin | Reporting Services Integration | Authentication Mode. I was using a service account before that.

I believe the last thing I tried was the key change that solved it, but the other items could also have helped (though it never worked until I made the last change).

Lots of docs I read through to try to figure out what was wrong. If the above doesn't work, you may want to start with one of the links below.

Thursday, September 5, 2013

Connect to a FileShare using different credentials

Ever try to use robocopy of other tools to copy files from a Windows share, but you need to use the credentials of another users? If you were to try to use Windows to access the Windows share it would prompt you for a username and password. However, from the command line or batch file it won't. To get around that, you can do the following:

net use \\server1\c$ /user:domain1\user1

When you are done with it, you can remove the credentials you setup by doing the following:

net use \\server1\c$ /delete

You can type net use /? to get help

Here is what you could get from the help

>net use /?
The syntax of this command is:

NET USE
[devicename | *] [\\computername\sharename[\volume] [password | *]]
        [/USER:[domainname\]username]
        [/USER:[dotted domain name\]username]
        [/USER:[username@dotted domain name]
        [/SMARTCARD]
        [/SAVECRED]
        [[/DELETE] | [/PERSISTENT:{YES | NO}]]

NET USE {devicename | *} [password | *] /HOME
NET USE [/PERSISTENT:{YES | NO}]

For explanations of each switch check out the online docs.

Notice you can pass the password so you can use it in a start up or batch script. It also has a /PERSISTENT option so that the connection will be restored at each logon.

Wednesday, September 4, 2013

Creating a FBA (Forms Based Authentication) (Extranet) site in SharePoint 2010

By default SharePoint uses Windows Authentication and Active Directory to control who can access a SharePoint site. In most cases, this is desired behavior. However, I have a scenario were the users are actually external users from the internet. Basically, I want to use one of my SharePoint web applications as an Extranet. While Windows Authentication works well for intranets, it is doesn't make sense on the internet. Typically on the internet users have a username and password that is specific to the site they are access. This is the behavior we want to have for our SharePoint site.

You can use FBA (Forms Based Authentication) and still use Active Directory as the security store to query, but in my case I didn't want to do that either because there were some domain trust issues. Also, it made provisioning new users for the extranet more difficult. The ideal solution I chose was using ASP.NET Membership provider that can be used in any ASP.NET application. Mainly because it is standard and SharePoint supports it, and others have already used it.

Unfortunately, doing all this is not trivial and is actually quite tedious. Fortunately, many people have done this with some variation.

I looked at several sites that showed how to do this to varying levels of detail. I found this one that showed lots of details, screenshots, and explained why in many cases. I did learn some things along the way that were not explicitly noted.
  • When creating the ASP.NET database, use the farm service account or whatever you run the application pools as. This will guarantee that the service account has access to the database. This was important to me since I didn't have direct access to my SQL Server. Alternatively, you can do it like the article describes as well. The reason is I needed to use Windows Integrated Security to connect to my SQL Server database. This can be easy if the Service account can RDP to a server, but if the user can't (like my scenario) then you need to run the aspnet_regsql.exe as the service account. To do that, do the following:
    1. Open a command prompt by right-clicking on it and choosing Run as Administrator
    2. At the command prompt type
    runas /user:SPServiceUser cmd.exe
    This will give you a command prompt running under the service account (mine is called SPServiceUser in this example). Now you can do whatever you want as that user.

    3. In this case, we want to run aspnet_regsql.exe, so do something like:
    C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe
  • When it came to the SecurityTokenServiceApplication, I didn't have much luck with the default providers being set the way the author suggested. I changed removed the defaultProviders Attribute for roleManager and membership tags. New Default could be FBA,FBARoles, but the CA user look test (later in this doc) only seems to work with c,I as defaults. Curious if others have the same issue.
  • You will need to make these changes on each node in the SharePoint web farm, probably want to just copy the web.config files from server to server. If you aren't sure if the corresponding web.configs on each server is the same, then maybe just copy the key parts outlined in my diagram. I was surprised my web.configs had variations from server to server. I don't think they should be though.
When it came to troubleshooting, and comparing different articles I found on the internet, I found it difficult to figure out why there were differences and if there were what were they. Also, I wanted to know what they were assuming the default settings in IIS and the web.configs were before and after. Also, I am a visual person, so I wanted a nice visual representation of before and after. I also found it difficult to keep track of what the settings where for users verses roles. So, I put together a diagram and corresponding final web.config examples. You can download it here. The user settings are on the left, and the roles are on the right.

Once you are all done, you will likely realize that you have no way to manage users yet. A good choice for adding this functionality to the Site Settings of SharePoint 2010 is SharePoint 2010 FBA Pack. I have tried it (password change and reset, add, edit, delete users manually) and found that it works well. I am not letting users request access to the site, so I didn't try that functionality.

Other things I tried
I ran into trouble trying to extend an existing web application and have FBA on one url and Windows Authentication on another url. I was able to get a single site to have both FBA and Windows Authentication, but we didn't want the users to have to decide if they were FBAor Windows Authentication. I also tried converting an existing site using Powershell, but I didn't have much luck with that either. In the end, it was best to just create a site that only used FBA.

If you are doing the same thing for SharePoint 2013, you may want to look at this one. I haven't studied it in detail,but it looks like it is good. From what I remember reading, the configuration is basically  the same, but IIS doesn't support adding the users so you have to do it another way.

The key links you need in one place:
Step by Step Instructions
My Visual Summary and Web.Config examples
Add FBA User and Role management to SharePoint 2010
A good place to start if you are using SharePoint 2013 instead of 2010

Tuesday, August 27, 2013

Troubleshooting Reporting Services Access Denied Error when using Forms Based Authentication (FBA) in SharePoint 2010


Here is the scenario. I have a SharePoint 2010 site that uses Forms Based Authentication and as such it uses Claims Based Authentication. I did not enable Windows Integrated Authentication on the site. I created a Reports Library and created a very basic report there. It doesn't even pull any data. It just shows static content. I did that to eliminate any chance that the access denied was to a data source. In the real world, I did eventually have it pull real data once I solved my access denied issue.

I am running:
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (X64) Mar 29 2009 10:11:52 Copyright (c) 1988-2008 Microsoft Corporation Express Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1) (VM)
 
The error I get when trying to load the page is as follows:
 
 
 
In text form:
Report Server has encountered a SharePoint error. (rsSharePointError)
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
For more information about this error navigate to the report server on the local server machine, or enable remote errors.
 
After searching through the SharePoint log files on the server we found:
Web part failed in SetParamPanelVisibilityForParamAreaContent: Microsoft.Reporting.WebForms.ReportServerException: Report Server has encountered a SharePoint error. (rsSharePointError) ---> Microsoft.Reporting.WebForms.ReportServerException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) ---> Microsoft.Reporting.WebForms.ReportServerException: For more information about this error navigate to the report server on the local server machine, or enable remote errors     --- End of inner exception stack trace ---     --- End of inner exception stack trace ---     at Microsoft.Reporting.WebForms.ServerReportSoapProxy.OnSoapException
 

The Solution

 
For Access Denied error, one solution put forth in this forum is
Reporting Services service account must be local admin on the reporting services server, please check if you meet this requirement. If not add the user to the server's local admin group and "reintegrate the reporting services with SharePoint"



The SSRS service account (you can get this from the SSRS Configuration tools in the Start Menu) was not in the local administrators group where  Reporting Services is installed. I have made this correction. I did NOT appear to fix the issue. I even tried restarting Reporting Services from  Services.msc, but no help.
Then I realized that I still need to "reintegrate the reporting services with SharePoint." I was not sure exactly what that meant, so I just tried some things. Here is what I did that I think fixed it after adding the SSRS service account user to the local admin group:
  1. In Central Administration| Reporting Services | Reporting Services Integration| Clicked Activate feature in all existing site collections and then the OK button.
  2.  
  3. In Central Administration| Reporting Services |Add a Report Server to the Integration changed Server Name to a wrong value then changed back to the server name where Reporting Services is installed. Click OK after each change. When prompted for credentials I entered the farm service account and password.
  4.  
  5. I tried the report and it worked. I’m not sure exactly which step fixed it, but it works now.


Some other things to try if it still doesn't work:


You need to be running SQL Server 2008 R2 according to this article on MSDN. It says:

"SharePoint 2010 Claims based authentication is not supported by SQL Server 2008 or SQL Server 2008 SP2 report servers. Use SQL Server 2008 R2 Reporting Services if you need to use a Claims enabled SharePoint 2010 Web application."

According to the article, you don’t have to upgrade our SQL Server to SQL Server 2008 R2, but you do need to upgrade to at least SQL Server 2008 SP1 + Cumulative Update #8. You would have to upgrade the SQL Server 2008 R2 Reporting Services add-in for SharePoint 2010 products on all associated servers.

This article from MSDN also talks about compatibility issues. This is also useful. Here is one just for troubleshooting.

Wednesday, August 14, 2013

How to copy a SharePoint SiteCollection to a new server

First thing, you should make sure that the patch level is the same for both the installed patches and the content database. See here for more details on updating the patch level. Once the environments are the same, it is relatively straight forward to copy a SharePoint Site collection from one server to another server.


Here are the steps
  1. Backup the site collection
    You can use Central Administration | Backup and Restore | Perform a site collection backup. You can use a UNC share path or you can specify a local disk path.
    Alternatively, you can use Powershell to do the backup as well.
    PS> Backup-SPSite "http://yourSPServerHere/sites/siteCollection1" -Path "C:\temp\siteCollection1.bak"
  2. Copy the backup file to the new server or use a file share that both server can access to avoid copying the backup file. In this example, I kept the same path on the local disk for ease of syntax.
  3. Restore the site collection at a desired url
    PS> Restore-SPSite "http://yourNewSPServerHere/sites/siteCollection1" -Path "C:\temp\siteCollection1.bak"
    NOTE: Unfortunately, there is ability to do this in Central Administration like there is for the backup.
    Also, notice I kept the same basic url (minus the server change)

Troubleshooting Powershell

If you get an error like the following:
The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.
Check here for details on how you can get access.

Patching or Updating SharePoint 2010 is a two step process

Whenever you patch or update SharePoint Server 2010 there are really two steps you need to follow. The first is the more obvious one. You download the patch from Microsoft and install it. It will typically show up in the Program Files list under the Control Panel. This needs to be done on each web front end in the farm. This is where many people stop. However, SharePoint 2010 requires that the content databases be updated as well. To update the configuration database, you have to do the following steps on one of web front ends in the farm. I usually use the one that has Central Administration installed.

  1. Open an Administrative command prompt.
  2. cd C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN
  3. Run PSConfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures
 This process can take a while depending on how big your databases are, processing power, etc, but it does take many minutes generally and SharePoint will be down while it is being updated.

For more details, check out this blog. I summarized some key info from it:

Tuesday, August 13, 2013

Troubleshooting: Cannot start service SPAdminV4 on computer

 
 
Failed to create the configuration database.
An exception of type System.InvalidOperationException was thrown.  Additional exception information: Cannot start service SPAdminV4 on computer '.'.
 
Potential Cause #1: SPAdminV4 Service needs more time to startup
The default is typically less than 30 seconds, so I changed it to 4 minutes (240,000 milliseconds) and this helped. A smaller value or larger value may be needed for your environment.
 
To change the default timeout for ALL services to start up do the following:
When a service starts, the service communicates to the Service Control Manager how long the service must have to start (the time-out period for the service). If the Service Control Manager does not receive a "service started" notice from the service within this time-out period, the Service Control Manager terminates the process that hosts the service. This time-out period is typically less than 30 seconds. If you do not adjust this time-out period, the Service Control Manager ends the process and the attached debugger while you are trying to debug. To adjust this time-out period, follow these steps:
  1. In Registry Editor, locate, and then right-click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
  2. Point to New, and then click DWORD Value. In the right pane of Registry Editor, notice that New Value #1 (the name of a new registry entry) is selected for editing.
  3. Type ServicesPipeTimeout to replace New Value #1, and then press ENTER.
  4. Right-click the ServicesPipeTimeout registry entry that you created in step c, and then click Modify. The Edit DWORD Value dialog box appears.
  5. In the Value data text box, type TimeoutPeriod, and then click OK
    Note TimeoutPeriod is a placeholder for the value of the time-out period (in milliseconds) that you want to set for the service. For example, if you want to set the time-out period to 24 hours (86400000 milliseconds), type 86400000.
  6. Restart the computer. You must restart the computer for Service Control Manager to apply this change.
 
Yes, you need to restart for the change to take effect.

This was copied from http://support.microsoft.com/kb/824344; see #3 on the page.
 
Potential Cause #2: Certificate Validation
 
Beginning with June 2012 CU for SharePoint 2012 the CRL (Certificate Revocation List) checks to be enforced, which in turn affects some native functionality of SharePoint AdminV4 service. 
When running the SharePoint Product Configuration Wizard, the configuration will fail with the following error above. This is typically an issue if you don’t have direct internet access.
 
To work around this issue.
 
1.) Add a new computer policy which alters the options for retrieving certificate validation on a network.
2.) Add host file entries into the local computer host file.
  • Alter the computer policy
    • Click on Start-Run
    • Type in "GPEdit.msc" and click "OK"
    • Expand Computer Configuration-Windows Settings-Security Settings-Public Key Policies
    • Double-click "Certificate Path Validation Settings"
    • Click on the "Network Retrieval" tab
    • Check the box "Define these policy settings"
    • Uncheck "Automatically update certificates in the Microsoft Root Certificate Program (recommended)" and uncheck "Allow issuer certificate (AIA) retrieval during path validation (recommended"
    • Click on "OK"
    • Close out of GPEdit.msc
  • Add host file entries
    • Click on Start-Run
    • Type in "C:\Windows\System32\Drivers\Etc" and click "OK"
    • Double-click the file "Hosts"
    • Select "Notepad" as the program to open the file
    • Insert the following lines into the hosts file
      • 0.0.0.0 crl.microsoft.com
      • 0.0.0.0 crl.verisign.com
      • 0.0.0.0 ocsp.verisign.com
      • 0.0.0.0 SVRSecure-G2-crl.verisign.com
      • 0.0.0.0 SVRSecure-G3-crl.verisign.com
      • 0.0.0.0 www.download.windowsupdate.com
      • 0.0.0.0 SVRSecure-G2-aia.verisign.com
    • Save the file and exit notepad
I copied the above steps from:
 
 

Thursday, August 8, 2013

What is running on port 80


You can use netstat to see the process id of what is running on port 80 (or any other port for that matter). Here is the command you would use.

netstat -p tcp -ano

You can then start Task Manager and find the process that has that PID.

If you don't have a PID column you can add it.
  1. In Task Manager go to the Processes tab
  2. Go to the View menu | Select Columns... menu item.
  3. Select PID (Process Identifier)
  4. Click OK
That may or may not be useful. In my case the PID is 4 which is the System process and has the description NT Kernel & System. The problem is that lots of applications can use the kernel to open a port. Unfortunately, that was a deadend for me. I guess this exercise is sort of useful :)

Monday, August 5, 2013

List of Best Practices for C# and SharePoint development

Here are Guidelines for Naming Convention, Design Considerations, Best Practices, and Coding Conventions. They are definitely for C#. Web parts should be written in C# as well , so these conventions can also be applied to them.


Below is some best practices when developing web parts, and any code that uses the SharePoint Object Model. Generally, these do not go into code syntax or anything like that. They do go into issues specific to SharePoint development.




Thursday, August 1, 2013

Reporting Services Permission Error

I have Reporting Services installed on SharePoint 2010. I created a new web application in SharePoint and then created a Site Collection. I then created a Report Library and then created a report. I opened the report from the link in the Report Library and I got the following error.

Report Server has encountered a SharePoint error. (rsSharePointError)

 
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
 
For more information about this error navigate to the report server on the local server machine, or enable remote errors
 
To fix the error I did the following:
  1. Go to Central Administration | Application Management | Manage web applications
  2. Select your web application
  3. Click User Policy in the ribbon
  4. Add Users the Reporting Services service account and give it Full Control.

Thursday, July 25, 2013

Convert existing SharePoint Web Application from Classic Mode Authentication to Claims based Authentication

If you want to use FBA (Forms Based Authentication) with SharePoint you can, but you will need for the web application to be setup in Claims based Authentication instead of Classic Mode Authentication. One option would be to delete the application and re-create it using Claims based Authentication. While technically possible, it is a lot of work and not necessary. Instead, try using Powershell to solve this problem in seconds. Try the following:
  1. Open SharePoint Management Shell by going to Start Menu | All Programs | Microsoft SharePoint 2010 Products. Now right-click SharePoint 2010 Management Shell and choose Run as administrator.
  2. Now go the following Powershell commands:

    PS> $app = Get-SPWebApplication "http://yourSpHost:7777"
    PS> $app.UseClaimsAuthentication = "True"

    PS> $app.Update()
  3. To verify the change: Go to Central Administration | Manage web applications, and select the application you modified.
  4. Click the Authentication Providers button in the Web Applications ribbon. It will now show Claims Based Authentication.
 Troubleshooting:
NOTE: if you get the error: "The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered." try some of my fixes outlined here

Resolving: The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.

If you try to run something like Get-SPWebApplication http://yourSpHere:1234 you may get the error:

The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.


Things to try.

1. Make sure you run the command as Administrator. For example, Go to Start Menu | All Programs | Microsoft SharePoint 2010 Products. Now right-click SharePoint 2010 Management Shell and choose Run as administrator.

2. If that doesn't work then it is likely you don't have access to the SharePoint configuration database. On solution would be to grant your users access to the configuration database, but that probably is not the best plan.

3. A better option is use a user that does have rights to the configuration database. This is often a SharePoint service account. If that service account has RDP access you one of your SharePoint front end servers then login as that service account and execute the command. If you want to be able to execute it with your specific account, then we need to do some more things. You can do the same thing as #1 to bring up the SharePoint 2010 Management Shell, and then execute

powershell prompt>Add-SPShellAdmin -UserName yourdomain\yourusername

This should make it so your specific user can now do #1.

If the SharePoint service account does NOT have RDP access then things are a bit trickier. In that case, follow these instructions:
  1. RDP to the SharePoint server using an account (usually in the adminstrators group in Windows) that can execute RunAs command.
  2. Go to Start Menu | All Programs | Accessories. Then righ-click on the Command Prompt item and select Run as administrator.
  3. Now we need to open the PowerShell prompt as the SharePoint service account. To do this, do the following command:

    cmd promopt>runas /user:yourdomain\yourusername C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  4. Type whoami at the prompt to verify that you are indeed the service account.
  5. At this point we have a standard Powershell prompt, but it doesn't know about SharePoint, so we need to add it. Use the following command to do so:

    powershell prompt>Add-PSSnapin Microsoft.SharePoint.Powershell
  6. Now you should be able to grant your specific user rights to use SharePoint powershell commandlets. To do so, use the following command:

    powershell prompt>Add-SPShellAdmin -UserName yourdomain\yourUserName
  7. Now you should be able to use method #1 with your specific user and not have to do all this fancy stuff everytime.

Wednesday, July 10, 2013

How to Center a DIV tag horizontally using CSS

I miss the days of using the CENTER tag. Now it seems it is not really a good idea to use the CENTER tag. It is recommended that CSS be used instead. It seems that it is a bit more difficult to do with CSS.
In this example, my DIV only contains text, but it could contain anything. If it was just text, text-align:center could be used, but to center a div tag and its contents it takes a bit more.

First thing we need to do is give the DIV a width and then it can be centered. Here is an example of how to center a DIV that is 400px wide.


<div style="width:400px; display:block; margin-left:auto; margin-right:auto>">
some stuff here
</div>


You can also create a CSS class and reference it, but I have put the style inline for simplicity, but probably not a good for maintainability.

Thankfully, this is pretty simple once you know what to do.

Monday, June 24, 2013

Hide Columns in a SharePoint list based on SharePoint group

It seems to be a fairly common request to hide particular columns on a SharePoint form based on the SharePoint group that a user is a member of. One solution to this problem would be to create custom forms for Add, Edit, and Display in SharePoint using SharePoint designer. Then figure out a way to hide and show the columns. This requires SharePoint Designer access and may not always be an option. It also requires the user to read through ASP.NET / XSL markup and figure out how to do it. This is a very tedious task and hardly easy to maintain. The good news is that this is a truly secure solution since the data is not sent to the client (browser). If you have these strict security requirements then you may want to go this route. FYI, I have read that InfoPath is also an option, but I don't like going that route either.

I am working on an internal instance of SharePoint 2010 and simply hiding the data on the forms using CSS is sufficient because the user would have to look in the source of the page to see the data.

WARNING:
Note: This is NOT a true security solution! All data (even for hidden columns) is sent to the browser, but is just hidden from user's view in the browser.

In my case, it would not be the end of the world if users viewed source to see all the data. We are all part of the same company after all. If this is your scenario, then you may want to consider the solution outlined below.

My solution uses a JavaScript library called SPUtility.js. It makes hide and showing a field simple. It also makes changing a field to readonly simple as well. I can't take credit for the library, but I am very happy I found it. The only problem left to solve was how to get the current user and the groups that the user is in. This is something I had to come up with. It requires CSOM (Client Side Object Model) which requires SharePoint 2010 or later. I read that you can use SPServices if you are using MOSS 2007, but I have not tried to do it.

To implement the functionality to get user and group information, I wrote the following methods.

You can download the source here.

function getCurrentUserObject(callbackFunc)

function isCurrentUserInSharePointGroup(sharePointGroupID, callbackFunc)

function isUserInSharePointGroup(userLogin, sharePointGroupID, callbackFunc)

CSOM uses asynchronous calls for everything which makes it difficult to code if you are not accustomed to it. The good news is all you have to do is provide the callback function to make use of these functions. While that may sound difficult, just follow the example I have provided. In the example code the first thing it does is make sure the CSOM library (sp.js) is loaded and then executes our code. It takes the approach of getting the current user then seeing if the user is in the owner group and setting column visibility appropriately. If the user is not in the owner group it then looks in the members group and sets the column visibility appropriately. If they are not in either of those groups it sets the column visibility appropriately. You could continue on with different checks if desired.

Here is a snippet of what the solution code looks like:

function doOwnerChanges(userLogin, isInGroup)
{
  if (isInGroup)
  {
 
   SPUtility.GetSPField('Title').Show();
   SPUtility.GetSPField('Cost').Show();
   SPUtility.GetSPField('Customer Comment').Show();
   SPUtility.GetSPField('Assigned To').Show();
   SPUtility.GetSPField('Internal Comments').Show();
  }
  else // not in owner group let's see if they are in members group
  {
 
   isUserInSharePointGroup(userLogin, 7, Function.createDelegate(this, this.doMemberChanges));
 
  }
}


As you can see it is easy to maintain because all the complexity is abstracted away. If another column is added you would just add a line to the above code.



Added solution to your page

  1. Download the following:
    • SPUserGroupUtility.js My code that gets the current user and checks the groups the user is in.
    • ShowHideColumnExample.js (only needed if you want an example of how to use this solution). You can replace or not use this in your specific implementation. This is the file you will need to specify your columns. The name is not important except that you reference it later.
    • SPUtility.js This provides the functionality for hide/showing fields and making them readonly, etc.
    • Prototype.js Required by SPUtility.js.
    • sp.js - actually you don't need to download it. Ultimately, this is the CSOM library. It is provided by SharePoint 2010. Just use it in your code as needed.
  2. Upload the .js file to somewhere on SharePoint where all users can access the files. I recommend installing your .js file in your Site Assets directory on your site. You can find it by going to Site Action | View All Site Content | Site Assets.
  3. Navigate to form (EditForm.aspx or NewForm.aspx)
    In SharePoint 2010, you can choose Form Web Parts -> Default whatever Form
  4. Add a Content Editor Web Part to the page
  5. Edit the web part
    In SharePoint 2010, click the arrow -> Edit Web Part.
  6. Edit the content editor's HTML to add some JavaScript
    In SharePoint 2010, under Editing Tools -> Format Text click the HTML button -> Edit HTML Source
  7. Follow the instructions on installing the SPUtility.js
  8. <script src="/sites/someSite/SiteAssets/prototype.js" type="text/javascript"></script>
    <script src="/sites/someSite/SiteAssets/SPUtility.js" type="text/javascript"></script>
    <script src="/sites/someSite/SiteAssets/ShowHideColumnExample.js" type="text/javascript"></script>
    <script src="/sites/Brent/SiteAssets/SPUserGroupUtility.js" type="text/javascript"></script>
  9. Save the page / stop editing.

Troubleshooting

  • NOTE: To just try SPUtility.js you can try the install instructions.
  • If nothing happens on the page, make sure you don't have any errors. You may need to do an F12 in IE to see the error console. Also, you can look at the F121 | Network tab to see if the JavaScript files are able to be found.
  • You can always start the JavaScript debugger and see where it is breaking.

Tuesday, June 18, 2013

Authenticating a user against a specific domain (C#)

In the example below I am authenticating an imaginary user called usernameHere that has a password of passwordHere against the mydomainHere.com domain. In this example, the user would normally login using something like this: mydomainHere\usernameHere and then enter the password. The .com was added to the domain because that is typically how domains are set up. However, if you have a different long name for the domain, you should use that.

using using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

...
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "mydomainHere.com"))
{
     // validate the credentials
     bool isValid = pc.ValidateCredentials("usernameHere", "passwordHere", ContextOptions.Negotiate);
     Console.WriteLine("Valid: " + isValid);
    
}


You will need to add a reference to System.DirectoryServices.dll and System.DirectoryServices.AccountManagement.dll in order for this to work. If you don't have version 3.5 or newer of .NET, you will not have these methods available to you. This link has many other methods that you can try.

As a side note, here is a article that shows lots of code snippets for doing common tasks in Active Directory using C#.