in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

Ethan's blog

  • Specify What Forms a Field Shows Up On

    I am often asked about field level security in SharePoint. Well, SharePoint does not have field level security but it does have the ability to specify which forms a field will show up on. For example, we can have a field show up on the New form and all view forms but not on the edit form. This is by no means security, but it does allow for certain  scenarios, like after a value is entered it cannot be changed. So, this post will show you how to change those settings on fields.

    There are 2 different ways to set these properties. The first is through the list definition. When we create a list definition we can certain attributes on the Field element tag as follows.

    • ShowInEditForm - Determines if this field shows up in the Edit form for a specific field.
    • ShowInNewForm - Determines if this field show up in the New form for adding a new item to this list.
    • ShowInVersionHistory - Determines if this field shows up in the version details of a list item.
    • ShowInViewForms - Determines if this field shows up in the any View forms for a specific item.

    This post is going to show you the second way, in code, to set these properties. Through the SharePoint API you can also set these properties of a specific field. These are optional value fields, meaning that they can be null. So the first time you look at these, they might have a null value in them.

    The first thing we need to do is get a reference to the list that contains the field that we want to set these values on.

    // Create the site that contains our list
    SPSite oSite = new SPSite(strSiteUrl);

    // Open the web object
    SPWeb oWeb = spSite.OpenWeb();

    // Get the list that contains the field we want to change the settings on
    SPList oList = oWeb.Lists["Contacts"];

    Now that we have our list, we need to get the field that we want to set the settings on.

    // Get the field that we want to change the settings on
    SPField oField = oList.Fields["Title"];

    Now we can set the properties of our field according to our requirements. There are a couple more properties available in the API than there are in the List Definition schema.

    // Set the field properties
    oField.ShowInDisplayForm = true;     // Determines in this field shows on the display item form.
    oField.ShowInEditForm = false;        // Determines if this field shows on the edit item form.
    oField.ShowInListSettings = true;     // Determines if this field shows on the list settings page.
    oField.ShowInNewForm = true;        // Determines if this field shows on the new item form.
    oField.ShowInVersionHistory = true;// Determines if this field shows on the version history pages.
    oField.ShowInViewForms = true;    // Determines in this field shows on the all view forms pages.

    Now all we have to do is call the update method on the field object to actually update the settings and save the changes back to the database.

    // Update the field
    oField.Update();

    Continue reading if you want to see how to accomplish the same tasks in SWAT (SharePoint Work Acceleration Toolkit). You can find SWAT here http://www.idevfactory.com

    Set Field Settings

    In the Farm Tree window, rick click on the site that you want to set the web parts properties for and click Show Site Details. This will load all the details for that site.

    In the Site Details section, select the Site Lists tab.

    In the Site Lists tab, right click on the list that has the field that you want to set the properties on and click Show List Details.

    On the List Details window, right click on the field that you want to set the properties for and click Show Field Settings.

    On the Field Details window, select the specific settings that you want to change and click Update.

    Enjoy!!!

  • Working With Web Parts Through Code

    This post will show you how to work with web parts through code. Often times there is a need to work with web parts through the API. You can import, export, add remove as well as change settings of web parts.

    Importing and Adding Web Parts.

    The first thing we need to get is out site and web object.

    SPSite oSite = new SPSite("http://yoursiteurl");
    SPWeb oWeb = oSite.OpenWeb();

    The next thing we need to get is the page (file) that we want to import the web part on. For this example we will be working with the default.aspx page on a team site.

    SPFile oFile = oWeb.GetFIle("default.aspx");

    After we have a file object we can get the limited web part manager. The limited web part manager is what we use to do all of our web part operations.

    Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager oWebPartManager = oFile.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    Now we need to create a StringReader class. The constructor we are using takes a string as a parameter. This is simply the xml file of the web part that we want to import. (The web part .dwp or .webpart file).

    System.IO.StringReader oReader = new StringReader(<<web part xml file (.dwp or .webpart file string contents>>);

    Now we need to create a XmlReader and pass in our string reader.

    XmlTextReader oXmlReader = new XmlTextReader(oReader);

    We need to create a string for our output message.

    string strErrorMessage = "";

    No back to our web part manager, we need to import the web part. We simply call the ImportWebPart method on our limited web part manager object. The first parameter is the xml reader we created before and the second parameter is the output message passed back to us as a out parameter. This method will return a WebPart object.

    System.Web.UI.WebControls.WebParts.WebPart oWebPart = spWebPartManager.ImportWebPart(xmlReader, out strErrorMessage);

    No that we have the web part, we can set specific settings that we want to control for our web part. For example, if we don't want the close x to show up on the top right of the web part we could set the AllowHide property of the web part.

    oWebPart.AllowClose = false;

    No that we have actually imported the web part we need to actually add it to the site. We do this by calling the AddWebPart method on the limited web part manager. The first parameter is the web part that we imported in the previous step. The second parameter is the  zone id (as a string) that you want to add the web part to and the third parameter is the zone order (index).

    oWebPartManager.AddWebPart(oWebPart, "left", 1);

    Full code listing.

    // Get the site
    SPSite oSite = new SPSite("http://yoursiteurl");

    // Get the web we are going to import and add the web part to
    SPWeb oWeb = oSite.OpenWeb();

    // Get the file (page) that we want to add the web part to
    SPFile oFile = oWeb.GetFIle("default.aspx");

    // Get the limited web part manager
    Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager oWebPartManager = oFile.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    // Create the string reader for the web part .dwp or .webpart file.
    System.IO.StringReader oReader = new StringReader(<<web part xml file (.dwp or .webpart file string contents>>);

    // Create the xml text reader to read the string into
    XmlTextReader oXmlReader = new XmlTextReader(oReader);

    // Create the error message that will get passed back
    string strErrorMessage = "";

    // Import the web part
    System.Web.UI.WebControls.WebParts.WebPart oWebPart = spWebPartManager.ImportWebPart(xmlReader, out strErrorMessage);

    // Now actually add the web part to the page
    oWebPartManager.AddWebPart(oWebPart, "left", 1);

    NOTE: You can also remove and export web parts through the limited web part manager.

    Continue reading if you want to see how to accomplish the same tasks in SWAT (SharePoint Work Acceleration Toolkit). You can find SWAT here http://www.idevfactory.com

    Set Web Part Properties

    In the Farm Tree window, rick click on the site that you want to set the web parts properties for and click Show Site Details. This will load all the details for that site.

    In the Site Details section, select the Site Pages tab.

    In the Site Pages tab, right click on the page you want to look at the web parts of and click Show Page Web Parts.

    On the Page Web Parts window, right click on the web part that you want to set the settings on and click Web Part Properties.

    On the Web Part Properties window, select the specific properties you wish to set and click Update.

    NOTE: You can also close and open a web part from this screen as well.

    NOTE: Under the Wizards menu of SWAT, there a 3 different wizards dealing with web parts. Add Web Parts, Replicate Web Parts and Delete Web Parts. These wizards allow you to work with many web parts on many different sites all in one action.

    Enjoy!!!

  • Setting Permissions Through Code

    I seam to always get asked this question on every project. This will be a very basic post to show you how to assign permissions through the SharePoint API.

    When working with permissions through the SharePoint API, there are some key objects to take note of.

    • SPUser - A actual security object in SharePoint (AD User, AD Group or Forms Based User or Group).
    • SPGroup - A SharePoint group defined through SharePoint.
    • SPRoleDefinition - A actual role (permission level) defined in SharePoint (Read, Full Control etc...)
    • SPRoleAssignment - The actual assignment between a SPUser/SPGroup and a SPRoleDefinition

    Assign a User to a SharePoint Group

    To assign a user to a SharePoint group we need to get the SPGroup object and add a user with the AddUser method. This method has 2 overloads, the first takes a SPUser object and the second takes some specific parameters (login name, email, name, notes). Below is the code in both formats.

    // ******************** Adding a SPUser to a SharePoint Group ********************
    // Create the site that contains our list
    SPSite oSite = new SPSite("<<my site url>>");

    // Open the web object
    SPWeb oWeb = spSite.OpenWeb();

    // Get the group that we want to add the user to
    SPGroup oGroup = oWeb.Groups["<<group name>>"];

    // Get the user that we want to add to the group
    SPUser oUser = oWeb.AllUsers["domain\login"];

    // Now we add the user to the groups user collection
    oGroup.AddUser(oUser);

    // Update the group
    oGroup.Update();

    // ******************** Adding a User to a SharePoint Group ********************
    // Create the site that contains our list
    SPSite oSite = new SPSite("<<my site url>>");

    // Open the web object
    SPWeb oWeb = spSite.OpenWeb();

    // Get the group that we want to add the user to
    SPGroup oGroup = oWeb.Groups["<<group name>>"];

    // Now we add the user to the groups user collection
    oGroup.AddUser("login", "email", "name", "notes");

    // Update the group
    oGroup.Update();

    Assigning Roles (Permission Levels) to a User or SharePoint Group

    To assign permission to a user (account) or a SharePoint group there are some objects that we need to look at in a certain order. The first thing we need to do is get the the security principal that we want to assign the role to (SPUser or SPGroup). The next thing we need to do it get the actual permission (role) that we want to assign (ex: Read, Full Control etc...). Then we need to create a SPRoleAssignment object and on the constructor pass it in the SPUser or SPGroup (security principal) that we want to assign the permissions to. Now we need to add the role definition to the RoleDefinitionBindings collection of the role assignment object. Then we need to add the actual role assignment to the web (site) and update the web. Below is the full code lisitng.

    // Create the site that contains our list
    SPSite oSite = new SPSite("<<my site url>>");

    // Open the web object
    SPWeb oWeb = oSite.OpenWeb();

    // Get the group that we want to add the user to
    SPGroup oGroup = oWeb.Groups["<<group name>>"];

    // Get the role definition we want to assign ex: Full Control
    SPRoleDefinition oRole = oWeb.RoleDefinitions["<< role name>>"];

    // Create the role assignment object
    SPRoleAssignment oRoleAssignment = new SPRoleAssignment(oGroup);

    // Add the role definition to the role assignemnt.
    // This will assign the specific permission to the security principal for this role assignemnt.
    oRoleAssignment.RoleDefinitionBindings.Add(oRole);

    // Now we need to add the role assignment to the web
    oWeb.RoleAssignments.Add(oRoleAssignment);

    // Now update the web
    oWeb.Update();

    Enjoy!!!

  • Generating Test Data

    Often times there is a need to have some good test data in lists or libraries for development, testing and demos. This post is specific to the SharePoint Work Acceleration Toolkit (SWAT) from iDevFactory. You can find the tool here http://www.idevfactory.com

    SWAT has the capability to generate random child sites as well as documents (and metadata) for document libraries and list items for lists. This post will show you how to generate random documents for a document library.

    In the Farm Tree window, right click on the site that you want to generate the test data on and select Show Site Details.

    In the Site Details section, select the Site Lists tab.

    In the Site Lists tab, right click on the document library that you want to generate test data for and select Generate Test Data

    On the Generate Test Data screen, for the # of Items to Generate enter 500.

    On the Generate Test Data screen, right click on the Title field and select Set Field Parameters.

    On the Field Parameters screen, select Sentence and click Ok. This will generate a sentence instead of a single word for the Title field.

    On the Generate Test Data screen, click Ok. This will kick off the process for generating our test data.

    After the process is done generating our test data, we can navigate to that document libraries page and see the test data that got generated.

    Enjoy!!!

    Posted Sep 27 2007, 07:39 AM by ethan with 4 comment(s)
    Filed under: , ,
  • Create Your Own Data Entry Form Web Part

    There are many scenarios that I always run into on projects or client sites that we need to create our own data entry forms for lists. Microsoft has really done a lot of work around this in exposing the objects that SharePoint uses so we can reuse these and have the same SharePoint look and feel. This post will show you how to build a data entry web part that uses the same objects that SharePoint does.

    There are many discussion on creating web parts and rendering the controls that you create onto web parts. This post will not go into that, but will focus on the objects for a data entry form.

    The control that we are dealing with is in the Microsoft.SharePoint.WebControls namespace. There are a couple things that you would want to determine before you actually create and render the control, like if the field is hidden or read only etc... After we determine if this field should be created and displayed we simply create a control called  FormField. Once we create this control you simply set a couple properties and SharePoint will take care of the rest. The 3 main properties are ControlMode, ListId and FieldName. ControlMode tells the control which mode that this form is in (Display, Edit and New). The ListId tells the control which list on the site to hook to and FieldName tells the control which field that this control is attached to in the list. There is a fourth property to set if we are in Edit or Display mode and that is ItemId. If we set ItemId and are in Edit or Display mode, then SharePoint will automatically set the control value to that specific items value in the list. After we have added all of our fields, we can create a SaveButton control (In the same namespace, Microsoft.SharePoint.WebControls). You would also set the ControlMode and ListId properties on the save button to hook that specific button to the list as well. Once you have done all that, all you would need to do is add the controls created to your web parts collection (or however you render your controls inside a web part). Once you have the controls showing up, you can enter and edit data, click Save and SharePoint will take care of determining which list and item to hook to and actually updating the correct list item with the new values. There is also a property on the SaveButton called RedirectUrl. If you do not set this property, once the user hits Save it will automatically redirect the user back to the default list page. If you choose, you can set this property back to the calling page or a different page of your choice and when the user hits Save, they will be redirected back to that page. So you can build web parts that mimic the SharePoint data entry forms without the user ever having to go to the list itself. The other control we are using is the FieldLabel control. The FieldLabel control will render the actual label for that specific field. Below is the full code listing to render the web part.

    // Create the table object that we are going to add the rows and cells to for our data entry form
    Table oTable = new Table();
    oTable.CellPadding = 0;
    oTable.CellSpacing = 0;

    // Get the site that this web part is running on.
    SPWeb oWeb = Microsoft.SharePoint.WebControls.SPControl.GetContextWeb(Context);

    // Get the list we are going to work with
    SPList oList = oWeb.Lists["Contacts"];

    // Loop through the fields
    foreach (SPField oField in oList.Fields)
    {
        // See if this field is not hidden
        if (!oField.Hidden && !oField.ReadOnlyField && oField.Type != SPFieldType.Attachments)
        {
            // Create the label field
            FieldLabel oLabelField = new FieldLabel();
            oLabelField.ControlMode = SPControlMode.New;
            oLabelField.ListId = oList.ID;
            oLabelField.FieldName = oField.InternalName;

            // Create the form field
            FormField oFormField = new FormField();
            oFormField.ControlMode = SPControlMode.New;
            oFormField.ListId = oList.ID;
            oFormField.FieldName = oField.InternalName;

            // Add the table row
            TableRow oRow = new TableRow();
            oTable.Rows.Add(oRow);

            // Add the cells
            TableCell oCellLabel = new TableCell();
            oRow.Cells.Add(oCellLabel);
            TableCell oCellControl = new TableCell();
            oRow.Cells.Add(oCellControl);

            // Add the control to the table cells
            oCellLabel.Controls.Add(oLabelField);
            oCellControl.Controls.Add(oFormField);
       
            // Set the css class of the cell for the SharePoint styles
            oCellLabel.CssClass = "ms-formlabel";
            oCellControl.CssClass = "ms-formbody";
        }
    }

    // Create the save button
    SaveButton oButtonSave = new SaveButton();
    oButtonSave.ControlMode = SPControlMode.New;
    oButtonSave.ListId = oList.ID;

    // Create the row for the save button
    TableRow oRowButton = new TableRow();
    oTable.Rows.Add(oRowButton);

    // Create the cell for the save button
    TableCell oCellButton = new TableCell();
    oCellButton.ColumnSpan = 2;
    oRowButton.Cells.Add(oCellButton);

    // Add the table to the web part controls collection
    Controls.Add(oTable);

    Following is a screen shot of the web part that was rendered with the above code.

    Enjoy!!!

  • Working With Features Through Code

    This post will show you how to work with features through code. Using the API we can install, uninstall, activate and deactivate features.

    Install a Feature.

    To install a feature we first need to get a reference to our local farm.

    SPFarm oFarm = SPFarm.Local;

    Then all we have to do is add the feature to the FeatureDefinitions collection on the local farm. The first parameter if a relative path to the feature.xml file (relative to the Features directory. ex: MyFeature\feature.xml). The second parameter is the guid of the feature itself. The guid can be parsed from the feature.xml file. Or this can be the solution guid that the feature belongs to. There are 2 overloads to the Add method explained below.

    oFarm.FeatureDefinitions.Add(<<feature definition object>>); (Add the feature based on a SPFeatureDefinition object to add).
    oFarm.FeatureDefinitions.Add(<<feature.xml.>>, <<feature guid>>); (Adds a feature based on the feature.xml file and a solution guid).
    oFarm.FeatureDefinitions.Add(<<feature.xml.>>, <<feature guid>>); (Adds a feature based on the feature.xml file and a solution guid and true to force the reinstall of a feature definition).

    Uninstall a Feature.

    To uninstall a feature we first need to get a reference to our local farm.

    SPFarm oFarm = SPFarm.Local;

    Then all we need to do is remove the feature from the FeatureDefinitions collection on the local farm. There are 4 overloads to the Remove method explained below.

    oFarm.FeatureDefinitions.Remove(<<feature guid>>); (Removes the feature based on a specific feature guid).
    oFarm.FeatureDefinitions.Remove(<<feature.xml>>); (Removes the feature based on a a relative feature.xml file).
    oFarm.FeatureDefinitions.Remove(<<feature guid>>, <<true, false>>); (Removes the feature based on a specific feature guid, true to force the removal of the feature definition).
    oFarm.FeatureDefinitions.Remove(<<feature.xml>>); (Removes the feature based on a a relative feature.xml file, true to force the removal of the feature definition).

    NOTE: The above method will install the feature to the local farm. If the feature is scoped at the farm level it will also activate it at the farm level as well.

    Activate a Feature on a Specific Site

    To activate a feature on a specific site, you need to add it to that site. The first thing we need to do is get a SPSite object and open a SPWeb object

    SPSite oSite = new SPSite("http://mysiteurl");
    SPWeb oWeb = oSite.OpenWeb();

    Now all we need to do is add the feature to the Features collection of that specific site. There are 2 overloads to the Add method explained below.

    oWeb.Features.Add(<<guid>>); (Add the feature with the specific guid.).
    oWeb.Features.Add(<<guid>>, <<true, false>>); (Add the feature with the specific guid, true to overwrite an existing feature with the same guid).

    Deactivate a Feature on a Specific Site

    To deactivate a feature on a specific site, you need to remove it from that specific site. The first thing we need to do is get a SPSite object and open a SPWeb object

    SPSite oSite = new SPSite("http://mysiteurl");
    SPWeb oWeb = oSite.OpenWeb();

    Now all we need to do is remove the feature from the Features collection for that specific site. There are 2 overloads to the Remove method explained below.

    oWeb.Features.Remove(<<guid>>); (Removes the feature with the specific guid.).
    oWeb.Features.Remove(<<guid>>, <<true, false>>); (Removes the feature with the specific guid, true to force the operation event if there are errors).

    NOTE: To activate are deactivate a feature that is scoped at a web application or site collection level, you work with the Features collection on a SPWebApplication object for a web application or a SPSite object for a site collection.

    Continue reading if you want to see how to accomplish the same tasks in SWAT (SharePoint Work Acceleration Toolkit). You can find SWAT here http://www.idevfactory.com

    Install a Feature

    In Features window in SWAT, right click on the feature that you want to install and click Feature Manager.

    On the Feature Manager window, click Install Feature. This will install the feature into your farm.

    Uninstall a Feature.

    In Features window in SWAT, right click on the feature that you want to install and click Feature Manager.

    On the Feature Manager window, click UnInstall Feature. This will uninstall the feature into your farm.

    Activate a Feature on a Specific Site

    In the Farm Tree window, rick click on the site that you want to activate the feature on and click Show Site Details. This will load all the details for that site.

    In the Site Details are, select the Site Features tab. This will show you all the features for that site that are activated and deactivated.

    In the Site Features section, right click on the feature that you want to activate and click Activate Feature. This will activate that feature on that specific site.

    Deactivate a Feature on a Specific Site

    In the Farm Tree window, rick click on the site that you want to activate the feature on and click Show Site Details. This will load all the details for that site.

    In the Site Details are, select the Site Features tab. This will show you all the features for that site that are activated and deactivated.

    In the Site Features section, right click on the feature that you want to deactivate and click Deactivate Feature. This will deactivate that feature on that specific site.

    Activate a Web Scoped Feature on many Sites at once.

    SWAT has a lot of wizards built into it to accomplish many routine tasks. On the Wizards menu select Activate Features. This will launch the Activate Features wizard which will guide you through the steps.

    On Step 1, select the sites that you want to activate the features on and click next.

    On Step 2, select the features that you wish to activate.

    On Step 3, click finish. This will activate all the features on the sites that you selected.

    Enjoy!!!

  • Working With Solutions Through Code

    This post will show you how to install and deploy solutions with code. The API is very rich in its objects and makes the solution framework available to install and deploy solutions in code. You can also see what servers and web applications that a solutions has been deployed to.

    The first thing we do is get a reference to our local farm.

    SPFarm oFarm = SPFarm.Local;

    The next thing we do is actually add the solution to the local farm.

    Replace the C:\MySolutionFile.wsp with the full path to your solution file.

    SPSolution oSolution = oFarm.Solutions.Add(@"C:\MySolutionFile.wsp");

    The next thing we need to do is tell SharePoint to go ahead and provision the solution. This will let SharePoint go through its provisioning process for the added solution.

    oSolution.Provision();

    Now we can actually deploy the solution. We can deploy the solution to the local farm globally, meaning all the web applications, or we can deploy the solution to specific web applications. The method DeployLocal has 2 different calling options. One to take a couple boolean paramaters and second to take the boolean parameters as well as a Collection of SPWebApplication object. This will tell SharePoint what web application to actually deploy the solution to.

    This code will deploy the solution locally to all web applications in the farm. The first parameter tells SharePoint to install the web part packages and the second tells SharePoint to force the deployment if the same solution already exists.

    oSolution.DeployLocal(true, true);

    This code will deploy the solution to specific web applications. The first parameter tells SharePoint to install the web part packages, the second is a collection of all the SPWebApplication objects that you wish to deploy the solution to and the third tells SharePoint to force the deployment if the same solution already exists

    oSolution.DeployLocal(true, <<Collection of SPWebApplication objects>>, true);

    Now that you have deployed your solutions, you can look at specific properties on the SPSolution object and tell what servers the solution is deployed to as well as what web application the solution is deployed to.

    To look at what servers a solution is deployed to, you look through the DeployedServers property on the solution object. This is just a collection of SPServer objects.

    foreach (SPServer oServer in oSolution.DeployedServers)
    {
        // Do your processing of each server object
    }

    To look at what web applications a solution is deployed to, you look through the DeployedWebApplications property on the solution object. This is just a collection of SPWebApplication objects.

    foreach (SPWebApplication spWebApplication in CurrentSolution.DeployedWebApplications)
    {
        // Do your processing of each web application object
    }

    Here at iDevFactory we have also been getting alot of request on how you do certain tasks in our SharePoint Work Acceleration Toolkit. For those of you interested in how to accomplish the same tasks above in SWAT read on.

    In SWAT there is a Solutions window. This shows you all the solutions that are installed in your farm.

    In the solutions window, you can click the add button to bring up the Add Solution window.

    On the Add Solution window, click the Select Solution button and browse to your solution file.

    On the Add Solution window, after you have selected your solution file to add, you can select specific web applications to deploy the solution to as well as deploying the solution locally. After you have made your specific selected, click the Add button to add the solution to your SharePoint farm.

    Back at the Solutions window, you can right click on a specific solution and select Solution Manager.

    On the Solution Manager window, the Detail tab will show you specific details about your solution General Information, Solution Information, Deployment Information and Job Information.

    On the Solution Manager window, the Servers tab will show you all the servers that this solution is deployed to.

    On the Solution Manager window, the Web Applications tab will show you all the web application that this solution is deployed to. You can also deploy to other web applications as well as retract from deployed web applications.

    Enjoy!!!

  • Inspecting The SharePoint Content Database

    Inspecting The SharePoint Content Database

    This is going to be the first post on a many to come about the SharePoint Content Database. There are some cases when we need to look into and read from the content databases.

    NOTE: Never update any SharePoint database directly. Always use the SharePoint API (Object Model) for any updates.

    We will begin with some of the basic tables and a very high level diagram on some of the relationships between them.

    Features Table that holds information about all the activated features for each site collection or site.
    Sites Table that holds information about all the site collections for this content database.
    Webs Table that holds information about all the specific sites (webs) in each site collection.
    UserInfo Table that holds information about all the users for each site collection.
    Groups Table that holds information about all the SharePoint groups in each site collection.
    Roles Table that holds information about all the SharePoint roles (permission levels) for each site.
    AllLists Table that holds information about lists for each site.
    GroupMembership Table that holds information about all the SharePoint group members.
    AllUserData Table that holds information about all the list items for each list.
    AllDocs Table that holds information about all the documents (and all list items) for each document library and list.
    RoleAssignment Table that holds information about all the users or SharePoint groups that are assigned to roles.
    SchedSubscriptions Table that holds information about all the scheduled subscriptions (alerts) for each user.
    ImmedSubscriptions Table that holds information about all the immediate subscriptions (alerts) for each user.

    Below is a very high level database diagram. This does not show all the relationships between all the tables.

    There are a some tables left out of this post that we will look at in upcoming posts. Here are some common queries that we can run against the content databases.

    -- Query to get all the top level site collections
    SELECT SiteId AS SiteGuid, Id AS WebGuid, FullUrl AS Url, Title, Author, TimeCreated
    FROM dbo.Webs
    WHERE (ParentWebId IS NULL)

    -- Query to get all the child sites in a site collection
    SELECT SiteId AS SiteGuid, Id AS WebGuid, FullUrl AS Url, Title, Author, TimeCreated
    FROM dbo.Webs
    WHERE (NOT (ParentWebId IS NULL))

    -- Query to get all the SharePoint groups in a site collection
    SELECT dbo.Webs.SiteId, dbo.Webs.Id, dbo.Webs.FullUrl, dbo.Webs.Title, dbo.Groups.ID AS Expr1,
    dbo.Groups.Title AS Expr2, dbo.Groups.Description
    FROM dbo.Groups INNER JOIN
    dbo.Webs ON dbo.Groups.SiteId = dbo.Webs.SiteId

    -- Query to get all the users in a site collection
    SELECT dbo.Webs.SiteId, dbo.Webs.Id, dbo.Webs.FullUrl, dbo.Webs.Title, dbo.UserInfo.tp_ID,
    dbo.UserInfo.tp_DomainGroup, dbo.UserInfo.tp_SiteAdmin, dbo.UserInfo.tp_Title, dbo.UserInfo.tp_Email
    FROM dbo.UserInfo INNER JOIN
    dbo.Webs ON dbo.UserInfo.tp_SiteID = dbo.Webs.SiteId

    -- Query to get all the members of the SharePoint Groups
    SELECT dbo.Groups.ID, dbo.Groups.Title, dbo.UserInfo.tp_Title, dbo.UserInfo.tp_Login
    FROM dbo.GroupMembership INNER JOIN
    dbo.Groups ON dbo.GroupMembership.SiteId = dbo.Groups.SiteId INNER JOIN
    dbo.UserInfo ON dbo.GroupMembership.MemberId = dbo.UserInfo.tp_ID

    -- Query to get all the sites where a specific feature is activated
    SELECT dbo.Webs.Id AS WebGuid, dbo.Webs.Title AS WebTitle, dbo.Webs.FullUrl AS WebUrl, dbo.Features.FeatureId,
    dbo.Features.TimeActivated
    FROM dbo.Features INNER JOIN
    dbo.Webs ON dbo.Features.SiteId = dbo.Webs.SiteId AND dbo.Features.WebId = dbo.Webs.Id
    WHERE (dbo.Features.FeatureId = '00BFEA71-D1CE-42de-9C63-A44004CE0104')

    -- Query to get all the users assigned to roles
    SELECT dbo.Webs.Id, dbo.Webs.Title, dbo.Webs.FullUrl, dbo.Roles.RoleId, dbo.Roles.Title AS RoleTitle,
    dbo.UserInfo.tp_Title, dbo.UserInfo.tp_Login
    FROM dbo.RoleAssignment INNER JOIN
    dbo.Roles ON dbo.RoleAssignment.SiteId = dbo.Roles.SiteId AND
    dbo.RoleAssignment.RoleId = dbo.Roles.RoleId INNER JOIN
    dbo.Webs ON dbo.Roles.SiteId = dbo.Webs.SiteId AND dbo.Roles.WebId = dbo.Webs.Id INNER JOIN
    dbo.UserInfo ON dbo.RoleAssignment.PrincipalId = dbo.UserInfo.tp_ID

    -- Query to get all the SharePoint groups assigned to roles
    SELECT dbo.Webs.Id, dbo.Webs.Title, dbo.Webs.FullUrl, dbo.Roles.RoleId, dbo.Roles.Title AS RoleTitle,
    dbo.Groups.Title AS GroupName
    FROM dbo.RoleAssignment INNER JOIN
    dbo.Roles ON dbo.RoleAssignment.SiteId = dbo.Roles.SiteId AND
    dbo.RoleAssignment.RoleId = dbo.Roles.RoleId INNER JOIN
    dbo.Webs ON dbo.Roles.SiteId = dbo.Webs.SiteId AND dbo.Roles.WebId = dbo.Webs.Id INNER JOIN
    dbo.Groups ON dbo.RoleAssignment.SiteId = dbo.Groups.SiteId AND
    dbo.RoleAssignment.PrincipalId = dbo.Groups.ID

    These are just some of the common queries that I have used against the content database. In upcoming post I will exam how the permissions are scoped and how we can determine where the permissions are assigned by looking further into the content database. I will also show you how you can look into the content database and see where all the event handlers are being used and what they are attached to.

    Enjoy!!!

  • Inspecting Policies for a Web Application

    MOSS 2007 has a new feature called Web Application Policies. These are security permissions that is tied to a Web Application. These security settings override any security setting that is set at the Site Collection or Site (Web) level for that user. This post will show you how to get all the policies for a Web Application and see what kind of rights they are.

    On the SPWebApplication object there is a property called Policies. This property is a SPPolicyCollection that contains SPPolicy objects. The UserName property contains the name of the AD user or group that this policy belongs to. Because a policy can actually have a Grant and Deny permisions assigned to it, there is a property called PolicyRoleBindings that contain all the permission bindings for this property. we can simply loop through the role bindings and inspect them to see what kind of bindings they are. Below is a utility method that will inspect the policies for a Web Application passed in.

    private void InspectPolcies(SPWebApplication oWebApplication)
    {
        // Loop through the web application policies
        foreach (SPPolicy oPolicy in oWebApplication.Policies)
        {
            // The user name of the policy we are looking at
            string strUserName = oPolicy.UserName;

            // Loop through the policy role bindings for this policy
            foreach (SPPolicyRole oPolicyRole in oPolicy.PolicyRoleBindings)
            {
                // See if the grant policy is NOT empty
                if (oPolicyRole.GrantRightsMask != SPBasePermissions.EmptyMask)
                {
                    // Put your grant policy processing code here...
                }

                // See if we have a deny policy
                if (oPolicyRole.DenyRightsMask != SPBasePermissions.EmptyMask)
                {
                    // Put your deny policy processing code here...
                }
            }
        }
    }

    Enjoy!!!

  • How to Auto Detect Your SharePoint Environment

    This post will show you how to auto detect your Web Applications and Site Collections using the object model. In SPS2003 there was a SPGlobalAdmin object in the Microsoft.SharePoint.Administration namespace. That has been depracted, in MOSS 2007 we have a new object called SPFarm in the same namespace (Microsoft.SharePoint.Administration).

    To auto detect your SharePoint environment, the first thing we do is get a reference to the local farm using the static variables Local on the SPFarm object.

    SPFarm oFarm = SPFarm.Local;

    NOTE: There is also a static method on the SPFarm object called Open that takes a database connection string. This can be a connection string to a configuration database for a different farm. I have actually used this before so the farm that this code is running on can connect to other SharePoint farms. There are some security considerations there, but Microsoft has put the hooks in for one farm to connect to another.

    Now that we have a reference to the local farm, we can start to auto detect the objects in our farm.There is a collection property on the farm object called Services. This property is a SPServiceCollection which contains SPService objects. We simply loop through the services in our farm. When we loop through our services we check to see if the SPService object is a SPWebService object. If it is then we cast into a SPWebService object which contains a collection of Web Applications. You can now loop through each of the Web Applications of the Web Service object. The SPWebApplication object has a property called Sites that contain all the site collection belonging to the Web Application. Once you have the SPSite object you can get the root web (SPWeb) object from the property RootWeb. From there you can loop through the child webs or do whatever processing you need to do. Below is the full code.

    // Get a reference to the local farm
    SPFarm oFarm = SPFarm.Local;


    // Loop through the services in the farm 
    foreach (SPService oService in oFarm.Services)
    {
        // See if this service is a SPWebService
        if (oService is SPWebService)
        {
            // Cast into a SPWebService
            SPWebService oWebService = (SPWebService)oService ;

            // Loop through the web applications in the web service
            foreach (SPWebApplication oWebApplication in oWebService.WebApplications)
            {
                // Loop through the site collections
                foreach (SPSite oSite in oWebApplication.Sites)
                {
                    // Get the root web object
                    SPWeb oWebRoot = oSite.RootWeb;

                    // Put your processing code here......

                    // Be sure to dispose the SPSite and SPWeb objects for memory cleanup
                    oWeb.Dispose();
                    oSite.Dispose();
                }
            }
        }
    }

    NOTE: After you open and use a SPSite and/or SPWeb objects you MUST be sure to dispose them for cleanup. If you do not then you could get nasty memory leaks in your runtime library.

    Enjoy!!!

  • Introduction

    Hi all and I hope you find this blog useful. I have been doing SharePoint consulting for over 5 years. I have referred to blogs on a regular bases and am very excited about giving back to the SharePoint community. In doing SharePoint consulting for all these years, I have developed a very rich toolbox for development and consulting. In doing this I am also one of the founders of a SharePoint product company called iDevFactory. We have just released a new product called SWAT (SharePoint Work Acceleration Toolkit). Through this blog I will begin to do a series of posts on the SharePoint API and how we did some of the features that this tool has to offer. We also have a Enterprise Security Management and Reporting product called USPM (Universal SharePoint Manager). In doing this product we have done A LOT of database discovery that I will also be exposing in upcoming posts. I hope you all find this useful and I welcome your feedback.


Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts