1

I am new to SharePoint and CSOM, but I am comfortable in PowerShell and .NET. I'm trying to do the following tasks in SharePoint Online:

  1. Get the list of users in a particular named group
  2. For each user, create a folder
  3. For each folder created, break inheritance with the parent folder and assign exclusive access to its respective user

For the first task, I've tried the following code:

# Get a specific group by name
$allGroups = $web.SiteGroups
$ctx.Load($allGroups)
$ctx.ExecuteQuery()
$group = $allGroups.GetByName('My Group')

# Get all users in the group 'My Group'
$users = $group.Users
$ctx.Load($users)
$ctx.ExecuteQuery()

The GroupCollection.GetByName method always gives me a "collection has not been initialized" error. I know that $allGroups is initialized because I am able to query other properties such as $allGroups.Count. What am I doing wrong? Is there another way to retrieve a particular group by name?

The second task should be straightforward. I already have successfully created new folders, so I just need to use a foreach loop to accomplish this step.

I haven't been able to test the third task yet, but I have seen plenty of code samples online for breaking inheritance, and I expect that adding a permission for a user won't be too difficult. I'll edit this question if I run into problems, but in the meantime, some sample code to get me started would be very appreciated.

2 Answers 2

2

As Mike mentioned earlier I would definitely use the PnP PowerShell command-lets. It saves you a lot of typing. I have put together a little script doing 99 % of what you are asking for.

Connect-PnPOnline -Url https://yoursiteurl
$group = Get-PnPGroup "groupname"
foreach ($user in $group.Users) {
    Write-Host "Creating folder for $($user.Title)"
    Add-PnPFolder -Name $user.Title -Folder "Shared Documents"
    $folder = Get-PnPFolder -Url "shared documents/$($user.Title)" -Includes ListItemAllFields
    Set-PnPListItemPermission -User $user.Title -AddRole 'Contribute' -List Documents -Identity $folder.ListItemAllFields.Id -ClearExisting
}

The only caveat with this approach is that it seems to add the user executing the script to the folder as well (with full control).

You can find a full reference for the used command-lets here: https://msdn.microsoft.com/en-us/pnp_powershell/pnp-powershell-overview

The ListItemAllFields property of the folder is necessary to retrieve in order to get the actual list item ID of the folder. Everything in a document library or list has a list item ID. The ID is required to set the permissions on the folder.

2
  • This is perfect, thank you! I started out with the PnP cmdlets but didn't realize that you could use Set-PnPListItemPermission on a folder. Commented Feb 5, 2018 at 22:07
  • You are welcome. Glad to hear it is useful to you! Commented Feb 6, 2018 at 10:28
0

You probably need another ctx.Load

$group = $allGroups.GetByName('My Group')
$ctx.Load($group)

Each time you drill down into a child object you will probably need to make another round trip to the server with a ctx.Load().

As you are doing this in PowerShell, you may want to take a look at the SharePoint PnP cmdlets that basically wrap up all of the CSOM.

https://dev.office.com/patterns-and-practices

https://github.com/SharePoint/PnP

https://docs.microsoft.com/en-us/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.