views:

1470

answers:

2

So I have a boat load of pivot tables that I upload everyday to folders like: Pivot0001 Pivot0002 Pivot0003

and so on.

I also have user groups called Pivot0001 and so on with users that need to access that folder in it. What I now need to do is set the permissions on each folder (I have 400 or so of them). I know I need to do a loop and set permissions. What I dont know how to do is get a list of all the folders and then set permissions to that folder.

EDIT I forgot to say this is for SharePoint...sorry about that

Here is the final code that worked (not really clean but it works)

[Void][System.Diagnostics.Stopwatch] $sw;
$sw = New-Object System.Diagnostics.StopWatch;
$sw.Stop();
$sw.Start();
clear   

$path = "\\path\to\webdav\"
$dirs = Get-ChildItem $path -Recurse | Where-Object { $_.Attributes -band [System.IO.FileAttributes]::Directory }
[Void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint");
$SPSite = New-Object Microsoft.SharePoint.SPSite("http://sharepoint");
$OpenWeb = $SpSite.OpenWeb("/Downloads");
[int]$i = 0;
foreach ($dir in $dirs) {
    $i++
    Write-Host "Setting $dir to $dir" -F Green;
    $path = "http://sharepoint/Downloads/" + $dir;
    $TheNewGroup = $OpenWeb.GetFolder($path);
    [Microsoft.SharePoint.SPFolder]$folder = $OpenWeb.GetFolder($path);
    [Microsoft.SharePoint.SPGroupCollection]$spc = $OpenWeb.SiteGroups;
    [Microsoft.SharePoint.SPGroup]$group = $spc[$dir];
    [Microsoft.SharePoint.SProleAssignment]`
     $roleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment([Microsoft.SharePoint.SPPrincipal]$group);
    $OpenWeb.GetFolder($path).Item.BreakRoleInheritance("true");
    $roleAssignment.RoleDefinitionBindings.Add($OpenWeb.RoleDefinitions["Read"]);
    $OpenWeb.GetFolder($path).Item.RoleAssignments.Add($roleAssignment);
}
Write-Host "found $i Folders" -F Green
$SPSite.Dispose();
$sw.Stop();
$howlong = $sw.Elapsed.ToString();
write-host "Took: " $howlong -f Green;
A: 

Getting a list of folders isn't exactly straightforward, but easily understandable:

Get-ChildItem \downloads\pivots | Where-Object { $_.PSIsContainer }

You can then pipe that further into the ForEach-Object cmdlet where you can set the permissions:

Get-ChildItem \downloads\pivots |
Where-Object { $_.PSIsContainer } |
ForEach-Object {
    $_.SetAccessControl( ... )
}
Joey
Your method is cleaner however bobby's was more complete :)
Mitchell Skurnik
+3  A: 

Something like this should work:

$domain = "YOURDOMAIN"
$path = "C:\Your\Folder\Path"

$dirs = Get-ChildItem $path | Where-Object { $_.Attributes -band [System.IO.FileAttributes]::Directory }
foreach ($dir in $dirs)
{
    $acl = Get-Acl $dir.FullName
    $user = $domain + "\" + $dir.Name
    $permission = $user, "FullControl", "Allow"
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
    $acl.SetAccessRule($rule)
    $acl | Set-Acl $dir.FullName
}


The above works for a normal local file system path, but SharePoint has a different folder security model. I found a blog post by Robert Gruen that explains how to programmatically set permissions. He gives this C# code sample:

// get a reference to the folder (this assumes path points to a valid folder)
SPFolder folder = SharePointConfiguration.Site.GetFolder(path);

// get a reference to the Sharepoint group collection
SPGroupCollection spc = SharePointConfiguration.Site.SiteGroups;

// get a reference to the group who’s permissions you want to modify for the folder above
SPGroup group = spc[groupName];

// create a role assignment from the group reference
SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)group);

// break role inheritance for folders/files because they will be having permissions separate from their parent file/folder
folder.Item.BreakRoleInheritance(true);

// update the role assignments for the group by adding the permissionSet "TestPermissionLevel" which is a custom
// permissionset I created manually... you can easily use any of the built-in permission sets
roleAssignment.RoleDefinitionBindings.Add(SharePointConfiguration.Site.RoleDefinitions["Test Permission Level"]);

// apply the new roleassignment to the folder.  You can do this at the listitem level if desired (i.e. this could be SPfile.Item.... instead of SPFolder.Item)
folder.Item.RoleAssignments.Add(roleAssignment);

I'm sure with a bit of translation, this could be adapted to PowerShell.

bobbymcr
+1. But I like the PSIsContainer property better :-)
Joey
I forgot to say this is for SharePoint...sorry about that..thought I will try this with UNC to see if that works
Mitchell Skurnik
It should work as long as the user you run the script as has permission to the remote path.
bobbymcr
Everything works except the point where it tries to assign the permissions. Sharepoint does it a different way as it is more webdav and usually has its own calls to do that sort of thing
Mitchell Skurnik
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfolder.aspx I have a bad feeling that there is no way to programaticly set permission on a folder
Mitchell Skurnik
This might be what you're looking for: http://blogs.msdn.com/robgruen/archive/2007/11/15/how-to-programmatically-set-permissions-on-files-folders-in-a-sharepoint-document-library.aspx
bobbymcr
bobbymcr - that would work if it was just one or two groups but since that is creating a special level I would need to create special permission groups for everyone
Mitchell Skurnik
That is very close and I am tearing apart the code to see if I can hack something together
Mitchell Skurnik
I think I am going to have to ask a few of my co-workers to help me manually assign permissions to these groups.
Mitchell Skurnik
That blog post should work but now when I get to the part where i need to break role inheritance I get "you cannot call a method on a null-valued expression
Mitchell Skurnik
Bobby I want to mark this as the correct answer...can you post the code from the blog?
Mitchell Skurnik
Okay, I added it.
bobbymcr
So the script I have in my first post is working but only placing users in the /Downloads folder and not going to specific sub folder I want
Mitchell Skurnik
[Microsoft.SharePoint.SPFolder]$folder = $OpenWeb.GetFolder($path); [Microsoft.SharePoint.SPGroupCollection]$spc = $OpenWeb.SiteGroups; [Microsoft.SharePoint.SPGroup]$group = $spc[$dir]; [Microsoft.SharePoint.SProleAssignment]` $roleAssignment = New-Object Microsoft.SharePoint.SPRoleAssignment([Microsoft.SharePoint.SPPrincipal]$group); $OpenWeb.GetFolder($path).Item.BreakRoleInheritance($true); $roleAssignment.RoleDefinitionBindings.Add($OpenWeb.RoleDefinitions["Read"]); $OpenWeb.GetFolder($path).Item.RoleAssignments.Add($roleAssignment);
Mitchell Skurnik