You can use a Script Task in SSIS to move SharePoint list attachments to the file system. This C# code references the Microsoft.SharePoint assembly. It’s very important to note that the the SharePoint attachments have to be on the same server that the package is running on. Thes means that the package can only run on SSIS installed on the SharePoint box where the attachments are. You will need to install SSIS and the corresponding msdb database on your SharePoint server if it isn’t already installed.
This is what the final package looks like:
Most of the these tasks are self explanatory and you’ll need to set up your own tables and logic to accomplish the goals of your package. You’ll want a table that tells you which items have attachments. See this post for details on how to import data from a SharePoint list. Attachments is one of the fields you can import, which is simply a bit that says whether or not the list item has any attachments.
These are the variables used in the package:
For Each Loop:
Variables used in the script task:
References needed in the script task:
Here is the C# code:
using System; using System.Data; using Microsoft.SqlServer.Dts.Runtime; using System.Windows.Forms; using System.IO; using Microsoft.SharePoint; using System.Data.SqlClient; using System.Net; namespace ST_573f63e769424529b4c14ec196d01e4f.csproj { [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")] public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase { #region VSTA generated code enum ScriptResults { Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success, Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure }; #endregion /* The execution engine calls this method when the task executes. To access the object model, use the Dts property. Connections, variables, events, and logging features are available as members of the Dts property as shown in the following examples. To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value; To post a log entry, call Dts.Log("This is my log text", 999, null); To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true); To use the connections collection use something like the following: ConnectionManager cm = Dts.Connections.Add("OLEDB"); cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;"; Before returning from this method, set the value of Dts.TaskResult to indicate success or failure. To open Help, press F1. */ public void Main() { // Read the attachments info and write it to a SQL table string SharePointSite = (string)Dts.Variables["SPSite"].Value; SPSite mySite = new SPSite(SharePointSite); //SPSite mySite = new SPSite("http://primenetdev/forms"); SPWeb myweb = mySite.OpenWeb(); SPList myList = myweb.Lists["Fitness Reimbursement Authorization"]; int ItemID = (int)Dts.Variables["ItemID"].Value; SPListItem myListItem = myList.GetItemById(ItemID); int i = 1; foreach (String attachmentname in myListItem.Attachments) { // MessageBox.Show("Each attachment"); String attachmentAbsoluteURL = myListItem.Attachments.UrlPrefix // gets the containing directory URL + attachmentname; //Set up SQL Connection string sSqlConn = Dts.Variables["SqlConn"].Value.ToString(); SqlConnection sqlConnection1 = new SqlConnection(sSqlConn); SqlCommand cmd = new SqlCommand(); SqlDataReader reader; cmd.CommandType = CommandType.Text; cmd.Connection = sqlConnection1; sqlConnection1.Open(); //If its the first attachement, name it 12 digits ending in the Item ID if ((i.Equals(1))) { cmd.CommandText = "INSERT INTO SP_Attachments (WorkflowName, ItemSharePointID, AttachmentName, AttachmentURL, Moved, NewFileName) VALUES ('Fitness','" + ItemID + "','" + attachmentname + "','" + attachmentAbsoluteURL + "','" + 0 + "','F' + RIGHT('00000000000' + CAST(" + ItemID + " as VARCHAR),11)" + ")"; } //Otherwise append an attachment id else { cmd.CommandText = "INSERT INTO SP_Attachments (WorkflowName, ItemSharePointID, AttachmentName, AttachmentURL, Moved, NewFileName) VALUES ('Fitness','" + ItemID + "','" + attachmentname + "','" + attachmentAbsoluteURL + "','" + 0 + "','F' + RIGHT('00000000000' + CAST(" + ItemID + " as VARCHAR),11) + CAST(" + i + "as VARCHAR))"; } reader = cmd.ExecuteReader(); sqlConnection1.Close(); string MRI = (string)Dts.Variables["MRI_File_Location"].Value; DirectoryInfo dir = new DirectoryInfo(MRI); if (dir.Exists) { // Create the filename for local storage using String ItemNum = "00000000000" + ItemID.ToString(); String ItemName = ItemNum.Substring(ItemID.ToString().Length, 11); String FileName = "\F" + ItemName + i; //If its the first attachement, name it 12 digits ending in the Item ID, otherwise append which attachement it is if ((i.Equals(1))) { FileName = "\F" + ItemName; } FileInfo file = new FileInfo(dir.FullName + FileName); i = i + 1; if (!file.Exists) { if (attachmentAbsoluteURL.Length != 0) { // download the file from SharePoint or Archive file system to local folder WebClient client = new WebClient(); //if (Strings.Left(fileUrl, 4).ToLower() == "http") { //download the file from SharePoint client.Credentials = System.Net.CredentialCache.DefaultCredentials; client.DownloadFile(attachmentAbsoluteURL, file.FullName); } //Mark record as Moved sqlConnection1.Open(); DateTime Now = DateTime.Now; cmd.CommandText = "UPDATE SP_Attachments SET Moved = 1, Moved_Date = '" + Now + "' WHERE ItemSharePointID = '" + ItemID + "'"; reader = cmd.ExecuteReader(); sqlConnection1.Close(); // MessageBox.Show("End"); } Dts.TaskResult = (int)ScriptResults.Success; } } } } }
H
Hi,
I read your great post on how to import data from a SharePoint list, but wanted to know how to include the attachment name and sharepoint location path of any attachements in the list, which lead me to this post. I don’t really want to copy the attchments to the file system, only extract the file name and paths. Can this be done?
Hi Ed,
You can read the next post which tells you how to do this. http://thedataqueenblog.azurewebsites.net/category/integration-services/sharepoint-list-attachments/
Cheers,
Martina