Dans le cadre de la gestion de contenu SharePoint Online et surtout dans un contexte de migration, les droits “Site Collection Administrator” sont à proscrire pour les “Site Onwers”, il est bien préférable de mettre ces personnes dans le groupe d’origine “Site Owners”.
Le problème se présente rapidement avec les personnes jouant avec ces permissions et décidant de casser celles-ci jusqu’à la suppression de son propre groupe. C’est aussi dans un contexte de migration la réinitialisation de tout le contenu au niveau de ces permissions.
Ainsi ce script PowerShell utilise le module CSOM afin de boucler dans tous les sites et sous-sites afin de donner le droit “Full Control” au groupe voulu au niveau de chaque sous-site, mais aussi au niveau de chaque liste (en revanche je ne parcoure pas le niveau des items volontairement).
Dans le même temps, le script assigne l’adresse email spécifié dans les “Site access request” afin de déléguer la gestion de ces permissions au propriétaire du site.
[string]$username = "LoginAccount@tenant.onmicrosoft.com"
[string]$PwdTXTPath = "C:\\SECUREDPWD\ExportedPWD-$($username).txt"[string]$SPOSiteCollectionURLToSet = “https://tenant.sharepoint.com/sites/MySiteCollection”
[string]$RootSiteOwnerGroupToSet = "MySiteCollection Owners"
[string]$SiteOwnerEmailAdress = "SiteOnwerEmail@mycompany.com"
[boolean]$ChangeRequestAccessEmail = $false
[string]$RoleTypeToApply = "Administrator"function Load-DLLandAssemblies
{
[string]$defaultDLLPath = ""# Load assemblies to PowerShell session
$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
[System.Reflection.Assembly]::LoadFile($defaultDLLPath)$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
[System.Reflection.Assembly]::LoadFile($defaultDLLPath)$defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll"
[System.Reflection.Assembly]::LoadFile($defaultDLLPath)
}Function Invoke-LoadMethod() {
param(
[Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),
[string]$PropertyName
)
$ctx = $Object.Context
$load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load")
$type = $Object.GetType()
$clientLoad = $load.MakeGenericMethod($type)
$Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
$Expression = [System.Linq.Expressions.Expression]::Lambda(
[System.Linq.Expressions.Expression]::Convert(
[System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),
[System.Object]
),
$($Parameter)
)
$ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
$ExpressionArray.SetValue($Expression, 0)
$clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}Function Add-Group-As-FullPermission-InSPWeb()
{
Param(
[Microsoft.SharePoint.Client.ClientContext]$Context,
[string]$SPGroupName,
[Microsoft.SharePoint.Client.Web]$SPWeb,
[string]$RoleType
)
Write-Host " ---------------------------------------------------------"# get group/principal
$Mygroups = $SPWeb.SiteGroups
$MyRootWeb = $Context.Site.RootWeb
$context.Load($MyRootWeb)
$Context.Load($Mygroups)
$Context.ExecuteQuery()
<#
foreach($MyTempGroup in $Mygroups)
{ Write-Host " --->>> Group In Group List: ", $MyTempGroup.Title }
#>
$Mygroup = $Mygroups | where {$_.Title -eq $SPGroupName}
#$MyRoleType = [Microsoft.SharePoint.Client.RoleType]$Roletype
$roleDefs = $SPWeb.RoleDefinitions
$Context.Load($roleDefs)
$Context.ExecuteQuery()
$roleDef = $roleDefs | where {$_.RoleTypeKind -eq $Roletype}
Write-Host " --- Role Definition: ", $roleDef.Name
Write-Host " --- Group Name: ", $Mygroup.Title, " - Original Name:", $SPGroupName
try{
$collRdb = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Context)
$collRdb.Add($roleDef)
$collRoleAssign = $SPWeb.RoleAssignments
$rollAssign = $collRoleAssign.Add($Mygroup, $collRdb)
$Context.ExecuteQuery()
Write-Host " >>>>> Permissions assigned successfully." -ForegroundColor Green
}
catch{
write-host " !!!!!!! info: $($_.Exception.Message)" -foregroundcolor red
}Write-Host " ---------------------------------------------------------"
}Function Add-Group-As-FullPermission-InSPList()
{
Param(
[Microsoft.SharePoint.Client.ClientContext]$Context,
[string]$SPGroupName,
[Microsoft.SharePoint.Client.Web]$SPWeb,
[Microsoft.SharePoint.Client.List]$SPList,
[string]$RoleType
)
Write-Host " ---------------------------------------------------------"# get group/principal
$Mygroups = $SPWeb.SiteGroups
$MyRootWeb = $Context.Site.RootWeb
$context.Load($MyRootWeb)
$Context.Load($Mygroups)
$context.Load($SPList)
$Context.ExecuteQuery()<#
foreach($MyTempGroup in $Mygroups)
{ Write-Host " --->>> Group In Group List: ", $MyTempGroup.Title }
#>
$Mygroup = $Mygroups | where {$_.Title -eq $SPGroupName}
#$MyRoleType = [Microsoft.SharePoint.Client.RoleType]$Roletype
# get role definition
$roleDefs = $SPWeb.RoleDefinitions
$Context.Load($roleDefs)
$Context.ExecuteQuery()
$roleDef = $roleDefs | where {$_.RoleTypeKind -eq $Roletype}
Write-Host " --- Role Definition: ", $roleDef.Name
Write-Host " --- Group Name: ", $Mygroup.Title, " - Original Name:", $SPGroupName
try{
$collRdb = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Context)
$collRdb.Add($roleDef)
$collRoleAssign = $SPList.RoleAssignments
$rollAssign = $collRoleAssign.Add($Mygroup, $collRdb)
$Context.ExecuteQuery()
Write-Host " >>>>> Permissions assigned successfully." -ForegroundColor Green
}
catch{
write-host " !!!!!!! info: $($_.Exception.Message)" -foregroundcolor red
}Write-Host " ---------------------------------------------------------"
}function Check-Permission-InLists
{
Param(
[Microsoft.SharePoint.Client.ClientContext]$Context,
[Microsoft.SharePoint.Client.Web]$SPWeb
)$Mylists = $SPWeb.Lists;
$Context.Load($Mylists)
#you can use one execute per multiple loads
$Context.ExecuteQuery();
Write-host " ---- CHECK IN LISTS --- "
foreach($myList in $MyLists)
{
Write-host " ==== List Name:", $mylist.Title
if($mylist.hidden -eq $false)
{
Write-host " ====> List Name not hidden:", $mylist.Title -ForegroundColor Yellow
Invoke-LoadMethod -Object $myList -PropertyName "HasUniqueRoleAssignments"
$context.ExecuteQuery()
if($myList.HasUniqueRoleAssignments)
{
Write-Host " -->> List in the SPWeb:", $myList.Title -ForegroundColor Yellow
Write-Host " -->> Has Unique Permissions:", $myList.HasUniqueRoleAssignmentsAdd-Group-As-FullPermission-InSPList -Context $Context -SPGroupName $RootSiteOwnerGroupToSet -SPWeb $SPWeb -SPList $myList -RoleType $RoleTypeToApply
}
}
}
}function Get-SPOSubWebs
{
Param(
[Microsoft.SharePoint.Client.ClientContext]$Context,
[Microsoft.SharePoint.Client.Web]$RootWeb
)
$Webs = $RootWeb.Webs
$Context.Load($Webs)
$Context.ExecuteQuery()
ForEach ($sWeb in $Webs)
{
Write-host " -------------------------------------------------------- "
Write-host " -->> SubSite:", $sWeb.URL -ForegroundColor green
Invoke-LoadMethod -Object $sWeb -PropertyName "HasUniqueRoleAssignments"
$context.ExecuteQuery()
Write-Host " -->> Has Unique Permissions:", $sWeb.HasUniqueRoleAssignmentsif($sWeb.HasUniqueRoleAssignments)
{
Invoke-LoadMethod -Object $sWeb -PropertyName "RequestAccessEmail"
$context.ExecuteQuery()
Write-Host " -->> Request Access Email Before change:", $sWeb.RequestAccessEmail
if(($ChangeRequestAccessEmail) -and ($sWeb.RequestAccessEmail -ne $SiteOwnerEmailAdress))
{
Write-Host " ===->> Request Access Email to change"
$sWeb.RequestAccessEmail = $SiteOwnerEmailAdress
$sWeb.Update()
$context.ExecuteQuery()
Invoke-LoadMethod -Object $sWeb -PropertyName "RequestAccessEmail"
$context.ExecuteQuery()
Write-Host " -->> Request Access Email After change:", $sWeb.RequestAccessEmail
}Add-Group-As-FullPermission-InSPWeb -Context $Context -SPGroupName $RootSiteOwnerGroupToSet -SPWeb $sWeb -RoleType $RoleTypeToApply
}Check-Permission-InLists -Context $Myctx -SPWeb $sWeb
Get-SPOSubWebs -Context $Context -RootWeb $sWeb
}
}function Reset-Group-OwnerShip
{
Param(
[Microsoft.SharePoint.Client.ClientContext]$Context,
# [Microsoft.SharePoint.Client.Web]$SPWeb,
[string]$GroupOwnerName
)
$MyRootWeb = $Context.Site.RootWeb
$Mygroups = $MyRootWeb.SiteGroups
$context.Load($MyRootWeb)
$Context.Load($Mygroups)
$Context.ExecuteQuery()foreach($MyTempGroup in $Mygroups)
{
Write-Host " --->>> Group Name: ", $MyTempGroup.Title
$ThegroupOwner = $Context.Web.SiteGroups.GetByName($GroupOwnerName);
$MyTempGroup.Owner = $ThegroupOwner
$MyTempGroup.Update()
$Context.ExecuteQuery()
}
}function SetGroupAsFullOwner([string]$MyRootWebURL)
{
[bool]$CreateSGSDocLibList = $false
$Myctx = New-Object Microsoft.SharePoint.Client.ClientContext($MyRootWebURL)
$secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath)
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd
$Myctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($creds.UserName,$creds.Password)
$Myctx.RequestTimeout = 1000000 # milliseconds
$MyspoRootweb = $Myctx.Web
$Myctx.Load($MyspoRootweb)
$Myctx.ExecuteQuery()Write-Host " "
Write-Host " ---------------------------------------------------------"
Write-Host " >>>> # Server Version:" $Myctx.ServerVersion " # <<<<<<" -ForegroundColor Green
Write-Host " ---------------------------------------------------------"
Write-Host " "Write-host " -------------------------------------------------------- "
Write-host " -->> RootSite:", $MyspoRootweb.URL -ForegroundColor greenReset-Group-OwnerShip -Context $Myctx -GroupOwnerName $RootSiteOwnerGroupToSet
Invoke-LoadMethod -Object $MyspoRootweb -PropertyName "RequestAccessEmail"
$Myctx.ExecuteQuery()
Write-Host " -->> Request Access Email Before change:", $MyspoRootweb.RequestAccessEmail
if($MyspoRootweb.RequestAccessEmail -ne $SiteOwnerEmailAdress)
{
Write-Host " ===->> Request Access Email to change"
$MyspoRootweb.RequestAccessEmail = $SiteOwnerEmailAdress
$MyspoRootweb.Update()
$Myctx.ExecuteQuery()
Invoke-LoadMethod -Object $MyspoRootweb -PropertyName "RequestAccessEmail"
$Myctx.ExecuteQuery()
Write-Host " -->> Request Access Email After change:", $MyspoRootweb.RequestAccessEmail
}Check-Permission-InLists -Context $Myctx -SPWeb $MyspoRootweb
Get-SPOSubWebs -Context $Myctx -RootWeb $MyspoRootweb
}cls
Load-DLLandAssembliesSetGroupAsFullOwner $SPOSiteCollectionURLToSet
Ce script est utilisé, testé et validé depuis des mois et fonctionne parfaitement, avec un test max d’une collection ayant 2900 sous-sites.
Fabrice Romelard [MBA Risk Management]
Sites utilisés pour certaines parties:
- https://gist.github.com/star-crossed/0062ec1e5ef622a4c8e8
- http://sharepoint.stackexchange.com/questions/126221/spo-retrieve-hasuniqueroleassignements-property-using-powershell
- https://social.technet.microsoft.com/wiki/contents/articles/31157.manage-sharepoint-online-access-requests-using-powershell.aspx
- https://blogs.msdn.microsoft.com/chandru/2015/12/31/sharepoint-onlinecsom-change-access-requests-settings/
- http://www.sharepointdiary.com/2014/12/delete-unique-permissions-reset-broken-inheritance-using-powershell.html
- https://gist.github.com/asadrefai/b854cf8ca1719a3fcc73
- https://gallery.technet.microsoft.com/office/Script-to-get-All-Webs-in-c2c1cdaf
Commentaires
Enregistrer un commentaire