Creating Folders/Users/Permissions Programtically

Set of code to do some cool things programatically…

 

SPSite site = new SPSite("http://sharepoint2007:100");
            site.AllowUnsafeUpdates = true;
            SPWeb web = site.RootWeb;
            web.AllowUnsafeUpdates = true;

            SPListTemplateCollection coll = web.ListTemplates;
            SPList newList = null;

            //create a list
            try
            {
                newList = web.Lists[web.Lists.Add("Assignments", "Student Assignments", coll[1])];
            }
            catch (Exception ex)
            {
                newList = web.Lists["Assignments"];
            }

            string[] users = {"training\administrator","training\student"};

            //iterate all the users (from database?)
            foreach (string s_user in users)
            {
                //add to site
                SPUser user = web.EnsureUser(s_user);                                                              
                string name = s_user;

                if ( user.LoginName.Contains("\"))
                    name = user.LoginName.Substring(user.LoginName.IndexOf("\") + 1);

                //create a folder for each user
                SPListItem folder = newList.Items.Add("", SPFileSystemObjectType.Folder,name);
                try
                {
                    folder.Update();
                    newList.Update();
                }
                catch (Exception ex)
                {                    
                }

                //set permissions            
                SPRoleDefinition RoleDefinitionRdr = web.RoleDefinitions.GetByType(SPRoleType.Administrator);
                SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)user);
                roleAssignment.RoleDefinitionBindings.Add(RoleDefinitionRdr);

                //adds permissions to site
                web.RoleAssignments.Add(roleAssignment);

                if (!folder.HasUniqueRoleAssignments)
                {
                    folder.BreakRoleInheritance(false);
                }

                while (folder.RoleAssignments.Count > 0)
                    folder.RoleAssignments.Remove(0);

                folder.RoleAssignments.Add(roleAssignment);
                folder.Update();
            }

Powershell script to create Active Directory user Profiles and MySites

This is awesome…check it out!  A powershell script that will create a profile for every AD user, then creates there My Site!

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

$dom = "LDAP://CN=Users;DC=training;DC=corp"
$root = new-object DirectoryServices.DirectoryEntry $dom

$selector = new-object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root

$adobj = $selector.findall() | where {$_.properties.objectcategory -match "CN=Person"}
$spsite = new-object Microsoft.SharePoint.SPSite("http://sharepoint2007:100")
$context = [Microsoft.Office.Server.ServerContext]::GetContext($spsite)
$pmanager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

ForEach ($person in $adobj)
{
$prop = $person.properties
$prop.cn

$exists = $pmanager.UserExists($prop.cn)

if ($exists -eq $false)
{
$pmanager.CreateUserProfile($prop.cn)
}

$up = $pmanager.GetUserProfile($prop.cn)
$up.CreatePersonalSite()

}

 

Powershell script to backup My Sites!

This one rocks too!

 $ssppath = "http://sharepoint2007:100/personals"

$out = stsadm -o enumsites -url $ssppath
$out = [xml] $out

ForEach ($web in $out.Sites.Site )
{
$url = $web.url

$name = "c:" + $url.SubString($url.LastIndexOf("/")+1).replace(":","") + ".bak"

write-host "stsadm -o backup -url $url -filename $name -overwrite"
stsadm -o backup -url $url -filename $name -overwrite

}

Most Commonly Missed Best Practice with Internet Sites

Wanna know what it is?  It is a disaster waiting to happen!  

Some day an IIS 6.0 vulnerability will come out that allows you to get administrator access to the _vti_bin directory of your SharePoint site.  You will then be able to execute a call to the Lists web service and delete the "Pages" document library!  

To prove it, do a search on Pages/default.aspx in google.  You will get a listing on all the sites on the internet that are running sharepoint as their internet site.  Check their _vti_bin directory access by appending /_vti_bin/lists.asmx

 If you get the web service page for the list service, that company has setup there site WRONG!

The correct way of doing things is to create an extended web application that HAS the _vti_bin and the original with the _vti_bin DELETED!  The original is the internet accessable one and the extended one is accessible only by internal staff (so you can use SharePoint Designer and such).

Anyone feel like writing a vulnerability and the code to delete all the pages  document libraries on the internet to prove my point???  Couldn't be too hard 🙂

CJG

Windows Workflow Foundation Course

Oh yeah, I'm writing it.  And I'll tell you…it's going to be awesome!  I'll post the outline later, but so far, it's looking really good! 

I'll also be posting a Powershell script to backup "My Sites" in the next couple of days!  I would have done it today, but I have had the flu!  Yuk!  Just now getting over it!

Hope everyone is doing great!
Chris

The CJG Office 2007 Object Model

I have been doing alot with Office 2007 documents.  Specifically PowerPoint and Word, basically I am dynamically generating them for all kinds of applications!  Using my Database class builder tool, I have generated an object model around the Office XML schema!

I will be releasing this later in March anyway, so figure I would post about it now!  Maybe some of you will find it helpful!

Chris

 Here's a code example:

 wp p = new wp();
            p.PId = null;
            p.RsidP = null;
            p.RsidR = null;
            p.RsidRDefault = null;
            p.RsidRPr = null;
            p.WsmartTags = null;

            wr r = new wr();
            r.RId = null;
            r.RsidR = null;
            r.RsidRPr = null;
            wbr br = new wbr();
            br.Type = "page";
            r.Wbr = br;
            p.Wrs.Add(r);

Invalid characters for SharePoint titles

This deserves lots of reposting!  Today a student had an issue with the JavaScript not working on a list!  Seems that several different chars will cause SharePoint to fail in soo many different ways!  Check out this Microsoft knowledge base!

 http://support.microsoft.com/default.aspx?scid=kb;en-us;905231

 Yikes!   Three cheers for validation!

 

 

The Only Thing You Can’t Do With the SharePoint Object Model

Can you guess what item I found that you can't do with the SharePoint Object Model?  I have been through the entire API from top to bottom and there seems to be one thing missing!

 A way to add authoratative URLs to your SSP Search Configuration!  In my latest course, SharePoint Search Administration, you explore the Search API looking to perform every task that is available through the web UI.  I was successful in doing everything but add those nice relevance algorithm changes authoritative URLs

 If you have successfully done this, ping me back!  Otherwise, I have to think that it was the ONE AND ONLY THING that got left out of the Object Model (oh, let's not talk about the web services interfaces shall we…).

Create a BDC Application Definition for a Web Service

In working with a large Canadian Law firm this week, I built this lab to help them learn to build Web Services that cater to BDC Web Service Application Definition files.  Pretty neat stuff…keep in mind that you have  to setup the BDC Editor before performing these steps.

Exercise 1 – Create a BDC App Def File (Web Service)

Purpose:
        Create
a BDC Application Definition File with the Microsoft BDC tool.  Note that this tool is a basic editor, it
doesn’t implement any advanced functionality. 
To do advanced things, you will need to reference the schema file and
build your own xml.

Result:           
An Application Definition File

Task 1 –Create a Web
Service

  1. In Visual Studio, create a
    new web service project
    • Click
      “File->New->Web Site”
    • Select “ASP.NET Web
      Service”
    • For location, type
      “D:lab workBDCWebService”
    • Click “Ok”

Task 2 –Create a
return class

  1. Create a new class to act as
    our return type
    • Right click the
      project, select “Add New Item”
    • Select “Class”
    • For name, type
      “Product.cs”
    • Click “Add”
  2. Click “Yes” to the “App_Code”
    directory
  3. Add the following variable to
    the class (copy under the “public class Product” line):



protected int m_ProductID;

    protected
string m_ProductName;

    protected
int m_SupplierID;

    protected
int m_CategoryID;

    protected
string m_QuantityPerUnit;

    protected
double m_UnitPrice;

    protected
short m_UnitsInStock;

    protected
short m_UnitsOnOrder;

    protected
short m_ReorderLevel;

    protected
bool m_Discontinued;

 

  1. Add the following properties
    to the class:


public int ProductID

    {

        get {
return (m_ProductID); }

        set {
m_ProductID = value; }

    }

    public
string ProductName

    {

        get {
return (m_ProductName); }

        set {
m_ProductName = value; }

    }

    public int
SupplierID

    {

        get {
return (m_SupplierID); }

        set {
m_SupplierID = value; }

    }

    public int
CategoryID

    {

        get {
return (m_CategoryID); }

        set {
m_CategoryID = value; }

    }

    public
string QuantityPerUnit

    {

        get {
return (m_QuantityPerUnit); }

        set {
m_QuantityPerUnit = value; }

    }

    public
double UnitPrice

    {

        get {
return (m_UnitPrice); }

        set {
m_UnitPrice = value; }

    }

    public
short UnitsInStock

    {

        get {
return (m_UnitsInStock); }

        set { m_UnitsInStock
= value; }

    }

    public
short UnitsOnOrder

    {

        get {
return (m_UnitsOnOrder); }

        set {
m_UnitsOnOrder = value; }

    }

    public
short ReorderLevel

    {

        get {
return (m_ReorderLevel); }

        set {
m_ReorderLevel = value; }

    }

    public bool
Discontinued

    {

        get {
return (m_Discontinued); }

        set {
m_Discontinued = value; }

    }

 

 

  1. Add the following methods to
    the class:



public Product(IDataRecord record)

    {

       
this.Fill(record);

    }

 

    internal
void Fill(IDataRecord record)

    {

       
m_ProductID = (int)record["ProductID"];

       
m_ProductName = (string)record["ProductName"];

 

        if
(record["SupplierID"] != DBNull.Value)

        {

            m_SupplierID =
(int)record["SupplierID"];

        }

        if
(record["CategoryID"] != DBNull.Value)

        {

           
m_CategoryID = (int)record["CategoryID"];

        }

        if
(record["QuantityPerUnit"] != DBNull.Value)

        {

            m_QuantityPerUnit
= (string)record["QuantityPerUnit"];

        }

        if
(record["UnitPrice"] != DBNull.Value)

        {

           
m_UnitPrice = Convert.ToDouble(record["UnitPrice"]);

        }

        if
(record["UnitsInStock"] != DBNull.Value)

        {

           
m_UnitsInStock = Convert.ToInt16(record["UnitsInStock"]);

        }

        if
(record["UnitsOnOrder"] != DBNull.Value)

        {

           
m_UnitsOnOrder = Convert.ToInt16(record["UnitsOnOrder"]);

        }

        if
(record["ReorderLevel"] != DBNull.Value)

        {

           
m_ReorderLevel = Convert.ToInt16(record["ReorderLevel"]);

        }

       
m_Discontinued = (bool)record["Discontinued"];

 

    }

 

  1. Add the following attribute
    to the class:



[Serializable]

 

  1. Compile the project, fix any
    errors

Task 3 –Implement the
web methods

  1. Open the Service.cs file
  2. Add the following using
    statements to the file:


using System.Data;

using System.Data.SqlClient;

using System.Collections.Generic;

using System.ComponentModel;

using Microsoft.ApplicationBlocks.Data;

using System.Configuration;

 

  1. Add a property to get a
    connection string from the configuration file:


private string ConnectionString

    {

        get

        {

           
AppSettingsReader reader = new AppSettingsReader();

           
return (string)reader.GetValue("ConnectionString",
typeof(string));

        }

    }

 

  1. Open the web.config file
  2. Add the following line to the
    <Configuraton><appSettings> element:


    <add
key="ConnectionString"
value="server=.;database=northwind;uid=sa;pwd=Pa$$w0rd"/>

 

  1. Save the file
  2. Add a method to get a list of
    ids:



[WebMethod(Description = "Returns a List of
Products IDs")]

    public
List<int> GetProductEnumeratorIDs()

    {

       
List<int> retVal = new List<int>();

 

        string
sql = "SELECT [ProductID] FROM [Products]";

 

       
SqlDataReader reader = null;

 

        try

        {

 

           
reader = SqlHelper.ExecuteReader(this.ConnectionString,
CommandType.Text, sql);

 

            if
(reader.HasRows)

            {

 

               
while (reader.Read())

               
{

                   
retVal.Add(reader.GetInt32(0));

                }

 

            }

 

        }

        catch

        {

           
throw;

        }

        finally

        {

            if
(reader != null && !reader.IsClosed)

            {

               
reader.Close();

            }

        }

 

        return
retVal;

    }

 

  1. Add a method to get a single
    Product from the database by ProductId:


[WebMethod(Description = "Returns a single Product Entity by ID")]

    public
Product GetProduct(int productID)

    {

        string
sql = "SELECT [ProductID], [ProductName], [SupplierID], [CategoryID],
[QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder],
[ReorderLevel], [Discontinued] FROM [Products] WHERE [ProductID] =
@ProductID";

 

       
SqlDataReader reader = null;

 

        try

        {

 

           
reader = SqlHelper.ExecuteReader(this.ConnectionString,

                            CommandType.Text,
sql,

                            new
SqlParameter[] {

                                                    new SqlParameter("@ProductID",
productID) });

 

            if
(reader.HasRows)

            {

               
reader.Read();

               
return new Product(reader);

 

            }

 

        }

        catch

        {

           
throw;

        }

        finally

        {

            if
(reader != null && !reader.IsClosed)

            {

               
reader.Close();

            }

        }

 

        return
null;

    }

 

  1. Add a method to get a single
    Product from the database by ProductName:



[WebMethod(Description = "Returns a List of
Products Filtered By Name")]

    public
List<Product> GetProductsByName(string productName)

    {

       
List<Product> retVal = new List<Product>();

 

        string
sql = "SELECT [ProductID], [ProductName], [SupplierID], [CategoryID],
[QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel],
[Discontinued] FROM [Products] WHERE [ProductName] Like @ProductName";

 

       
SqlDataReader reader = null;

 

        try

        {

 

           
reader = SqlHelper.ExecuteReader(this.ConnectionString,

                            CommandType.Text,
sql,

                            new
SqlParameter[] {

                                                    new
SqlParameter("@ProductName", string.Format("%{0}%",
productName)) });

 

            if
(reader.HasRows)

            {

 

               
while (reader.Read())

               
{

                   
retVal.Add(new Product(reader));

               
}

 

            }

 

        }

        catch

        {

           
throw;

        }

        finally

        {

            if
(reader != null && !reader.IsClosed)

            {

               
reader.Close();

            }

        }

 

        return
retVal;

    }

  1. Add a method to get all the
    Products from the database:


[WebMethod(Description = "Returns a List of Products")]

    public
List<Product> GetProducts()

    {

       
List<Product> retVal = new List<Product>();

 

        string
sql = "SELECT [ProductID], [ProductName], [SupplierID], [CategoryID],
[QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder],
[ReorderLevel], [Discontinued] FROM [Products]";

 

       
SqlDataReader reader = null;

 

        try

        {

 

           
reader = SqlHelper.ExecuteReader(this.ConnectionString,

                            CommandType.Text,
sql);

 

            if
(reader.HasRows)

            {

 

               
while (reader.Read())

               
{

                   
retVal.Add(new Product(reader));

               
}

 

            }

 

        }

        catch

        {

           
throw;

        }

        finally

        {

            if
(reader != null && !reader.IsClosed)

            {

               
reader.Close();

            }

        }

 

        return
retVal;

    }

 

  1. Add a helper class called
    SqlHelper:
    • Right click the
      project, select “Add New Item”
    • Select “Class”
    • For name, type
      “SqlHelper”
    • Click “Add”
  2. Paste the code in the 07_Lab07.extra.txt
    code snippet file into the file
  3. Compile the project, fix any
    errors
  4. Set the web service port to
    200
    • Click the project in
      the solution explorer
    • In the “Properties”
      window, set Dynamic Ports to “false”
    • Set the Port number to
      “2000”
  5. Run the web service, press F5
  6. Click “Ok” to create the
    web.config file
  7. You should see your web
    service running on port 2000


Task 4 –Create a BDC
Application Definition file

  1. Click “Start->All
    Programs->Microsoft Business Data Catalog Definition Editor”
  2. The BDC editor will start:


  1. Click “Add LOB System”
  2. Click “Connect to Web Service”
  3. Type the URL of the web
    service “http://localhost:2000/BDCWebService/Service.asmx”
  4. Click “Connect”
  5. Click “Add Web Method” (on
    the right side)
  6. Drag all the methods to the design surface (make sure they are all
    added to the same Entity)!
    • GetProductEnumeratorIDs
    • GetProduct
    • GetProductsByName
    • GetProducts


  1. Click “Ok”
  2. For the name, type “Products”
  3. Click “Ok”
  4. Note how our Instances and
    Entities are populated


  1. Also note how the
    Identifiers, Methods and Actions are populated
  2. Right Click on any node,
    notice how you get the ability to add a new item that is appropriate for
    whatever level you are on in the tree view


  1. Select the “Enitiy1” node
  2. In the Property editor,
    change the name to “Products”


  1. Expand the
    Products->Methods->GetProductByName->Parameters->Return->Return->Item
    nodes


  1. You will see the properties
    of the Product class exposed as fields that will be returned in your BDC
    Application!
  2. Right click “Identifier”,
    select “Add Identifier”
    • For Name, type
      “ProductId”
    • For the Type, select
      “System.Int32”
  3. Setup an Enumerator method
    • Expand GetProductEnumeratorIDs
    • Right click
      “Instances”, select “Add Method Instance”
    • Click the “Id
      Enumerator” method type
    • For the name, type
      “EnumId”
    • Click “Ok”
  4. Setup a SpecificFinder method
    • Expand GetProduct
    • Right click “Filters”,
      select “Add Filter”
    • For FilterType, select
      “Equals”
    • For Name, type
      “ProductId”
    • Expand
      “Parameters->Return->Return”
    • Select “ProductID”
    • Set the Identifier to
      “ProductId[Product]”
    • Right click
      “Instances”, select “Add Method Instance”
    • Click the “SpecificFinder”
      method type
    • For the name, type
      “ProductSpecificFinder”
    • Click “Ok”
  5. Setup a Finder method
    • Expand GetProducts
    • Expand
      “Parameters->Return->Return->Item”
    • Select “ProductID”
    • Set the Identifier to
      “ProductId[Product]”
    • Right click
      “Instances”, select “Add Method Instance”
    • Click the “Finder”
      method type
    • For the name, type
      “ProductFinder”
    • Click “Ok”
  6. Right click the “Products”
    LobSystem and select “Export”


  1. Save to your desktop as Lists.xml
  2. Open the file, review its
    contents

Task 5 –Upload your
new BDC Application

  1. Open the Central
    Administration site
  2. Click “SharedServices1”
  3. Click “Import Application
    Definition”
  4. Select your “products.xml”
    file
  5. Click “Import”

Task 7 –Create BDC
Web Part

  1. Open your team site
  2. Click “Site Actions->Edit
    Page”
  3. Select the “Business Data
    List” web part
  4. Click “Add”
  5. Click “Open the tool pane”
    link
  6. For Type, click the browse
    button
  7. Select the “Products”
    business Data Type
  8. Click “Ok”
  9. Click “Ok”
  10. You should see a listing of
    all the products from the web service!