ProjectPoint

How To: Check if a user is part of a SharePoint group in InfoPath

Earlier this week a colleague sent out an email with the following problem:

“My client wants to hide certain fields and sections in an InfoPath form if a user is not part of a specific SharePoint group. The InfoPath form should not use code as the client declines solutions with code behind.”

This email got send around and a couple of people replied that custom code in form of a web service will need to be used. Not quite what my colleague’s client wanted.

One of the responses was to use the GetUserCollectionFromGroup method from the UserGroup web service (one of SharePoint’s out of the box web services), wrap it in a custom web service and verify the group membership in the custom web service. The reason for this suggestion was that the returned result set in InfoPath doesn’t get interpreted correctly. It basically can’t be used and the custom web service can be used to transform the results and do the verification within the web service.

I am a BIG fan of SharePoint’s out of the box web services and I was sure that the web service still can be used to get users of a certain SharePoint group. This could then be used to determine if the user is part of the group. My first thought was to save the InfoPath form as source files and modify the XML schema of that web service somehow. A bit of googeling later I had a solution ready to go thanks to Ian’s Blog entry here. It describes exactly what needs to be modified in the XML schema. Great post! And here is my solution with Ian’s help:


At this stage the form queries the current user’s account name and stores it in the CurrenUserAccountName field on form open. Next we will query the UserGroup web service to get us a list of users in a specific SharePoint group:

Now the tricky part. We need to save our form and then use the Export Source Files option under “Publish“.


Once that is done, close the form and navigate to the location where you exported your form to. Open the file named “GetUserCollectionFromGroup1.xsd“. This file defines the XML schema. Open the file in a text or XML editor. The following steps can be found in Ian’s blog. Thanks again!

Right under this code within the file:

1
<s:import namespace="http://www.w3.org/2001/XMLSchema"></s:import>

insert the following snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<s:complexType name="GetUserCollectionFromGroupType">
 <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="Users">
   <s:complexType>
    <s:sequence>
     <s:element maxOccurs="unbounded" name="User" >
      <s:complexType>
       <s:attribute name="Notes" type="s:string"></s:attribute>
       <s:attribute name="Name" type="s:string"></s:attribute>
       <s:attribute name="IsSiteAdmin" type="s:string"></s:attribute>
       <s:attribute name="Sid" type="s:string"></s:attribute>
       <s:attribute name="ID" type="s:string"></s:attribute>
       <s:attribute name="LoginName" type="s:string"></s:attribute>
       <s:attribute name="Email" type="s:string"></s:attribute>
       <s:attribute name="IsDomainGroup" type="s:string"></s:attribute>
      </s:complexType>
     </s:element>
    </s:sequence>
    </s:complexType>
  </s:element>
 </s:sequence>
</s:complexType>

Now locate the following piece of code within your file:

1
2
3
4
5
6
7
<s:element name="GetUserCollectionFromGroup">
  <s:complexType> 
    <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="groupName" type="s:string"></s:element>
    </s:sequence> 
  </s:complexType> 
</s:element>

and replace it with this:

1
2
3
4
5
6
7
8
<!--<s:element name="GetUserCollectionFromGroup">
  <s:complexType> 
    <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="groupName" type="s:string"></s:element>
    </s:sequence> 
  </s:complexType> 
</s:element>-->
<s:element name="GetUserCollectionFromGroup" type="tns:GetUserCollectionFromGroupType" />

We are almost there J Now save the file and open the manifest.xsf by right clicking it and select Design.

If you have a look at your GetUserCollectionFromGroup data source and its fields, you will notice that it has changed from this:

to this:

Now the last thing we need to do is setup the IsGroupMember field. We want it to return a 1 if the user is in the group and a 0 if the user is not in the group.

We are done. You can now use the “IsGroupMember” field to hide and show different sections and fields in your form based on if the user is a member of the configured SharePoint group.

One thing to be aware of though is, that whenever you change the “GetUserCollectionFromGroup” data source, you will need to go through the setup process again for this data source.

Happy InfoPath-ing :)

*****UPDATE*****
Thanks to Phillip for the hint. Apparently you have to make sure that all users have read permissions to the SharePoint group you want to check. Otherwise it will come up with the common 5566 error that indicates that there are problems accessing the datasource. To give users read permissions on the group follow the steps below:

  1. Go to Site Actions -> Site Settings -> People and Groups
  2. Click on the “Groups” heading on the left
  3. Locate the group your users need to have read access to
  4. Click on the Edit button next to it
  5. Make sure that in the Group Settings section of the following page, for the first question (“Who can view the membership of the group?”) the option “Everyone” is selected
  6. Click OK

Thanks again to Phillip for pointing this out! Much appreciated.

, , , ,

98 thoughts on “How To: Check if a user is part of a SharePoint group in InfoPath
  • Mike says:

    I was getting a 0 value for users who were in the group I was searching for.

    After looking at the results from the separate data connections, I was getting a mis-match on the cases between the accountname retrieved via Get UserProfileByName and the loginname retrieved in the results from the GetUserCollectionFromGroup. I applied a translate (converting upper to lower case) on the contents of the CurrentUserAccountField, and also converted to lowercase the ‘loginname’ in the filter on the IsGroupMember field. The cases then matched and things worked as expected.

  • Patrick says:

    Hi Mike,
    thanks for your comment. I heard that on a few occasions, but funnily enough when ever I try it, i get both the domain and the username in lower case from both data sources.
    Anyway, although I haven’t encountered it myself, I will update the post in the coming days with your tip.

    thanks,
    Pat

  • Suresh says:

    This wat i expected

  • Gina Sweigart says:

    I can get this to work in the client but not in a browser enabled form. Any hints?

  • Dustin says:

    I’m attempting this in a Claims Aware website, and the desktop filler never picks up the user account because there is that i:0.w# thingy at the beginning of the user list from SharePoint, which is completely missing from the desktop. I’m testing this now as a web-browseable form for a client. This might be the ticket to get around using User Roles.

  • Shreyas says:

    Thanks for the post! has been of great help… but i am stuck with a slight problem, the username is not refreshing in the browser, on some investigation i found that the code behind that i have is causing the problem, as soon as i remove the code its showing the current user prefectly…
    I also thought could be a problem with my code and just had empty methods, even then the username value doesnt show properly.
    Can you please help me with that?
    Thanks

  • Patrick says:

    Hi Dustin,
    I have never tried it on a claims aware site. What you can do to strip the “i:0.w#” off your string is to use the substring-after() function in InfoPath, like so: substring-after(YOURUSERSTRING; “i:0.w#”)

  • Patrick says:

    Hi Shreyas,
    I am not too sure why you have troubles with the code behind your form. One suggestion though. Since you already have code behind your form, have you tried achieving the same goal in code? do you get the same result/issue with your username?

  • Shiv yadav says:

    I have followed all the steps and able to create what I want in Infopath 2010 however when I published it to a sharepoint list, I get an error. The error says” An error occurred while trying to connect to a Web service.
    An entry has been added to the Windows event log of the server.
    Log ID:5566
    Correlation ID:06690617-d68f-4fff-aa4d-56191e106e88″

    I have checked that SharePoint groups are visible/readablt to everyone. When I checked the Logs, I found that My form is trying to access web services and there it says “Authentication failed”.

    I am able to launch my form perfectly fine(in SharePoint list) only with the service account which is running the respective webapp’s application pool.

    I also tried to disbaled the lookcheckback with registery edit.

    Any suggestions would be highly appreciated….!!

  • Richard says:

    This post just shows how spoilt I was with lotus notes. Need to hide any control on a form, one simple line of code and job done.

  • Patrick says:

    Hi,
    have you tried accessing the web service just through your browser? Does that work or do you get an error as well?
    Cheers,
    Pat

  • Patrick says:

    Hi Richard,
    you can probably do this with less effort in code behind the form. The point of InfoPath though is, that it is intended for power users that dont have programming knowledge. Hence the no-code solution approach in this post :)

  • david says:

    I also got the currentuser and loginName mis-match issue. I used translate function to resolve this problem. But the currentuser is single occurence and loginName is multiple, so I still get 0 if the first occurence in loginName does not much the currentuser.

  • Mayank says:

    Thanks for the wonderful article. I have implemented the solution. But if I were to move to a different Virtual machine that has SharePoint and InfoPath, do I have to start from scratch. If not, how do I make a change to URL that is linking to web services. What files do I need to copy.

  • Patrick says:

    if you store the data connections as UDCX files in your site, you can move the connection files along with the InfoPath form into your other environment. Then all you need to do to change the URL for the form, go to the UDCX file and change the URLs in there. The form will use the new URL then

  • Patrick says:

    it does not matter whether the loginname is the first or the second or the third occurrence. The applied filter should return a 1 no matter where the loginname matches the currentuser. The point of the filter is to search for the current user within the XML returned by the web service. if it doesn’t return 1, then the username is not part of the returned results.

  • Viktor says:

    When setting IsGroupMember towards the end, checking my formula of
    count(translate(@LoginName[.=CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))

    returns

    Argument 1 must return a node-set.

    –>count(translate(xdXDocument:GetDOM(“GetUserCollectionFromGroup”)/dfs:myFields/dfs:dataFields/ns1:GetUserCollectionFromGroupResponse/ns1:GetUserCollectionFromGroupResult/ns1:GetUserCollectionFromGroup/ns1:Users/ns1:User/@LoginName[. = xdXDocument:get-DOM()/my:myFields/my:CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))<–

    Anyone have any ideas? Thanks!

  • Cory says:

    Thanks for this blog entry Patrick. Quick question….what if I want to have multiple SP Groups collaborate on a form and only see their views, sections etc? When I create this data source I can only name one group but I have need of, say, 10 groups to create the rules around.

  • Patrick says:

    Hi Cory, in that case you’d have to create one data connection for each group. Which would take quite a while to do, let alone the possible performance impact. Any chance you could put those users in a SharePoint list, assigned to roles and then do a similar check on the list? Not the best solution from an admin point of view, but for the form it would be the better way with that many groups. Depending on the number of users in each group

  • Madhavan says:

    I have followed all the steps and able to create what I want in Infopath 2010 however when I published it to a sharepoint list, I get an error. The error says” An error occurred while trying to connect to a Web service.
    An entry has been added to the Windows event log of the server.
    Log ID:5566
    Correlation ID:06690617-d68f-4fff-aa4d-56191e106e88″

    I have checked that SharePoint groups are visible/readablt to everyone. When I checked the Logs, I found that My form is trying to access web services and there it says “Authentication failed”.

    I am able to launch my form perfectly fine(in SharePoint list) only with the service account which is running the respective webapp’s application pool.

    I also tried to disbaled the lookcheckback with registery edit.

    Any suggestions would be highly appreciated….!!

  • Anila says:

    Hi mike,

    I have still getting 0 value for users who were in the group I was searching for,
    i can’t complete the translate function ,

    when i put like this,
    count(translate(@LoginName[contains(., txtName)],”ABCDEFGHIJKLMNOPQRSTUVWXYZ”,”abcdefghijklmnopqrstuvwxyz”))

    getting error like,
    Argument 1 must return a node-set.

    –>count(translate(xdXDocument:GetDOM(“GetUserCollectionFromGroup”)/dfs:myFields/dfs:dataFields/ns1:GetUserCollectionFromGroupResponse/ns1:GetUserCollectionFromGroupResult/ns1:GetUserCollectionFromGroup/ns1:Users/ns1:User/@LoginName[contains(., xdXDocument:get-DOM()/my:myFields/my:txtName)], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))<–
    Is anybody here to help me…

  • Patrick says:

    Hi Madhavan, please refer to this blog. Might help you resolve your issue. Worked for me in the past.
    http://blogs.technet.com/b/saantil/archive/2013/03/29/an-error-occurred-while-trying-to-connect-to-a-web-service.aspx

  • Ravi says:

    Hi,
    Thanks for the post. It worked like a charm. I have one specific issue, In my udcx file I specified Authentication. So my form uses this Authentication(username and password) and connects to UserProfile and UserGroup web services. The Strange thing I found is that, always the currentUserLogin name is equal to the username provided in the udcx file. Any thoughts?

  • Frustrated User says:

    I’ve tried it multiple times, now for 3 days ;( and keep getting this error

    The query cannot be run for the following DataObject: GetUserCollectionFromGroup
    InfoPath cannot run the specified query.
    The SOAP response indicates that an error occurred on the server:

    Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ was thrown.
    Group cannot be found.0×80131600

  • Patrick says:

    This is because for the authentication you use a different user. The web service will use the authentication credentials provided in you file, hence the same username no matter who opens the form :)

  • Patrick says:

    Judging by what you provided i’d say your fo cant find the group. It either does not exist or you are calling the web service the wrong site

  • Christopher Rogala says:

    I am not sure the step where you are updating the IsGroupMember field is correct. Based on the directions, the formula is

    count(translate(@LoginName[. = CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, abcdefghijklmnopqrstuvwxyz))

    I then receive an error on the count function. Shouldn’t the translate be part of the filter for the group data connection? Thoughts?

  • Christopher Rogala says:

    The way I solved the previous post dealing with the count() function was to add an action to the CurrentUserAccountName which convert all LoginName fields to lower case. I used the following steps:
    1) Select CurrentUserAccountName in the Main fields
    2) Click Manage Rules in the ribbon
    3) Click New->Action (optional: named the rule “Check Group Membership”)
    3) Click Add->Set a field’s value
    4) Click the tree button next to the Field textbox
    5) Select GetUserCollectionFromGroup->LoginName
    6) Click the function next to the Value textbox
    7) Use the steps provide in the example to create the function below:
    translate(@LoginName, “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”)

    This will convert the LoginName data field to lower case. You’re not done just yet, because you still have to set the IsGroupMember field in the Main.
    8) In the rules panel, click Add->Set a field’s value
    9) Click the tree button next to the Field textbox
    10) Select Main->IsGroupMember
    11) Click the function next to the Value textbox
    12) Add the count() function and double click on the link in the function to insert a field
    13) Filter to GetUserCollectionFromGroup
    14) Expand the tree of the data fields and select the LoginName
    15) Click Filter Data->Add
    16) LoginName should be selected on the left side dropdown
    17) In the right side drop down, choose the “select a field or group”
    18) Filter to Main
    19) Select CurrentuserAccountName
    20) Click through all the next and ok buttons

    Your formula should look like this: count(@LoginName[. = CurrentUserAccountName]). For testing, add the IsGroupMember, CurrentUserAccountName, and a repeating table for the GetUserCollectionFromGroup connection.

    Run the preview, and you should be golden!!

    CHEERS!!

  • Manoj Kumar says:

    Thanks for the post.
    i am getting the value “0″ even though the user is in the group or not.

    Thanks in advance

  • LEONARDI Thomas says:

    Hi all!
    Just for information:
    I followed this procedure (great thanks ^^) and I encountered a formula prob (like Viktor post for example):
    count(translate(@LoginName[.=CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))
    Argument 1 must return a node-set.
    –>count(translate(xdXDocument:GetDOM(“GetUserCollectionFromGroup”)/dfs:myFields/dfs:dataFields/ns1:GetUserCollectionFromGroupResponse/ns1:GetUserCollectionFromGroupResult/ns1:GetUserCollectionFromGroup/ns1:Users/ns1:User/@LoginName[. = xdXDocument:get-DOM()/my:myFields/my:CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))<–

    I had find an issu:
    You must use a third variable like this:

    Formula for IsGroupMember : count(IsGroupMemberTemp)
    Formula for IsGroupMemberTemp : translate(@LoginName[. = CurrentUserName], "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")

    And everything gonna be allright :)

  • Patrick says:

    Thanks for that Thomas :) Much appreciated!

  • Mostafa says:

    It seems every user is showing up as a member of the group. I put the GetUserCollectionFromGroup connection in a repeatable table and it shows the correct list of users, however when a user who is not in the group creates a new instance of the form, they have the value 1 even though they are not in that group.

  • Neil Norpa says:

    I followed this procedure, thanks.. and I have also encountered a formula problem
    :
    count(translate(@LoginName[.=CurrentUserAccountName], “ABCDEFGHIJKLMNOPQRSTUVWXYZ”, “abcdefghijklmnopqrstuvwxyz”))
    Argument 1 must return a node-set.

    What is the fix for this can someone please detail it.

  • Alan Paternoster says:

    Great article and really helped me out. Bravo!!! Patrick.
    Additional thanks to Thomas,,,,, I had the “Argument 1 must return a node-set” error and his TEMP field solved it.

  • Kishore says:

    Hi Patrick,
    Thanks for posting very usefull and efficient article. I have followed all the same steps in inofpath 2010 and published that as a “form library”. When I am opening the form i am getting the following error.

    An error occurred while trying to connect to a Web service.
    An entry has been added to the Windows event log of the server.
    Log ID:5566
    Correlation ID:e97d5a10-1841-4da6-a5c3-aa2133a3c7e7

    I have verifined the permissions of the group (“EveryOne” is slected). and I successfully browse and access both the web services.

    Please help me in this regard. Thanks Much.

  • Patrick says:

    Hi, have you checked the log files and what the error for the corresponding correlation ID is? Might give you more detail on the issue.
    Cheers,
    Pat

  • Ana says:

    Any chance of doing this without edting the .xsd fle?

  • Patrick says:

    Hi Ana, no unfortunately you can’t do that. If you look for a solution that can do this in an easier way, you might want to look at Nintex Forms.

  • rehan says:

    Hi,
    I am always getting value 1 for the “Isusergroup” no matter if the user is in group or not.
    Please help.

  • larry says:

    great post, besides a few tweaks I was able to make this work. so here is the $64k question. How can I make this with either multiple group names, of use a field (that has groupname value), most of the forms I deal with will refer to 5 maybe 6 groups. I would like to add 2 fields for each group. 1, group name and 2 groupnameIsInGroup without adding 5 to 6 data connections and having to manage them in the manifest

  • Matt J says:

    The most frustrating part of this is that the user info is case sensitive. DOMAIN\user is not the same as domain\user. In this article they try to translate the data to to proper format but I could never get that to work.. The functions would not take my syntax properly. (I saw a few above having the same issue.)

    So instead of having to translate I pulled data from another soap connection. For CurrentUserAccountName I queried the GetUserPropertyBtAccountName and used AccountName for the property name. Then all you have to do is point to “Value” for the default value. No translation, no filters, it pulls it as DOMAIN\user and matched up to the Login Name on the IsGroupMember field. Using the method above was giving me domain\user for one field and DOMAIN\user for the other. The way I ended up doing it brought them both back as DOMAIN\user.

    Hope this helps anyone struggling with the “Argument 1 must return a node-set” and translate issues.

  • Matt J says:

    Just to clarify above, you do NOT need to tranlate either one of the fields when using the GetUserPropertyByAccountName. They both come back as DOMAIN\user so no need to translate either of them.

  • This worked perfectly, thank you for the instructions! Fixed a requirement at work.

  • harley says:

    Great article, but is there anyway to use this with a SharePoint list infopath form that gets published back to the list as a browser based form?
    Editing the .xsd and .xsf files externally means they are not published back to SharePoint site.

  • Ashwani says:

    Hi Patrick,
    Thanks for the wonderful blog. Folllowing the steps mentioned in the blog. I made by Solution.
    It was working smoothly till lask weekend. But the server on which my site was hosted now changed to Claim based enviroment, i am now getting Error while connecting to webservice and my form load logic is also failing whic was based on the group membership of the soultion user.
    Please help me on this
    Thanks in advance.

  • Patrick says:

    unfortunately no. I haven’t come across a way to achieve this with an InfoPath list form. If you would like to look into Nintex Forms as an alternative where we provide an inline function that provides exactly what you are after.

  • Chris OConnor says:

    This method doesn’t work in SP2013 – must be related to CLAIMS. Everytime I try to use the Web Service, it just errors with “user not found”.

    Has anyone got a better answer than “use Nintex Forms” ?? :-P

  • vino says:

    I tried to check a user whether he exists in a particular group and set this user in a textbox. So my textbox default value should be like this @LoginName[.=LoginUser]. it worked fine.

    but after publish and few hours later this connection is beaked and showed like below.

    GetDOM(“GetUserCollectionFromGroup”)/dfs:myFields/dfs:dataFields/ns2:GetUserCollectionFromGroupResponse/ns2:GetUserCollectionFromGroupResult/ns2:GetUserCollectionFromGroup/ns2:Users/ns2:User/@LoginName[. = get-DOM()/my:myFields/my:HiddenControls/my:LoginUser]

    I checked the data connection and it showed just the group name. User and its parameters were not there. I modified GetUserCollectionFromGroup1.xsd several time and found the same issue. Can anyone please tell me how to resolve this?

1 2

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Visit Us On TwitterVisit Us On Linkedin