Additional Functions

Oct 27, 2015 at 2:31 PM
Hi,
Sorry if this is in the wrong place. I've been looking for a method to administer a 365 site (we're end users, not site admins). This project seems to be perfect for my needs, so thankyou.

I did find that it didn't quite meet my needs and have added a new module where i've made changes. I've never shared anything like this before, but i can't believe i'm the only user that needs it. Also i'm very new to powershell so i've done my best to be functional, but its probably a bit clunky at the moment.

I've added 3 functions, 2 are probably more supportive so i could workout the final requirements.
What i needed was an ability to set permissions on subfolders of a library, the depth of these folders would vary. I've used your set-documentpermissions as a starting point, calling mine set-folderpermissions. Of cause the camlquery was the major headache, and i assume it will work, but can't test on any other system other than mine.

Part 2 of the requirement was to set the role to "contribute (wd)" (not sure if this is standard on all 365 sites, but proves useful to our needs - without delete). However this means i don't have a roletype, but i do have a role name. This is the function list-roles. it also explains the function GetRoleByName as i followed what was already written.

Hopefully this explains the additional parameter "$rolename" for the set-folderpermissions. Also the $foldername is based from the root of the site including the folder structure you have "/sites/Main-site/sub-site/library/folder/subfolder/subfolder".

Hopefully this all makes sense and will make it into the project in some form (hopefully better than i've done) as i think it would be very useful to others (i know subfolder permissions isn't a good thing with sharepoint, but we do what we must). Below hopefully is my your/my code, and thanks for doing such a good job so far. Its taught me most of what i now can do in powershell.
#----------------------------------------------------------------------------- 
# Filename : ga.Permissions.ps1 
#----------------------------------------------------------------------------- 
# Author : Gerald Abbot
#----------------------------------------------------------------------------- 
# Contains methods to manage users, groups and permissions. -Additions to spps.usersandgroups.psm1



# None, Guest, Reader, Contributor, WebDesigner, Administrator, Editor


function Set-FolderPermissions
{
    [CmdletBinding()]
    param
    (   
        [Parameter(Mandatory=$true, Position=1)]
        [string]$groupname,

        [Parameter(Mandatory=$true, Position=2)]
        [string]$listname,

        [Parameter(Mandatory=$true, Position=3)]
        [string]$roleType,

        [Parameter(Mandatory=$false, Position=4)]
        [string]$roleName,

        [Parameter(Mandatory=$true, Position=5)]
        [string]$folderName,

        [Parameter(Mandatory=$true, Position=6)]
        [string]$permKeep,

        [Parameter(Mandatory=$true, Position=7)]
        [string]$permReset
    )

    process
    {
        Write-Host "Creating permissions for list $listname and $folderName folder for the group $groupname and role $roleType" -foregroundcolor black -backgroundcolor yellow

        # Try getting the SPWeb object

        $web = $Spps.Web

        # get the Role
        #$roleTypeObject = [Microsoft.SharePoint.Client.RoleType]$roleType
        #$role = GetRole $roleTypeObject

        if ($roleType -eq "None"){
        
            $roleTypeObject = [Microsoft.SharePoint.Client.RoleType]$roleType
            $role = GetRoleByName $roleName
            } else {
            $roleTypeObject = [Microsoft.SharePoint.Client.RoleType]$roleType
            $role = GetRole $RoleTypeObject
            }

        # get the group principal object
        $group = Get-Group $groupname
 
        # get the list
        $list = $web.Lists.GetByTitle($listname)
        $searchName =  [string]$folderName #$list.parentWebUrl + "/" +
        Write-Host $searchName

        $camlQuery = new-object Microsoft.SharePoint.Client.CamlQuery
        #$camlQuery.ViewAttributes ="Scope='RecursiveAll'"
        #$camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>$listItemName</Value></Eq></Where></Query></View>"

        #$camlQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='FileRef' /><Value Type='Lookup'>$searchName</Value></Eq></Where></Query><QueryOptions><ViewAttributes Scope='RecursiveAll' /></QueryOptions></View>"

       # $camlQuery.ViewXml = "<View><Query><Where><And><Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq><Eq><FieldRef Name='FileRef' /><Value Type='Text'>$searchName</Value></Eq></And></Where><QueryOptions><ViewAttributes Scope='RecursiveAll' /><Lists ServerTemplate='101' /></QueryOptions><ViewFields><FieldRef Name='FileLeafRef' /><FieldRef Name='FileRef' /></ViewFields></Query></View>"
        $camlQuery.ViewXml = "<View Scope='RecursiveAll'><Query><Where><And><Eq><FieldRef Name='FSObjType' /><Value Type='Lookup'>1</Value></Eq><Eq><FieldRef Name='FileRef' /><Value Type='Lookup'>$searchName</Value></Eq></And></Where></Query></View>"



        $listItems = $list.GetItems($camlQuery)


        
        $Spps.Load($listItems)
        $Spps.ExecuteQuery()

        Write-Host $listItems.Count
        if ($listItems.Count -gt 0)
        {
            
            $listItem = $listItems[0]

            $Spps.Load($listItem)
            $Spps.ExecuteQuery()


            # calling nongeneric method Spps.Load(list, x => x.HasUniqueRoleAssignments)
            $method = [Microsoft.Sharepoint.Client.ClientContext].GetMethod("Load")
            $loadMethod = $method.MakeGenericMethod([Microsoft.Sharepoint.Client.ListItem])

            $parameter = [System.Linq.Expressions.Expression]::Parameter(([Microsoft.SharePoint.Client.ListItem]), "x")
            $expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::Property($parameter, ([Microsoft.SharePoint.Client.ListItem]).GetProperty("HasUniqueRoleAssignments")), ([System.Object])), $($parameter))
            $expressionArray = [System.Array]::CreateInstance($expression.GetType(), 1)
            $expressionArray.SetValue($expression, 0)

            $loadMethod.Invoke( $Spps, @( $listItem, $expressionArray ) )

            $Spps.ExecuteQuery()


            # break the inheritance if not done already
            if (-not $listItem.HasUniqueRoleAssignments)
            {
                $listItem.BreakRoleInheritance($permKeep, $false) # don't (false) # keep the existing permissions and don't clear listitems permissions
                
                $Spps.ExecuteQuery()
            } Else {

                if ($permReset -eq $true) 
                {
                    $listItem.ResetRoleInheritance()   # BreakRoleInheritance($permKeep, $false) # don't (false) # keep the existing permissions and don't clear listitems permissions
                
                    $Spps.ExecuteQuery()
                
                    $listItem.BreakRoleInheritance($permKeep, $false) # don't (false) # keep the existing permissions and don't clear listitems permissions
                
                    $Spps.ExecuteQuery()
                }

            }


 
            # create the role definition binding collection
            $rdb = New-Object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Spps)
 
            # add the role definition to the collection
            $rdb.Add($role)
 
            # create a RoleAssigment with the group and role definition
            $ra = $listItem.RoleAssignments.Add($group, $rdb)
 
            # execute the query to add everything
            $Spps.ExecuteQuery()        

            Write-Host "Succesfully created permissions" -foregroundcolor black -backgroundcolor green

        } else {
            Write-Host "Item $folderName could not be found" -foregroundcolor black -backgroundcolor red
        }
    }
}



Function List-Roles
{
    [CmdletBinding()]
    #param
    #(
#       [Parameter(Mandatory=$true, Position=1)]
#       [Microsoft.SharePoint.Client.RoleType]$rType
#   )

    $web = $Spps.Web
    if ($web -ne $null)
    {
     $roleDefs = $web.RoleDefinitions
     $Spps.Load($roleDefs)
     $Spps.ExecuteQuery()
    # $roleDef = $roleDefs | where {$_.RoleTypeKind -eq $rType}
    # return $roleDef

        foreach ($roleDef in $roleDefs)
        {
            Write-Host "type : " $roleDef.RoleTypeKind " and " " Name :" $roleDef.Name
        }

    }
    return $null
}

Function GetRoleByName
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, Position=1)]
        [String]$rName
    )

    $rType = [Microsoft.Sharepoint.Client.RoleType]"None"

    $web = $Spps.Web
    if ($web -ne $null)
    {
     $roleDefs = $web.RoleDefinitions
     $Spps.Load($roleDefs)
     $Spps.ExecuteQuery()
     $roleDef = $roleDefs | where {$_.RoleTypeKind -eq $rType -and $_.Name -eq $rName}
     return $roleDef
    }
    return $null
}