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!

 

Use InfoPath to create your BDC Application Definitions

I found the ability to point InfoPath at XSD's useful in working with the BDC xsd and building application definitions.  Check it out, think about your other XSDs and how you might create forms around them!

 

Exercise 3 – Create An InfoPath Form (Xml)

Purpose:
        Learn
to create an InfoPath Form from an Xml document!

Result:           
An InfoPath Form

Task 1 – Create A Xml
Based Form

  1. Open InfoPath 2007 (if open,
    click “File->Design a Form Template”)
  2. Click “Design A Form
    Template”
  3. Select the “Xml or Schema”
    icon
  4. Click the “Enable
    browser-compatible features only”

  1. Click “Ok”
  2. Browse to the “C:Program
    FilesMicrosoft Office Servers12.0Bindcmetadata.xsd” file
  3. Click “Open”
  4. Click “Next”
  5. Click “Finish”
  6. From the Data Source view, drag
    the “LobSystem” node to the work area
  7. Select “Section with
    Controls”

  1. Click “Preview”
  2. Notice how you can now create
    a BDC application definition file using InfoPath!

  1. Close the preview
  2. Save the template as “MyXsdForm”

 

Building Custom SharePoint 2007 Document Converters

Module #09: Custom
Document Converter Lab #
02
(Optional)

 

 

Course:           Programming
Microsoft Office SharePoint Server

Estimated Time to Complete:  45 minutes

Objectives:

·        
Create/Deploy a
Custom Converter

Operating
Notes:
 

 

·        
Document Converters do not run on Domain Controllers!
Therefore, you will be able to create and install the converter, but not test
it with this image

Deliverables:

·        
None

 

Overview:         Learn
to create your own Document Converter

Exercise 1 – Create the Converter

Purpose:
        Create
a converter to transform a document

Result:           
A document converter

Task 1 – Create a Console
Application

  1. Open Visual Studio
  2. Create a new project
    • Click “File->New->Project”
    • Select “Console
      Application”
    • For name, type “MyConverter”
    • For location, type “D:Lab
      Work”

    • Click “Ok”
  1. Add a reference to
    WindowsBase
    • Right click the
      project, select “Add reference”
    • On the .NET tab,
      select “WindowsBase”
    • Click “Ok”

Task 2 – Update the
code

  1. Update the program.cs file to
    the following:


using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.IO.Packaging;

using System.Xml;

 

namespace MyConverter

{

    class
ConverterShell

    {

        #region
Private Members

 

        private
string[] inputArgs = null;

        private
string localPathtoFile = null;

        private
string localSettings = null;

        private
string localLogPath = null;

        private
string localOutputFullPath = null;

        private
const string ConverterName = "Xml to Xml";

        private
const string InputExtension = ".xml";

        private
const string OutputExtension = ".xml";

        private
const string InputArgInText = "-in";

        private
const string InputArgSettingsText = "-settings";

        private
const string InputArgOutText = "-out";

        private
const string InputArgLogText = "-log";

        private
StreamWriter streamLog = null;

 

       
#endregion

        #region
main

        static
void Main(string[] args)

        {

            //
Create New Converter

           
ConverterShell localConverter = new ConverterShell();

           
localConverter.inputArgs = args;

            //
Get command line

            localConverter.GetCommandLine(localConverter.inputArgs);

            //
Verify the files and copy

            if
(localConverter.VerifyFilesExist())

            {

XmlToXml myConverter = new
XmlToXml(localConverter.localOutputFullPath);

            }

           
return;

        }

       
#endregion

 

        #region
support routines

        bool
VerifyFilesExist()

        {

           
StreamReader streamIn = null;

           
bool disableCopy = false;

 

            if
(this.localPathtoFile.Equals(this.localOutputFullPath))

            {

               
disableCopy = true;

            }

            if
(this.localOutputFullPath.Length.Equals(0))

            {

               
LogResult(" Output file " + this.localOutputFullPath +
"is null ");

               
LogResult(" Please use a different file for the output file
");

               
return false;

            }

 

            try

            {

               
Stream streamInTmp = File.OpenRead(this.localPathtoFile);

               
streamIn = new StreamReader(streamInTmp);

               
streamIn.Close();

            }

           
catch

            {

               
LogResult("Error Input File for reading" +
this.localPathtoFile);

               
return false;

            }

           
LogResult(" Converting file " + this.localPathtoFile +
" to " + this.localOutputFullPath);

            //
Copy the file to the output path

            if
(!disableCopy)

            {

               
try

               
{

                   
File.Copy(this.localPathtoFile, this.localOutputFullPath, true);

               
}

               
catch

               
{

                   
LogResult("Error copying file to " +
this.localOutputFullPath);

                   
return false;

               
}

            }

           
return true;

        }

        // Get
Command Line Parameters

        public
void GetCommandLine(string[] args)

        {

            int
i = 0;

            //
Get all of the command line arguments

           
//           
Console.WriteLine(" args " + args[0] + " " +
args[1] +

           
//                " "
+ args[2] + " " + args[3] + " " + args[4] + " "
+ args[5]);

            try

            {

               
while (i < 8 && args[i] != null)

                {

                   
if (args[i] == InputArgInText && args[i + 1] != null)

                   
{

                        this.localPathtoFile
= args[i + 1];

                        i += 2;

                        continue;

                 
  }

                   
if (args[i] == InputArgSettingsText && args[i + 1] != null)

                   
{

                        this.localSettings =
args[i + 1];

                        i += 2;

                        continue;

                   
}

                    if (args[i] ==
InputArgOutText && args[i + 1] != null)

                   
{

                       
this.localOutputFullPath = args[i + 1];

                        i += 2;

                        continue;

                   
}

                    if (args[i] == InputArgLogText
&& args[i + 1] != null)

                   
{

                        this.localLogPath =
args[i + 1];

                        i += 2;

                        continue;

                   
}

                   
i += 2;

               
}

            }

           
catch (IndexOutOfRangeException e)

            {

               
// Need to eat the exception since we do not want to end because of
insufficient args

               
return;

            }

           
return;

        }

        void
LogResult(string value)

        {

            try

            {

               
Stream streamLogTmp = File.Open(this.localLogPath, FileMode.Append);

               
this.streamLog = new StreamWriter(streamLogTmp);

               
this.streamLog.WriteLine(value);

               
this.streamLog.Close();

            }

           
catch

            {

               
Console.WriteLine(value);

            }

        }

       
#endregion

    }

}

 

  1. Add a new class called
    XmlToXml.cs
    • Right click the
      project, click “New->Item”
    • Select “Class”
    • For Name, type
      “XmlToXml.cs”

    • Click “Add”
  1. Modify the class code to the
    following:


using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Xml;

 

namespace MyConverter

{

    class
XmlToXml

    {

        private
string filePath = null;

       

        public
XmlToXml(string pathName)

        {

           
filePath = pathName;

        }

 

        public
void AddNode()

        {

            try

            {

               
XmlDocument doc = new XmlDocument();

               
doc.Load(filePath);

               
doc.LastChild.AppendChild(doc.CreateNode(XmlNodeType.Element, "NewNode",
"A new node"));

               
doc.Save(filePath);

            }

           
catch (Exception ex)

            {

               
throw ex;

            }

           
finally

           
{               

            }

        }       

    }

}

 

  1. Review the code you just
    pasted in, mainly review the “Main” method
  2. Right click the project, select
    “Properties”
  3. Click the “Debug” tab
  4. For Command line arguments,
    copy the following:


-in C: arget.xml –out c:output.xml –log c:converter.log

  1. Compile the code, fix any
    errors
  2. Copy the executable (“D:Lab WorkMyConverterMyConverterinDebugMyConverter.exe”)
    to the “C:program filesMicrosoft office servers12.0TransformApps”
    directory.
    • NOTE: this is where
      your document converters should reside, notice the other converters that
      reside here:
      1. DocXPageConverter
      2. InfoPathPageConverter
      3. XslApplicatorConverter

Task 3 – Set
permission on HtLauncher directory

 

1.      Open
the “c:Program FilesMicrosoft office Servers12.0Bin” directory

2.      Right
click the HtmlTrLauncher directory, select “Properties”

3.      Click
“Security”

4.      Add
everyone with Full Control

5.      Click
“Ok”

 

Task 4 – Create a
feature and elements file

  1. Create a new directory called
    MyConverter in the /template/features directory of the 12 hive
  2. Create a file called
    feature.xml, paste the following into it:


<?xml version="1.0" encoding="utf-8" ?>

<Feature 
Id="[new guid]"

         
Title="My Converter"

         
Description="Converts xml to my own format"

         
Version="1.0.0.0"

         
Scope="WebApplication"

         
xmlns="http://schemas.microsoft.com/sharepoint/">

   
<ElementManifests>

       
<ElementManifest Location="MyConverter.xml"/>

   
</ElementManifests>

</Feature>

 

  1. Also note that you need to
    replace the [new guid] with a new GUID
    • Run the D:Lab Files09_Lab02guidgen.exe
      tool
    • Click “Radio #4”
    • Click “Copy”
    • Paste the GUID into
      the feature.xml file
    • Remove the curly
      braces ({})
  2. Create another file called
    MyConverter.xml, paste the following into it:


<?xml version="1.0" encoding="utf-8" ?>

<Elements
xmlns="http://schemas.microsoft.com/sharepoint/">

   
<DocumentConverter

       
Id="[new guid]"

       Name="Xml
to Xml"

       App="MyConverter.exe"

       From="xml"

       To="xml"
/>

</Elements>

 

  1. Be sure you create another
    guid id for the converter!
  2. Run the following commands:


stsadm –o installfeature –filename MyConverterfeature.xml

stsadm –o activatefeature –filename
MyConverterfeature.xml –url
http://servername:100

 

    • NOTE: if you copy and paste
      and get an error when running the command, replace the dashes!
  1. Perform an IISRESET
  2. Your new document converter
    is now installed!

Task 5 –Enable
Document Converters

  1. Open the Central
    Administration Site
  2. Click “Application management”
  3. Click “Manage Web Application
    features”
  4. For the “My Converter”
    feature, click “Activate”
    • NOTE: Ensure you are
      in context of web application on port 100
  5. Click “Document Conversions”
  6. Ensure that the web
    application is set to your team site web app
  7. Check the “Yes” radio button
  8. Select a load balancer server
    (you likely only have one to pick from)
  9. Notice your new converter is
    listed (“Customize “Xml to Xml” (xml into xml))
  10. Open in a new tab/windows the
    link for the converter, note the settings you can apply
  11. In the original central
    administration window, click Apply

Task 6 – Test the
converter

  1. Open your team site (http://servername:100)
  2. Add an xml document to the
    “Shared Documents” document library called TheirXml.xml with the following
    text inside the file:

 

<?xml version="1.0"
encoding="utf-8" ?>

<WatchThis>

</WatchThis>

 

  1. In the JavaScript dropdown
    for the item, select “Convert Document->Xml To Xml”

  1. For document name, type
    “OurXml”

  1. Click “Ok”
  2. A timer job will pick up the
    conversion request and put the converted document in the Pages document
    library.  As we mentioned previously
    before, a document converter will not run on a domain controller properly.

SharePoint 2007 and PowerShell

Module #06: PowerShell With SharePoint Lab #02

 

Course:                SharePoint
2007 Operations

Estimated Time to Complete:  60 minutes

Objectives:

·        
Load SharePoint Dll
into PowerShell

·        
Set PowerShell
Execution Policy

·        
Enumerate Webs

·        
Create a site with
PowerShell

·        
Create/Update an
item with PowerShell

·        
Backup SharePoint
with PowerShell

Operating
Notes:
 

·        
Run
this lab on the svr-sp2 image

·        
You
should be logged in as trainingadministrator


Deliverables:

·        
None

 

Overview:         Learn
to write PowerShell scripts for common SharePoint Tasks!

Exercise 1 – Write a PowerShell Script (Load SharePoint Dlls)

Purpose:
        Learn
to load the SharePoint dlls

Result:           
A PowerShell environment with SharePoint .NET
dlls loaded

Task 1 – Load the
SharePoint dlls

  1. Be sure to
    login to svr-sp2 as trainingadministrator
  2. Open a
    command prompt, start powershell:


Powershell

  1. Type the
    following:


[AppDomain]::CurrentDomain.GetAssemblies() | foreach-object {
split-path $_.Location -leaf } | sort

  1. Note how
    SharePoint is not in the list, we need to load the dlls!  Type the following command:


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

  1. You should
    get an output displaying the GAC, Version and Location information for the
    assembly
  2. Rerun the
    command to display the loaded assemblies, you should now see
    Microsoft.SharePoint loaded!

Exercise 2 – Create a PowerShell Profile

Purpose:
        Create
a PowerShell startup scripts

Result:           
A PowerShell script

Task 1 – Create the
script

  1. Open the C:WINDOWSsystem32windowspowershellv1.0
    directory
  2. Create a
    new file called Profile.ps1
  3. Open the
    new file and type the following into it:


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

  1. Close any
    open powershell prompts
  2. Open a new
    powershell prompt
  3. At startup
    you will get an error “…scripts is disabled on this systems”, we have to
    enable scripts to be run on the server!

Task 2 – Enable
Scripts

  1. Run the
    following command (you can also review the about_signing_help.txt file in
    the powershell install directory):


get-help about_signing

  1. Run the
    following command to get the execution policy:


get-executionpolicy

  1. Set  the execution policy to allow scripts to
    run:


set-executionpolicy unrestricted

  1. Close and
    reopen PowerShell, you should not get an error this time
  2. Run the
    following command:


[AppDomain]::CurrentDomain.GetAssemblies() | foreach-object {
split-path $_.Location -leaf } | sort

  1. You should
    see the SharePoint dll has been loaded!

Exercise 3 – Write a PowerShell Script (Enumerate Webs)

Purpose:
        Find
all the webs for a site collection

Result:           
A PowerShell script

Task 1 – Create the
script

  1. Open
    powershell, run the following:


$spsite = new-object Microsoft.SharePoint.SPSite("http://servername:100")

  1. NOTE: Be sure to replace servername
    with the name of your server
  2. NOTE: If you get an access denied
    error it likely means that you are logged in as spadmin, you can do two
    things:
    • Login as administrator on the server
      you are running powershell
    • Add spadmin as a site owner to the
      team site on port 100
  3. Run the
    following:


$spsite

  1. You will
    get a listing of all the properties that are available from the SPSite
    object! 
  2. One of the
    properties is a collection of all the webs in the site collection, run the
    following command:


$spsite.allwebs

  1. You will
    get an output all of the properties of the SPWeb object, too much
    information!
  2. Run the
    following command to select and sort specific properties:


$spsite.allwebs | select LastitemModifiedDate, URL, Created |
sort Created

  1. You can
    pipe the properties into other commands, so if you wanted to backup
    individual sites, you could do that!

Exercise 4 – Write a PowerShell Script (Create a Web)

Purpose:
        Create
A Web

Result:           
A PowerShell script

Task 1 – Create the
script

  1. Open
    powershell, run the following:


$spsite.allwebs.Add("sales", "Sales Site",
"Marketing And Sales", 1033, "STS#0", $true, $false)

  1. In a
    browser, open http://servername:100/sales
  2. You will
    see your new site!

Exercise 5 – Write a PowerShell Script (Create/Update an Item)

Purpose:
        Create/Update
an item

Result:           
A PowerShell script

Task 1 – Create the
script

  1. Open
    powershell, run the following commands:


$splist = $spsite.rootweb.lists["announcements"]
$splistitem = $splist.items[0]
$splistitem["Title"] = "a new title"
$splistitem.update()

  1. Open the http://servername:100 site, notice how
    the announcements list item has been updated!

Exercise 6 – Write a PowerShell Script (BackUp SharePoint)

Purpose:
        Learn
to use the SharePoint object model from PowerShell to backup SharePoint

Result:           
A PowerShell script to backup SharePoint

Task 1 – Create the
script

  1. Create a
    new directory called c:SharePointBackup
  2. Create a
    new script called BackUpSharePoint.ps1 in the c:scripts directory (create
    it if it doesn’t exist)
  3. Add C:scripts
    to your path
    • Click
      Start
    • Right
      click “My Computer”
    • Click
      the “Advanced” tab
    • Click
      the “Environment Variables” button
    • Click
      “Edit”
    • Add
      the following:


;c:scripts

    • Click
      Ok
    • Click
      Ok
    • Restart
      your PowerShell prompt
  1. Type the
    following into it:


$settings =
[Microsoft.SharePoint.Administration.Backup.SPBackupRestoreSettings]::GetBackupSettings("c:SharePointBackup",
"Full")

$backupId =
[Microsoft.SharePoint.Administration.Backup.SPBackupRestoreConsole]::CreateBackupRestore($settings)

$obj = 
[Microsoft.SharePoint.Administration.Backup.SPBackupRestoreConsole]::FindItems($backupId,
$settings.IndividualItem)[0]

[Microsoft.SharePoint.Administration.Backup.SPBackupRestoreConsole]::SetActive($backupId)

[Microsoft.SharePoint.Administration.Backup.SPBackupRestoreConsole]::Run($backupId,$obj)

 

  1. Open a PowerShell
    command prompt to c:scripts
    • If
      the script isn’t recognized, then you have to add c:scripts to your path
      environment variable
  2. Type
    backupsharepoint.ps1, type ENTER
  3. Open the
    c:sharepointbackups folder, notice you have some backups!

 

Creating a Custom Router for the Records Center

<!–[if !mso]>

Module #03: Custom
Router Lab #
03

 

 

Course:           Programming
Microsoft Office SharePoint Server

Estimated Time to Complete:  30 minutes

Objectives:

·        
Create a Custom
Router

Operating
Notes:
 

 

·        
None


Deliverables:

·        
None

 

Overview:         Learn
to extend the use of the Records Center!

Exercise 1 – Create A Custom Router

Purpose:
        Create
a new record router to route submitted documents!

Result:           
A new custom router

Task 1 – Create a
Class Library

  1. Create a new project
    • Click
      File->New->Project
    • Select “Class Library”
    • For name, type
      “MyCustomRouter”
    • For location, type “D:Lab
      Work”
    • Click “Ok”
  2. Add the following references:
    • Add a reference to
      Microsoft.SharePoint.dll
    • Add a reference to
      Microsoft.Office.Policy.dll

Task 2 – Create the
router

  1. In your project, rename
    Class1.cs to MyCustomRouter.cs
    • Right click, select
      “Rename”
    • Click “yes” to rename
      the class
  2. Add the following using statements:


using System.IO;

using Microsoft.SharePoint;

using Microsoft.Office.RecordsManagement;

using
Microsoft.Office.RecordsManagement.RecordsRepository;

using
Microsoft.Office.RecordsManagement.PolicyFeatures;

using Microsoft.Office.RecordsManagement.InformationPolicy;

 

 

  1. Implement the IRouter interface:


public class MyCustomRouter : IRouter

 

  1. Right click the IRouter text,
    select Implement Interface->Implement interface
  2. Update the OnSubmitFile
    method to the following:


try

            {

               
//Save it to disk

               
File.Create("C:\" + sourceUrl).Write(fileToSubmit, 0,
fileToSubmit.Length);

            }

           
catch (Exception ex)

            {

               
return RouterResult.RejectFile;

            }

 

           
return RouterResult.SuccessContinueProcessing;

 

 

Task 3 –Strong name
the project

  1. Right click the
    MyCustomRouter project, select “Properties”
  2. Click the “Signing” tab
  3. Click the “Sign the assembly”
    checkbox
  4. In the dropdown, select
    “<new>…”
  5. For key file name, type
    “MyCustomRouter”
  6. Uncheck the “Protect my key
    file…”
  7. Click “Ok”
  8. Compile the project, press F6
  9. Drag the D:Lab Work MyCustomRouterMyCustomRouter
    inDebug MyCustomRouter.dll file to the GAC (C:windowsassembly)

Task 4 – Create a
deployment application

  1. Create another project
    • In Visual Studio,
      click File->Add->New Project
    • Select “Windows
      Application”
    • For name, type
      “MyCustomRouterApp”
    • For location, type “D:Lab
      Work”

    • Click “Ok”
  1. Add some references
    • Add a reference to
      Microsoft.SharePoint.dll
    • Add a reference to
      Microsoft.Office.Policy.dll
  2. Add a button called
    “Register”, double click it
  3. Add the following using
    statements:


using Microsoft.SharePoint;

using Microsoft.Office.RecordsManagement;

using Microsoft.Office.RecordsManagement.RecordsRepository;

using
Microsoft.Office.RecordsManagement.InformationPolicy;

 

  1. In the button event handler,
    add the following:


using(SPSite site = new SPSite("http://servername:107"))

{

           
SPWeb web = site.RootWeb;

           
RecordSeriesCollection series = new RecordSeriesCollection(web);

           
series.AddRouter("My Router", "MyCustomRouter,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=[YOURPUBLICKEYTOKEN]", "MyCustomRouter.MyCustomRouter");

}

 

MessageBox.Show("Done!");

  1. NOTE: Be sure to replace servername and public key token!
  2. Set the MyCustomRouterApp to
    be the startup project
    • Right click the
      project, select “Set as startup project”
  3. Run the application, click
    the “Register” button

Task 4 – Test the
newly deployed router

  1. Open your Record Center Site
    (http://servername:107)
  2. Click “Record Routing”
  3. Edit the “Test” routing
    record

  1. For Router, select “My
    Router”

  1. Click “Ok”
  2. Open the RecordsManagementApp
    project from the last lab, submit the file again!
  3. Open your c: drive folder
    and notice the new file called “Custom Submit (no url)”, your new record
    router is working!

SharePoint Feature Deployment Map

I was doing some playing and decided to map out each level that each feature can be deployed too.  Check it out:

 

  Farm WebApplication Site Web
Control x x x x
Custom Action x x x x
Custom Action Group x x x x
Hide Custom Action x x x x
List Instance NO NO x x
List Template NO NO x x
Module NO NO x x
Receiver NO NO x x
Content Type NO NO x x
Field NO NO x NO
Workflow NO NO x x
ActivationDependency x – Follow Rules x – Follow Rules x – Follow Rules x – Follow Rules
FeatureSiteTemplateAssociation x x x NO

 

MCT Summit 2009!

Awesome news!  I have been asked to present at each of the MCT Summits in 2009!  I will be discussing the courseware library, where it has come from, where it is and where it is going!

 I plan to demo my CourseBuilder tool that we use to generate all our courses and dynamic courses!  The MCT Summit schedule is here:

 http://www.mctsummit2009.com/content/info.asp?Ccpsubsiteid=108&infoid=13

 The first stop is the Czech Republic, then back to my home town Seattle, then off to Asia!   I am looking forward to meeting all my fellow peers and educate everyone on how to be successful with the courseware library!

 Chris

Custom SharePoint Designer Workflow Activity For Document Encryption!

Module #17: Custom Activities Lab #3

 

 

Course:           Advanced SharePoint Development

Estimated Time to Complete:  60 minutes

Objectives:

·        Create a custom workflow activity for SharePoint Designer

Operating Notes:  

·        None

Deliverables:

·        None

 

Overview:         Let’s create our own custom workflow using SharePoint Designer

Exercise 1 – Create a Custom Activity

Purpose:         Create a custom activity to be used by SharePoint Designer

Result:           
Custom Activity

Task 1 – Create a Project

  1. Open Visual Studio
  2. Select the File->New->Project
  3. Select Visual C#
  4. For template, select Workflow project type.
  5. Select the Workflow Activity Library template.
  6. For Location, type C:asp
  7. For Name, type CustomActivities
  8. Click OK
  9. Rename Activity1.cs to EncryptDocument.cs
  10. Right click the project, select Add Reference
  11. Add the following references:
    • C:program filescommon filesmicrosoft sharedweb server extenstionsisapiMicrosoft.SharePoint.dll
    • C:program filescommon filesmicrosoft sharedweb server extenstionsisapiMicrosoft.SharePoint.WorkflowActions.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Common.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Security.Cryptography.dll
  12. Right click the EncryptDocument shape, select View Code
  13. Add the following using statements for the Workflow code:
    • using Microsoft.SharePoint;
    • using Microsoft.SharePoint.Workflow;
    • using Microsoft.SharePoint.WorkflowActions;
  14. Since we are going to use Enterprise library to do our encryption, add the following using statements:
    • using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    • using Microsoft.Practices.EnterpriseLibrary.Security;
    • using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
  15. Add the following Execute method:


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            SPSite site = (SPSite)__Context.Site;

            SPWeb web = (SPWeb)__Context.Web;

            this.ListId.Trim();

            this.ListId.ToLower();

            Guid listGUID = new Guid(this.ListId);

            SPList list = web.Lists[listGUID];

            SPListItem item = list.GetItemById(this.ListItem);

 

            SPFile file = item.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] encryptedByteArray = provider.Encrypt(bytes);           

            file.SaveBinary(encryptedByteArray);

            file.Update();

 

            return ActivityExecutionStatus.Closed;

        }       

 

  1. Add the following property, this will provide access to the workflow context back to our code:


public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EncryptDocument));

 

        [Description("Workflow Context")]

        [Category("Context")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

        public WorkflowContext __Context

        {

            get

            {

                return ((WorkflowContext)(base.GetValue(EncryptDocument.__ContextProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.__ContextProperty, value);

            }

        }

 

  1. Add the following ListId property:


public static DependencyProperty ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register("ListId", typeof(string), typeof(EncryptDocument));

 

        [Description("This is the description which appears in the Property Browser")]

        [Category("This is the category which will be displayed in the Property Browser")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

        public string ListId

        {

            get

            {

                return ((string)(base.GetValue(EncryptDocument.ListIdProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.ListIdProperty, value);

            }

        }

 

  1. Add the following ListItem property:


public static DependencyProperty ListItemProperty = System.Workflow.ComponentModel.DependencyProperty.Register("ListItem", typeof(int), typeof(EncryptDocument));

 

        [Description("This is the description which appears in the Property Browser")]

        [Category("This is the category which will be displayed in the Property Browser")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

        public int ListItem

        {

            get

            {

                return ((int)(base.GetValue(EncryptDocument.ListItemProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.ListItemProperty, value);

            }

        }

 

 

  1. Add another Activity, name this one DecryptDocument
  2. Add the same using statements (steps 13,14) and the same properties (steps 16,17,18)
  3. Add the following Execute method:


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            SPSite site = (SPSite)__Context.Site;

            SPWeb web = (SPWeb)__Context.Web;

            this.ListId.Trim();

            this.ListId.ToLower();

            Guid listGUID = new Guid(this.ListId);

            SPList list = web.Lists[listGUID];

            SPListItem item = list.GetItemById(this.ListItem);

 

            SPFile file = item.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] encryptedByteArray = provider.Decrypt(bytes);

            file.SaveBinary(encryptedByteArray);

            file.Update();

 

            return ActivityExecutionStatus.Closed;

        }

 

  1.  

 

Task 2 – Strong Name the assembly

  1. In the Solution Explorer, Right Click on Properties
  2. Click the Signing tab
  3. Check the checkbox, Sign the Assembly
  4. Select the New option from the Drop down below
  5. For Filename, type DocumentEncryption
  6. Uncheck the “Protect my key file with a password” option
  7. Compile the project

Task 3 – Copy to the GAC

  1. Copy the EncryptDocument.dll to the C:windowsassembly directory
  2. Copy the Enterprise Library dlls to the GAC as well
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Common.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Security.Cryptography.dll

Task 4 – Modify the web.config file

  1. Open web.config file in the C:inetpubwwwrootwssvirtualdirectories100 directory
  2. Add the following element to the System.Workflow.ComponentModel.WorkflowCompiler element:


<authorizedType

   Assembly="CustomActivities,Version=1.0.0.0,Culture=neutral,PublicKeyToken=[YOUR PUBLICKEYTOKEN]"

    Namespace="CustomActivities"

    TypeName="*"

    Authorized="True" />

 

  1. Save and close the web.config file
  2. Open Enterprise Library Configuration tool (shortcut on the desktop)
  3. From EntLib, open the web.config file
  4. Right click the “C:inetpub…” node, select New->Cryptography Application Block
  5. Right Click the Symmetric Providers node, select New->Symmetric algorithm provider
  6. Select DESCryptoServiceProvider
  7. Click Ok
  8. In the Cryptographic Key Wizard dialog, Click Next
  9. Click Generate
  10. Click Next
  11. Save the key file to the c:inetpubwwwrootwssvirtualdirectories100 directory, call it EncryptIt
  12. Click Save
  13. Click Next
  14. Select Machine Mode
  15. Click Finish
  16. Click the Cryptography Application Block node
  17. For DefaultSymmetricCryptoProvider, select the DESCryptoServiceProvider
  18. Save the web.config file

Task 5 – Create an ACTIONS file

  1. Create a file in C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATE1033Workflow called ENCRYPT.ACTIONS
  2. Copy the following to the file:


<?xml version="1.0" encoding="utf-8"?>

<WorkflowInfo Language="en-us">

  <Actions>

<Action

    Name="Encrypt a document/item"

    ClassName="CustomActivities.EncryptDocument"

    Assembly="CustomActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[PUBLICKEYTOKEN]"

    AppliesTo="all"

    Category="Encryption">

    <RuleDesigner Sentence="Encrypt %1 Item">

              <FieldBind Field="ListId,ListItem,ItemProperties" Text="this list" Id="1" DesignerType="UpdateListItem" />

         </RuleDesigner>

         <Parameters>

              <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />

              <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />

              <Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" />

              <Parameter Name="ItemProperties" Type="System.Collections.Hashtable, mscorlib" Direction="In" />

         </Parameters>

</Action>

<Action

    Name="Decrypt a document/item"

    ClassName="CustomActivities.DecryptDocument"

    Assembly="CustomActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[PUBLICKEYTOKEN]"

    AppliesTo="all"

    Category="Encryption">

    <RuleDesigner Sentence="Decrypt %1 Item">

              <FieldBind Field="ListId,ListItem,ItemProperties" Text="this list" Id="1" DesignerType="UpdateListItem" />

         </RuleDesigner>

         <Parameters>

              <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />

              <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />

              <Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" />

              <Parameter Name="ItemProperties" Type="System.Collections.Hashtable, mscorlib" Direction="In" />

         </Parameters>

</Action>

  </Actions>

</WorkflowInfo>

 

Task 6 – Create a workflow to use the Encryption action

  1. Reset IIS
  2. Open SharePoint Designer 2007
  3. Open your site (http://loclhost:100)
  4. Select File->New->Workflow menu command.
  5. For Name, type “Encrypt It”, select Shared Documents from the dropdown
  6. Click Next
  7. Click Actions, select the More Actions
  8. Click the dropdown for the Select a Category and choose “Encryption”
  9. In the Choose an Action box, select the “Encrypt a document/item” activity
  10. Click Add.
  11. Click on “this” option in the Action
  12. From the Choose List Item dialog box, select the “Current Item” option
  13. Click OK
  14. Click Finish

Task 7 – Run the workflow

  1. Add an item to the document library
  2. Right click the JavaScript dropdown, select workflows
  3. Click Encrypt It

Task 8 – Try to open the document

  1. Click the document, Word should fail to open it…it is encrypted!!!

Task 9 – Create a workflow to use the Decryption action

  1. In SharePoint Designer 2007, select File->New->Workflow menu command.
  2. For Name, type “Decrypt It”, select Shared Documents from the dropdown
  3. Click Next
  4. Click Actions, select the More Actions
  5. Click the dropdown for the Select a Category and choose “Encryption”
  6. In the Choose an Action box, select the “Decrypt a document/item” activity
  7. Click Add.
  8. Click on “this” option in the Action
  9. From the Choose List Item dialog box, select the “Current Item” option
  10. Click OK
  11. Click Finish

Task 10 – Run the workflow

  1. Add an item to the document library
  2. Right click the JavaScript dropdown, select workflows
  3. Click Decrypt It

Task 11 – Try to open the document

  1. Click the document, Word will open…it is decrypted!!!

SharePoint 2007 Document Encryption

Since releasing the new Advanced SharePoint Development course, I have been working on various items to add to it!  One of them is using Enterprise Library with SharePoint Event Handlers to implment document encryption!  Here is the lab!

Module #15: SharePoint Event Handlers Lab #3

 

 

Course:           Advanced SharePoint Development

Estimated Time to Complete:  45 minutes

Objectives:

·        Create an Event Handler feature that encrypts documents

Operating Notes:  none

Deliverables:

·        None

 

Overview:         SharePoint has exposed several events that we can tie into with our own code.  Let’s see how to do this!

Exercise 1 – Create a new SharePoint Event Handler

Purpose:         Create and register an event handler for SharePoint events

Result:           
A new event handler

Task 1 – Create a new Visual Studio Class Library

  1. Open Visual Studio, select New->Project
  2. Select Class Library from the project templates
  3. Name the project EncryptDocumentEventReceiver
  4. For location, c:asp
  5. Add a reference to
    • Microsoft.SharePoint.dll
    • Microsoft.Practices.EnterpriseLibrary.Common
    • Microsoft.Practices.EnterpriseLibrary.Security
    • Microsoft.Practices.EnterpriseLibrary.Security.Cryptography
  6. Add a using statement to
    • Micorosft.SharePoint
    • Microsoft.Practices.EnterpriseLibrary.Common;
    • Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    • Microsoft.Practices.EnterpriseLibrary.Security;
    • Microsoft.Practices.EnterpriseLibrary.Security.Configuration;
    • Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
  7. Rename class1 to EncryptDocument
  8. Make EncryptDocument inherit from SPItemEventReceiver
  9. Add the following methods:

private void Encrypt(SPItemEventProperties properties)

        {

            //get the file, encrypt it

            SPFile file = properties.ListItem.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] encryptedByteArray = provider.Encrypt(bytes);

            string encryptedText = Convert.ToBase64String(encryptedByteArray);

 

            file.SaveBinary(encryptedByteArray);

            file.Update();    

        }

 

        private void Decrypt(SPItemEventProperties properties)

        {

            //get the file, encrypt it

            SPFile file = properties.ListItem.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] decryptedByteArray = provider.Decrypt(bytes);

            string decryptedText = Convert.ToBase64String(decryptedByteArray);

 

            file.SaveBinary(decryptedByteArray);

            file.Update();           

        }

 

        public override void ItemCheckedOut(SPItemEventProperties properties)

        {

            Decrypt(properties);

 

            base.ItemCheckedOut(properties);

        }

 

        public override void ItemCheckedIn(SPItemEventProperties properties)

        {

            Encrypt(properties);

 

            base.ItemCheckedIn(properties);

        }

       

        public override void ItemAdded(SPItemEventProperties properties)

        {

            Encrypt(properties);

 

            base.ItemAdded(properties);

        }       

 

  1. Right Click the project, select Properties
  2. Select the Signing tab
  3. Click “Sign the assembly”
  4. Select <New…>, type EncryptDocumentEventReceiver.snk
  5. Uncheck “Password…”
  6. Build the project, Press Ctrl-Shift-B
  7. Copy the C:ASPEncryptDocumentEventReceiverEncryptDocumentEventReceiverinDebugEncryptDocumentEventReceiver.dll to the c:windowsassembly directory (this installs the assembly in the gac)

Task 2 – Extend the web.config file

  1. Open Enterprise Library console
  2. Click the open button, browse to the c:inetpubwwwrootwssvirtualdirectories100web.config file
  3. Click Open
  4. Right click the “C:inetpub…” node, select New->Cryptography Application Block
  5. Right click the Symmetric Provider node, select New->Symmetric Algorithm Provider
  6. Select TripleDESCryptoServiceProvider, Click Ok
  7. In the Cryptographic key wizard, Click Next
  8. Click Generate
  9. Click Next
  10. Name the key “EncryptIt.key”, Click Save
  11. Click Next
  12. Select Machine mode, Click Finish
  13. Click the Cryptography Application Block node
  14. For DefaultSymmetricCryptoProvider, select TripleDESCryptoServiceProvider

Task 3 – Create a console application to register the event handler

  1. In Visual Studio, click Add->New->Project
  2. Select a Windows Console Application
  3. Modify the Main method to this:


static void Main(string[] args)

        {

            try

            {

                SPSite site = new SPSite("http://localhost:100");

                SPWeb web = site.OpenWeb();

 

                SPEventReceiverDefinitionCollection receivers = web.EventReceivers;               

                SPEventReceiverDefinition newRecevier = receivers.Add();

                newRecevier.Name = "EncryptDocumentItemAdded";

                newRecevier.Assembly = "EncryptDocumentEventReceiver, Version=1.0.0.0, Culture=neutral,PublicKeyToken=3041621ef2536dab";

                newRecevier.Class = "EncryptDocumentEventReceiver.EncryptDocument";

                newRecevier.Type = SPEventReceiverType.ItemAdded;

                newRecevier.Update();

 

                newRecevier = receivers.Add();

                newRecevier.Name = "EncryptDocumentItemCheckedOut";

                newRecevier.Assembly = "EncryptDocumentEventReceiver, Version=1.0.0.0, Culture=neutral,PublicKeyToken=3041621ef2536dab";

                newRecevier.Class = "EncryptDocumentEventReceiver.EncryptDocument";

                newRecevier.Type = SPEventReceiverType.ItemCheckedOut;

                newRecevier.Update();

 

                newRecevier = receivers.Add();

                newRecevier.Name = "EncryptDocumentItemCheckedIn";

                newRecevier.Assembly = "EncryptDocumentEventReceiver, Version=1.0.0.0, Culture=neutral,PublicKeyToken=3041621ef2536dab";

                newRecevier.Class = "EncryptDocumentEventReceiver.EncryptDocument";

                newRecevier.Type = SPEventReceiverType.ItemCheckedIn;

                newRecevier.Update();               

            }

            catch (Exception ex)

            {

                Console.Write(ex.Message);

            }

        }

 

 

  1. Compile the project (Ctrl-Shift-B)
  2. Run the Console Project
  3. Reset IIS
  4. Open the http://localhost:100 site
  5. Create a text document, upload it to the document library
  6. Open the document, notice it is encrypted
  7. Check out the document
  8. Open the document, it is now decrypted!