Link to home
Start Free TrialLog in
Avatar of CLR Benjamin
CLR BenjaminFlag for France

asked on

Sharepoint 2013 edit permissions powershell

Hello,

We have sharepoint 2013 with one farm with two fronts, and still we doing a migration from a file server.

I need a powershell script to edit/add permissions on documents.

Here the scenario:

"https://sharepoint.contoso.com/Clients" is the site
In "clients", I have 85 folders like this : Client1 / Client2 / Client3...
On my file server, I extracted for each Client, permissions by users. So I have many CSV :

(I extracted only coworker permissions)
Client1.csv  | Column A   ~~ Client2.csv | Column A
                LGeorge                     BLucas
                BLucas                      SDenis
...

Open in new window


I want to make a powershell with the command "For-each" users in csv,  to add permissions in sharepoint to the folder Client1/2/3...
Problem is, I don't know the powershell command to add permissions on each folder in Sharepoint and break inheritance when I need to.

I heard about csom but dont know how it works, can you help me or guide me about this problem?

Thanks in advance
Avatar of Jamie McAllister
Jamie McAllister
Flag of Switzerland image

This is doable but I have some misgivings about so many custom permissions. First they're hard to manage, and second can affect performance (though 85 probably will be safe in that respect).

Better to refactor the structure using libraries and groups.

However I have created multiple libraries and broken permission inheritance with the script below, and this could easily be changed to do that for folders;



function Create-SPLists {

$libraryobjects = Import-CSV C:\Libs.CSV -Header Name,URL

ForEach ( $libraryobject in $libraryobjects ) {

New-SPList -Web http://MySite/MyWeb -ListTitle $libraryobject.Name -ListUrl $libraryobject.URL -Description "My Library" -Template "Document Library"

}

}

function New-SPList {
   
    [CmdletBinding()]
    Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [string]$Web,
    [Parameter(Mandatory=$true)]
    [string]$ListTitle,
    [Parameter(Mandatory=$true)]
    [string]$ListUrl,
    [Parameter(Mandatory=$false)]
    [string]$Description,
    [Parameter(Mandatory=$true)]
    [string]$Template
    )
Start-SPAssignment -Global
$SPWeb = Get-SPWeb -Identity $Web
$listTemplate = $SPWeb.ListTemplates[$Template]
$SPWeb.Lists.Add($ListUrl,$Description,$listTemplate)
$list = $SPWeb.Lists[$ListUrl]
$list.Title = $ListTitle
$list.EnableVersioning = $true
$list.EnableMinorVersions = $true
 $list.MajorVersionLimit = 2
 $list.MajorWithMinorVersionsLimit = 5
$list.OnQuickLaunch = $true
$list.EmailAlias = "string_value" #should be the email first part only, e.g. "test" in "test@example.com"
$list.RootFolder.Properties.Add("vti_emailoverwrite", 1) #1 = true, 0 = false
$list.RootFolder.Properties.Add("vti_emailsaveoriginal", 1) #1 = true, 0 = false
$list.RootFolder.Properties.Add("vti_emailattachmentfolders", "root") #valid values are "root", "sender", and "subject"
$list.RootFolder.Properties.Add("vti_emailusesecurity", 0) #1 = true - Use Document Library Permissions, 0 = false - Allow All/Anonymous
$list.BreakRoleInheritance($true,$true)
$list.Update()
$SPWeb.Dispose()
Stop-SPAssignment -Global
}

Create-SPLists
Avatar of CLR Benjamin

ASKER

Thank you for this script.

I try to understand it, I'm not a sharepoint expert. But I think I get it.

But for this:  Import-CSV C:\Libs.CSV -Header Name,URL

How should be the CSV? And where should I find URL for folders?  With sharepoint explorer on each folder?

When I launch the script with this informations:
function Create-SPLists {
Add-PSSnapin Microsoft.Sharepoint.Powershell
New-SPList -Web https://sharepoint.contoso.com/clients -ListTitle Lgeorge -ListUrl "https://sharepoint.contoso.com/clients/Documents partages/Clients/client1" -Description "My Library" -Template "Document Library"

Open in new window


I have errors:

'Exception calling "Add" with "3" argument(s) « Value cannot be null
Nom du paramètre : Argument « template » non valide de la méthode SPListCollection.Add(). Passez un argument du type approprié. »
Au caractère Ligne:25 : 1
+ $SPWeb.Lists.Add($ListUrl,$Description,$listTemplate)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException
 
Propriété « Title » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:27 : 1
+ $list.Title = $ListTitle
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « EnableVersioning » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:28 : 1
+ $list.EnableVersioning = $true
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « EnableMinorVersions » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:29 : 1
+ $list.EnableMinorVersions = $true
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « MajorVersionLimit » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:30 : 1
+ $list.MajorVersionLimit = 2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « MajorWithMinorVersionsLimit » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:31 : 1
+ $list.MajorWithMinorVersionsLimit = 5
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « OnQuickLaunch » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:32 : 1
+ $list.OnQuickLaunch = $true
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
Propriété « EmailAlias » introuvable dans cet objet. Assurez-vous qu’elle existe et qu’elle peut être définie.
Au caractère Ligne:33 : 1
+ $list.EmailAlias = "Lgeorge"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:34 : 1
+ $list.RootFolder.Properties.Add("vti_emailoverwrite", 1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:35 : 1
+ $list.RootFolder.Properties.Add("vti_emailsaveoriginal", 1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:36 : 1
+ $list.RootFolder.Properties.Add("vti_emailattachmentfolders", "root")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:37 : 1
+ $list.RootFolder.Properties.Add("vti_emailusesecurity", 0)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:38 : 1
+ $list.BreakRoleInheritance($true,$true)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
You cannot call a method on a null-valued expression.
Au caractère Ligne:39 : 1
+ $list.Update()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Open in new window



Where am I wrong?
I suggest you create the libary first then run the following to create the folders.

$ErrorActionPreference = "Stop"
$ver = $host | select version 
if($Ver.version.major -gt 1) {$Host.Runspace.ThreadOptions = "ReuseThread"} 
if(!(Get-PSSnapin Microsoft.SharePoint.PowerShell -ea 0)) 
{ 
Write-Progress -Activity "Loading Modules" -Status "Loading Microsoft.SharePoint.PowerShell" 
Add-PSSnapin Microsoft.SharePoint.PowerShell 
} 
 
$DestinationWebURL = "http://MyDomain/sites/MySiteCollection/MySubSite" 
$DestinationLibraryTitle = "My Target Library" 
$folderInfos = Import-CSV C:\MyScripts\MyFolders.csv -Header Name

$dWeb = Get-SPWeb $DestinationWebURL 
$dList = $dWeb.Lists | ? {$_.title -like $DestinationLibraryTitle} 

#$cType = $dList.ContentTypes["Folder"] 

foreach($folderInfo in $folderInfos) 
{ 
Write-Host "Creating " $folderInfo.Name
	$folder = $dList.AddItem("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $folderInfo.Name)
	
    $folder["Title"] = $folderInfo.Name
    $folder.Update();
}

Open in new window


However if you want custom permissions you'll have to take the bit of teh first script about breaking inheritance and apply that to the $folder variable in this new script.
Ok, now you lost me... I just need to edit folders permissions, for example: add  read/edit rights on folder Client1 for AD user Jgeorge.

I don't know how to explain it but I can't link folders in a variable and then edit permissions...
So: here my sharepoint
User generated image
And here folders I want to edit:
User generated image
Then when I do this part of your script I have this result:

 $dweb | select-object -ExpandProperty lists | fl title


Title : Calendrier
Title : Demandes d'accès
Title : Dossiers Archives
Title : Dossiers Assistantes
Title : Dossiers Clients
Title : Dossiers Manager
Title : fpdatasources
Title : Galerie Pages maîtres
Title : Microflux
Title : Pages du site
Title : Pièces jointes
Title : Présentations composées
Title : Tâches
Title : wfsvc
Title : Workflow History

Open in new window


And the path when I open folder "dossiers clients" in windows explorer is : https://sharepoint.domain.com/site/Documents partages/Dossiers Clients

I don't know if this is me who missing something in your script or just have a lack of knowledge in Sharepoint/Powershell...
It would be a pleasure to understand your step, if you can guide me. Or if you know a third party software that do the job?

Thank you
Here the final script I made, and working:

import-module activedirectory
Add-PSSnapin Microsoft.SharePoint.PowerShell 
del "C:\Users\spfarm\Desktop\report.csv"

#variables 
$siteName = "https://sharepoint.contoso.com/site"
$listName = "Dossiers Clients"
$permissionLevel = "Modification"  #"contribute" in english
#$userTest = "domain\test"

#Creations objets 
$site = new-object Microsoft.SharePoint.SPSite($siteName)
$web = $site.OpenWeb()
$doclib=[Microsoft.SharePoint.SPDocumentLibrary]$web.Lists[$listName]
$foldercoll=$doclib.Folders;

function GrantUserpermission($userName)
 {
   #add permission for user on folder 
  $spuser=$web.EnsureUser($userName)
  $sproleass=new-object Microsoft.SharePoint.SPRoleAssignment([Microsoft.SharePoint.SPPrincipal]$spuser)
  $folder.BreakRoleInheritance("true")
  $sproleass.RoleDefinitionBindings.Add($web.RoleDefinitions[$permissionLevel])
  $folder.RoleAssignments.Add($sproleass);
 }
 
# read CSV
Import-Csv C:\SP.csv | foreach {
$login = $_.login
$dossier = $_.dossier

foreach($folder in $foldercoll)
 {
 #take only folder in level 2 from url : "https://sharepoint.contoso.com/site/level1/level2/level3"
  if($folder.Name.Equals($dossier) -and ($folder.Url.ToString().Split('\/').Count -eq 3))
  {
   try
   {
    GrantUserPermission($login)

    #Success Message
     New-Object PSObject -Property @{
        User = $login

        Status = "Permissions granted to $dossier"
     }
   }
   Catch 
   {
     #Failed Message
     New-Object PSObject -Property @{
        User = $login
        Status = "permissions failed $($_.exception)"
     }| Export-csv –append  C:\Users\spfarm\Desktop\report.csv -nti
   }
  }
 }
}

$web.Close()
$site.Dispose()
Write-Host "Completed...."

Open in new window


Here the CSV

"login","dossier"
"domain\XXXusertestrerrorXXX","test"
"domain\test","test"

Open in new window


Thank you for your help!
ASKER CERTIFIED SOLUTION
Avatar of Jamie McAllister
Jamie McAllister
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Nice help and btw nice teaching