CopyCat: Using Built-in WebServices to Copy Document Library Permissions Across Servers
Here's a sample console application written in C# which will copy the permissions from one document library to another using the built-in Permissions.asmx WebService. Note that this sample does not account for cross-domain use, etc. This will *only* work if the same users exist on the destination. Overall, this is a fairly rough sample, but it covers some good material, so I thought I'd go ahead and post here. :)
The sample does the following:
-Gets the current destination list permissions using the web service on the destination site
-Removes the current destination list permissions using the web service on the destination site
-Gets the source list permissions using the web service on the source site
-Sets the destination list permissions using the web service on the destination site
This project will require adding a Web Reference -- to the Permissions web service on any machine (the URL will be overwritten in the code) -- in the VC# project. Adding the Web Reference should add standard references to System.Web.Services, System.XML, and System.Data.
Two notes on this sample:
1) There is little error handling.
2) We cannot remove or add implicit members (Administrator, Guest) of a list. These members are automatically added when a list is created, and are not controlled by the user; as such, they can not be programmatically modified.
=====
using System;
using System.Xml;
using System.Diagnostics;
namespace CopyDocLibPermissions
{
public class AddWithWS
{
[STAThread]
static void Main(string[] args)
{
string sSourceSiteURL = "https://<server>/sites/<site1>"; //TODO: modify
string sSourceList = "MySourceList"; //TODO: modify
string sDestSiteURL = "https://<server>/sites/<site2>"; //TODO: modify
string sDestList = "MyDestinationList"; //TODO: modify
int iReturn = CopyPermissions(sSourceSiteURL, sSourceList, sDestSiteURL, sDestList);
Console.ReadLine();
}
static int CopyPermissions(string SourceSite, string SourceList, string DestSite, string DestList)
{
//get permissions from destination list
System.Xml.XmlNode xDestPerms = GetPermissions(DestSite, DestList);
//remove existing permissions from destination list
RemovePermissions(DestSite, DestList, xDestPerms);
//get source list permissions
System.Xml.XmlNode xSourcePerms = GetPermissions(SourceSite, SourceList);
//add source list permissions to destination list
SetPermissions(DestSite, DestList, xSourcePerms);
Console.WriteLine("==COMPLETE!==\n");
return 0;
}
static XmlNode GetPermissions(string URL, string ListName)
{
URL += "/_vti_bin/Permissions.asmx";
localhost.Permissions oPermissionsService = new localhost.Permissions();
oPermissionsService.Url = URL;
oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;
try
{
XmlNode oNode = oPermissionsService.GetPermissionCollection(ListName, "List");
return oNode;
}
catch(System.Exception exGet)
{
Console.WriteLine("Error Getting Permissions!");
Debug.WriteLine(exGet.ToString());
return null;
}
}
static bool RemovePermissions(string URL, string ListName, XmlNode Permissions)
{
URL += "/_vti_bin/Permissions.asmx";
localhost.Permissions oPermissionsService = new localhost.Permissions();
oPermissionsService.Url = URL;
oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlNodeList xNL = Permissions.FirstChild.ChildNodes;
string sPerm = "";
string sIsUser = "";
string sName = "";
string sType = "";
for(int i=0;i<xNL.Count;i++)
{
sIsUser = xNL[i].Attributes["MemberIsUser"].Value.ToString().ToUpper();
if(sIsUser == "TRUE")
{
//is user
sName = xNL[i].Attributes["UserLogin"].Value.ToString();
sType = "user";
}
else
{
sPerm = xNL[i].OuterXml.ToString();
if(sPerm.IndexOf("RoleName") > 0)
{
//is Role
sName = xNL[i].Attributes["RoleName"].Value.ToString();
sType = "role";
}
else
{
//is group
sName = xNL[i].Attributes["GroupName"].Value.ToString();
sType = "group";
}
}
try
{
oPermissionsService.RemovePermission(ListName, "List", sName, sType);
Console.WriteLine("Permission Removed: {0}", sName);
}
catch(System.Exception exRemove)
{
Console.WriteLine("Can't Remove Permission: {0}",sName);
Debug.WriteLine(exRemove.ToString());
}
}
return true;
}
static bool SetPermissions(string URL, string ListName, XmlNode Permissions)
{
URL += "/_vti_bin/Permissions.asmx";
localhost.Permissions oPermissionsService = new localhost.Permissions();
oPermissionsService.Url = URL;
oPermissionsService.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlNodeList xNL = Permissions.FirstChild.ChildNodes;
string sPerm = "";
string sIsUser = "";
string sName = "";
string sType = "";
int iMask = 0;
for(int i=0;i<xNL.Count;i++)
{
sIsUser = xNL[i].Attributes["MemberIsUser"].Value.ToString().ToUpper();
iMask = Int32.Parse(xNL[i].Attributes["Mask"].Value);
if(sIsUser == "TRUE")
{
//is user
sName = xNL[i].Attributes["UserLogin"].Value.ToString();
sType = "user";
}
else
{
sPerm = xNL[i].OuterXml.ToString();
if(sPerm.IndexOf("RoleName") > 0)
{
//is Role
sName = xNL[i].Attributes["RoleName"].Value.ToString();
sType = "role";
}
else
{
//is group
sName = xNL[i].Attributes["GroupName"].Value.ToString();
sType = "group";
}
}
try
{
oPermissionsService.AddPermission(ListName, "List", sName, sType, iMask);
Console.WriteLine("Permission Added: {0}", sName);
}
catch(System.Exception exAdd)
{
Console.WriteLine("Can't Add Permission: {0}",sName);
Debug.WriteLine(exAdd.ToString());
}
}
return true;
}
}
}