Skip to main content
Nintex Community Menu Bar

We recently ran into a request to "archive project sites after the project has been completed" and this started to make me think of how we can automate as much as possible behind the scenes. Before we could do anything, we first had to define what "archive" meant to the end users, site owners, and us (the SharePoint team). After a few conversations, we all landed on the following:

 

  1. An archived site retains current permission structure, but is reduced down to read at the site level.
  2. All users will have access to the site, for historical reference, at a read level.
  3. The site will be "stamped" with an expiration date, upon which the site will be reviewed and deleted.
  4. Any content on the site may need to be migrated to team sites (for operational guides).

 

With these key points in mind, we can begin to really understand how to approach this. I am going to go over the first two steps here, and the others at a later time.

I do want to say that this will perform the actions at the top level of the site. Meaning, that if a user or group is applied directly to a library or a list, this process will not change the permissions that were applied through breaking inheritance.

 

Let's dive in!

 

The Setup

Before we get to the good stuff, let us go over what we need.

I did this in a UDA because we have heard similar asks from other departments, so in preparation I went ahead and did it this way. You can easily do this in a site workflow and feed it from a list.

 

UDA Parameters

186097_pastedImage_3.png

 

Workflow Variables

186110_pastedImage_0.png

 

Retaining Current Structure Reduced to Read

Honestly, at first we suggested to remove all user permissions and then grant everyone read via AD. This accomplishes the same thing, but we lose the permissions structure that was in-place. We also avoid any issues with orphaned user groups, or even removing user groups that were applied on other project sites.

 

186100_pastedImage_10.pngFirst thing to do is set the permission mask variable to read. This is done by setting out variable ReadPermissionMask to 138612833.

There are a lot of articles out there regarding permission masks and what each of them are.

 

Next, we need to get the applied groups and update their permissions. We will use Web Service calls to get the group XML so that we can iterate through the data and perform our actions.

 

We can use the GetGroupCollectionFromWeb service call from usergroup.asmx to set our varGroupXML. We will go after the data from the site that is provided by the user or workflow that we require as a parameter (inputSiteURL). You will have to put in an actual site URL to generate a list of web methods, but you can then replace the URL with your variable once you are setup.

 

186107_pastedImage_12.png

 

Now that we have the data, we need only to get the specific user group names. So of course we will throw a Query XML action in there and query our variable (varGroupXML). I would recommend testing the web service and seeing the XML so that you understand the structure. It helps determine the XPath needed to get the desired elements. For this, we will use the following for the XPath to get to the Name element: /defaultNS:GetGroupCollectionFromWeb/defaultNS:Groups/defaultNS:Group/@Name

 

It is time to do the actual updates! We will use a For each loop, and look at the varPermissionIDColl. For each varPermissionID in that collection, we want to call a web service to update the permissions. We will use the UpdatePermission web service in permissions.asmx. Just as before, we will use the inputSiteURL variable to target the specific site. We will need a bit more information on this step:

 

objectType: Web

permissionIdentifier: varPermissionID

permissionType: Group

permissionMask: ReadPermissionMask

 

186112_pastedImage_2.png

 

That is it for the groups. If you were to run this now, all user groups on the target site would be updated to Read permissions.

While we updated all the groups, what about the users? In a perfect world, everyone would be in a group so we would not need to worry about random users being applied outside of a group...but alas we do not live there and random users are granted access outside of user groups. So to accomplish the same thing for users, you will run through the same process, but this time go after users, not groups.

 

Just like in the first web service call, you will want to use a method from usergroup.asmx, but this time you will want to call the GetUserCollectionFromWeb method to set our varUserXML.

 

Again, using a Query XML action, get a collection of names to perform the updates on. This time we will want to get login names since we are dealing with users. The XPath for this will be something like: /defaultNS:GetUserCollectionFromWeb/defaultNS:Users/defaultNS:User/@LoginName

 

I stored it into the varPermissionIDColl variable (you could create another variable if wanted or needed for debugging) and looped through it in the same way. This time, in the web service call, we need to make a slight change since we are dealing with users:

 

objectType: Web

permissionIdentifier: varPermissionID

permissionType: User

permissionMask: ReadPermissionMask

 

That covers all user groups and users that are applied to the site level. Last piece is to apply all users to the site with Read permissions.

We accomplish this with a simple web service call using the method AddPermission from permissions.asmx. Here is what it will look like:

186114_pastedImage_27.png

 

Final Thoughts

This process is by no means one-size-fits-all, but it does accomplish some common asks (at least from what we have encountered). If you need to reduce all users and groups down to read, this is a straightforward way of doing things. Also, you could elevate permissions using the same process; simply change the permission mask. I have been toying with the idea of adding some logic to this to allow for permission level selection and evaluate the desired level within the workflow. This would allow for both reducing permissions as well as elevating them all within one UDA.

 

Also, as I said at the beginning, this only updates users and groups at the top site level. Any areas with broken inheritance will not be affected by this. I would like to explore how to "re-inherit" throughout the site, or possibly, find the areas with broken inheritance. This way no one slips through the cracks with different permissions.

 

Let me know what you have done or how you would approach/improve this!

 

Until next time.

 

I posted the UDA in Nintex Xchange™️​ titled Remove Permissions UDA  if you want to grab a copy of it.

Very cool Jesse McHargue​!


Hi Jesse,

doesn't this solution imply, that you never break the permissions inheritance? Otherwise you would still have write access in case the permissions are not inheritate from the website.


Hello Henning Eiben​ -

That is correct. For this example, we do not break inheritance at all as the sites that we do this to are project sites. All of the sites are in a single site collection and we setup the user groups based on roles. This allows the project manage to drop users into groups based on their roles within the project.

Again, this is not a perfect solution and does not fit all, but ti does give a glimpse into what can be automated!

I believe there is a way to inherit permissions back, but you have to know where they are broken. This can be cumbersome as it could go down all the way to a document/item.

If there are any thoughts on how to extend this to include such items, I would be happy to hear about it and test that functionality out!


depending on how you implement your roles and groups permissions you cannot prevent breaking the inheritance.

But non the less - it's a nice solutiion


Hello Henning Eiben​ -

Agreed - you cannot stop users from breaking permissions if you intend to have them manage their site/project. It is a known risk and through education and training, hopefully they understand the importance of keeping the user groups intact and not broken.

Thanks!


Reply