Link to home
Start Free TrialLog in
Avatar of DigitBoy
DigitBoyFlag for Netherlands

asked on

Set NFTS/share permissions via script

Dear experts,

is there a way to set ntfs/share permissions on folders and files (like owner, inheritance, read, write, delete, special permissions, etc ....) from csv input file using powershell script? I know I can use command lines, but all of them are not really useful for my goal.


In the csv file I have these headers:
uncFolderpath,user,Accsscontroltype,owner,Inheritance,ntfssystemRights
 

exp of csv file:
uncFolderpath,user,Accsscontroltype,owner,Inheritance,ntfssystemRights
\\FileServer\parentFolder\test,domain\Linda,allow,administrator,none,read
\\FileServer\parentFolder\test\soft\,domain\Linda,allow,administrator,subfolders and beneath,read;write;modify
\\FileServer\parentFolder\Pilot,domain\Brian,allow,administrator,none,fullcontrol
\\FileServer\parentFolder\Pilot\Help\,domain\Kevin,allow,administrator,none,read;modify
....
....

Thanks in advance.
Avatar of Zouleous
Zouleous
Flag of United States of America image

Disclaimer--I'm pretty new to Powershell...I have some ideas, but I think this is slightly more than I'm able to tackle right now.  I can give you a few tips though.

If you just needed to set NTFS permissions that would be less complicated imo.  Shares are managed with WMI in the Win32_Share class and Win32_SecurityDescriptor class.  I always set the share permissions to Everyone Full Access and manage at the NTFS level.  If you had a list of shares you wanted to modify that would be easier.  I assume all the folders located in your csv aren't necessarily shared out at that level?

NTFS permissions can be handled with the Set-ACL cmdlet.  The easiest way to work with ACLs is to first get the resource (get-ACL) and load it in to a variable.  Then use the AddAccessRule() method to add new permissions to the ACL.  Then use Set-ACL on the source object to overwrite the old permissions with the new ones.

My thought is to import-csv to an array and then loop through each element in the array to set NTFS permissions in the way I just described.  One problem you're going to have is your csv is referencing inheritance incorrectly.  You'll need to make sure the inherit flags match what powershell expects or translate them for powershell.  For example, there is no inheritance flag for "subfolders and beneath".  It should be called "container inherit" and "object inherit".

Sorry I couldn't be more help.
Avatar of DigitBoy

ASKER

Hi Zouleous,

thanks for your suggestion :), but I tried already several command line tools (setacl, icacls, ...). It didn't help me a lot that's why I need this kind of scripting solution in powershell or in vbs. I appriciate your effort to help me.

Cheers,

K
Avatar of Aard Vark
Seems this person has written a script to do this already, so why re-invent the wheel. Maybe just update it to accept your input file or update your input file to suite it :)

http://blog.tyang.org/2010/07/01/powershell-script-setting-ntfs-permissions-in-bulk/
I found time ago this script also, but this is for same permissions for all users. What I'm looking for is different permissions for users individual.
The problem is I'm not scriptor :(. I need help from experts. This is the reason why I posed a question on this site. The script from Tyang looks really good, but I don't have enough knowledge to reform it.
Is this just adding permissions? And the inheritance part, what are you expecting it to do?

Something to start us off with...
Import-Csv YourFile.csv | ForEach-Object {

  # Build an access rule based on the line we read from the file
  $AccessRule = New-Object Security.AccessControl.FileSystemAccessRule(
    $_.User, $_.ntfssystemRights, "ObjectInherit, ContainerInherit", "None", $_.AccessControlType)

  # Get the current access list
  $Acl = Get-Acl $_.uncFolderPath
  # Add the rule
  $Acl.AddAccessRule($AccessRule)
  # Save changes
  Set-Acl -Path $_.uncFolderPath -AclObject $Acl
}

Open in new window

Chris
Hi Chris,

thanks a lot for your script. I will try asap and will let you know. Please be patient with me, because I'm really a zero in scripting.

rgs
Hi Chris,

sorry I didn't answerd on your questions. I was in hurry to try your script.

Yes it is just to add folder permissions on the file servers. I have already a long list with a lot of permissions with their unc path and members (users or groups).

About the inheritance. The script has to set InheritanceFlags like below:

Subfolders and Files only
InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly

This Folder, Subfolders and Files    
InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.None

This Folder, Subfolders and Files
InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit

This folder and subfolders
InheritanceFlags.ContainerInherit, PropagationFlags.None

Subfolders only
InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly

This folder and files
InheritanceFlags.ObjectInherit, PropagationFlags.None

This folder and files
InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit


rgs
Hi Chris,

Sorry if their are confusions from my side.

The script has to add the following permissions from the input file on the shares.
AccessControlType,FileSystemRights,InheritanceFlags,ownership

The csv file has these headers:
UNCpath,AccessControlType,FileSystemRights,InheritanceFlags,ownership

rgs
So the CSV file will, for example, contain text like this in the inheritance field?

"This folder and files"

If so, something like this, although we need to adjust some of the tags above (due to repetition).
Import-Csv YourFile.csv | ForEach-Object {

  # Some defaults
  $InheritanceFlags = "containerInherit, ObjectInherit"
  $PropagationFlags = "None"

  # Override defaults if necessary
  $Inheritance = $_.InheritanceFlags
  Switch ($Inheritance) {
    "Subfolders and Files only"                      { $PropagationFlags = "InheritOnly" }
    "This Folder, One level of Subfolders and Files" { $PropagationFlags = "NoPropagateInherit" }
    "This folder and subfolders"                     { $InheritanceFlags = "ContainerInherit" }
    "Subfolders only"                                { $InheritanceFlags = "ContainerInherit"; $PropagationFlags = "InheritOnly" }
    "This folder and files"                          { $InheritanceFlags = "ObjectInherit" }
    "This folder and one level of files"             { $InheritanceFlags = "ObjectInherit"; $PropagationFlags = "InheritOnly" }
  }

  # Build an access rule based on the line we read from the file
  $AccessRule = New-Object Security.AccessControl.FileSystemAccessRule(
    $_.User, $_.FileSystemRights, $InheritanceFlags, $PropagationFlags, $_.AccessControlType)

  # Get the current access list
  $Acl = Get-Acl $_.uncFolderPath
  # Add the rule
  $Acl.AddAccessRule($AccessRule)
  # Save changes
  Set-Acl -Path $_.uncFolderPath -AclObject $Acl
}

Open in new window

Chris
Hi Chris,

thanks again for the code. Yes indeed the csv file will contain in the inheritance field: "This folder and files" and other inheritanceflags.

I found an issue related to inheritance field, because the inheritanceflag there is also comma "," like "This folder, subfolders and Files". Will this comma cause problems for powershell to read the fields after the comma? Because the header has also a comma "," between different fields.  

I have here an expl of the csv file:

UNCpath,Users,AccessControlType,FileSystemRights,InheritanceFlags,ownership
\\fileSRv1\IT\doc,domain\user1,Allow,ReadAndExecute,This folder, subfolders and Files,administrator
\\fileSRv1\IT\Finance,domain\user2,Deny,FullControl,This folder, subfolders and Files,administrator


PS: My appologize to be chaotic I forgot one more header in the csv file, the "users".
The complete csv file will have these headers:
UNCpath,User,AccessControlType,FileSystemRights,InheritanceFlags,ownership.



Rgs


Ah that field isn't quoted?

Is it possible to fix the CSV? Working around that will be hard work.

Chris
Hi Chris,

No problem at all :). I didn't know that it was possible.
I will quote the inheritanceflag field as you suggested like the expl below:

UNCpath,Users,AccessControlType,FileSystemRights,InheritanceFlags,ownership
\\fileSRv1\IT\doc,domain\user1,Allow,ReadAndExecute,"This folder, subfolders and Files",administrator
\\fileSRv1\IT\Finance,domain\user2,Deny,FullControl,"This folder, subfolders and Files",administrator

I'm going to try the script and will come asap with news :).

Knd rgs
"thanks for your suggestion :), but I tried already several command line tools (setacl, icacls, ...). It didn't help me a lot that's why I need this kind of scripting solution in powershell or in vbs. I appriciate your effort to help me."

Just to clear things up I wasn't suggesting any command line tools.  Everything I mentioned was for use in Powershell.  Notice the Get-ACL cmdlet and AddAccessRule() method that Chris uses?  Same thing I was talking about.  In any case it sounds like Chris has you on the right track, but it doesn't look like Chris is addressing the share permissions at all...only NTFS permissions.  Not sure if he plans on getting to that part later.
One thing at a time :) If only because the differences in setting NTFS vs Share are pretty significant.

Chris
Hi Zouleous,

sorry for that I didn't understood you correctly. My mistake.

Rgs
Hi Chris,


I have these shares on my file server:
\\fileSRv1\IT\doc
\\fileSRv1\test\Finance

The content of the csv file:
UNCpath,Users,AccessControlType,FileSystemRights,InheritanceFlags,ownership
\\fileSRv1\IT\doc,domain\user1,Allow,ReadAndExecute,"This folder, subfolders and Files",administrator
\\fileSRv1\test\Finance,domain\user2,Deny,FullControl,"This folder, subfolders and Files",administrator


When I want to run to set permissions on folder level I'm getting these errors:

New-Object : Exception calling ".ctor" with "5" argument(s): "Value cannot be null.
Parameter name: identity"
At C:\temp\setPERM.ps1:19 char:27
+   $AccessRule = New-Object <<<<  Security.AccessControl.FileSystemAccessRule(
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Get-Acl : Cannot validate argument on parameter 'Path'. The argument is null or empty. Supply an argument that is not n
ull or empty and then try the command again.
At C:\temp\setPERM.ps1:23 char:17
+   $Acl = Get-Acl <<<<  $_.uncFolderPath
    + CategoryInfo          : InvalidData: (:) [Get-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetAclCommand

You cannot call a method on a null-valued expression.
At C:\temp\setPERM.ps1:25 char:21
+   $Acl.AddAccessRule <<<< ($AccessRule)
    + CategoryInfo          : InvalidOperation: (AddAccessRule:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Set-Acl : Cannot bind argument to parameter 'Path' because it is null.
At C:\temp\setPERM.ps1:27 char:16
+   Set-Acl -Path <<<<  $_.uncFolderPath -AclObject $Acl
    + CategoryInfo          : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclComma
   nd

rgs
The column names you cite in your examples keep changing. If you change the column names you *must* change the fields the script references.

This should work, but is utterly dependent on predictable input.

Chris
Import-Csv YourFile.csv | ForEach-Object {

  # Some defaults
  $InheritanceFlags = "containerInherit, ObjectInherit"
  $PropagationFlags = "None"

  # Override defaults if necessary
  $Inheritance = $_.InheritanceFlags
  Switch ($Inheritance) {
    "Subfolders and Files only"                      { $PropagationFlags = "InheritOnly" }
    "This Folder, One level of Subfolders and Files" { $PropagationFlags = "NoPropagateInherit" }
    "This folder and subfolders"                     { $InheritanceFlags = "ContainerInherit" }
    "Subfolders only"                                { $InheritanceFlags = "ContainerInherit"; $PropagationFlags = "InheritOnly" }
    "This folder and files"                          { $InheritanceFlags = "ObjectInherit" }
    "This folder and one level of files"             { $InheritanceFlags = "ObjectInherit"; $PropagationFlags = "InheritOnly" }
  }

  # Build an access rule based on the line we read from the file
  $AccessRule = New-Object Security.AccessControl.FileSystemAccessRule(
    $_.Users, $_.FileSystemRights, $InheritanceFlags, $PropagationFlags, $_.AccessControlType)

  # Get the current access list
  $Acl = Get-Acl $_.UNCPath
  # Add the rule
  $Acl.AddAccessRule($AccessRule)
  # Save changes
  Set-Acl -Path $_.UNCPath -AclObject $Acl
}

Open in new window

Hi Chris,

I mixed everything like you said :(. Now I will try to not be chaotic.

Now I didn't change anything. It is still same headers and contents in the csv file. I launched the script, but I'm getting now these errors:

New-Object : Cannot find an overload for "FileSystemAccessRule" and the argument count: "5".
At C:\temp\setPERM.ps1:19 char:27
+   $AccessRule = New-Object <<<<  Security.AccessControl.FileSystemAccessRule(
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Get-Acl : Cannot validate argument on parameter 'Path'. The argument is null or empty. Supply an argument that is not n
ull or empty and then try the command again.
At C:\temp\setPERM.ps1:23 char:17
+   $Acl = Get-Acl <<<<  $_.UNCPath
    + CategoryInfo          : InvalidData: (:) [Get-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetAclCommand

Set-Acl : Cannot bind argument to parameter 'Path' because it is an empty string.
At C:\temp\setPERM.ps1:27 char:16
+   Set-Acl -Path <<<<  $_.UNCPath -AclObject $Acl
    + CategoryInfo          : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.SetA
   clCommand
Hi Chris,

My stupid mistake again. It seems to be working now. I'm gonna test it further.

Rgs,
Hi Chris,

Is there also a possibility to set "This Folder Only" option as inheritanceflag on the Shared folders/files please?

Rgs,

ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland 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
Thanks a millionChris :D. I'm going test it further and will let you know asap.

Good evening Chris,

I saw that there were several folders who had permissions from while ago. When I ran the script it seems to be that the permission didn't change at all. For new folders it worked.

Is there a way to delete or modify the privous permissions for the right user on the shared folders please? Like, if the script finds the same user from the csv file it deletes the user in the "security tab of the folder" and set the new one. Is this possible?
 
And sorry to bother you more with my endless story :(, but also the owner didn't change.

rgs
 
I should address owner first. That's very hard to set, in normal circumstances we can set it either to Administrators, or the current user (not a different user). However, PS has trouble with this, it's very hard to gain the permissions needed to reliably do so. With that in mind, I normally wind up recommending tools like TakeOwn to handle ownership changes.

For the rights, are we cleaning out the ACL entirely? Applying a brand new one?

Chris
Hi Chris,


thanks again for your time and support. About the ownership, I understand the difficulties and will leave it as it is.

About the ACL on folders, I thought to delete only the users who are listed in my cvs file. Maybe your idea is much better to clean entire ACL.
Will the administrators have still access to the folder after the cleaning of ACL's please?

Rgs.
Hi Chris,


I have one last question. Is it possible to have an output in powershell prompt to have better control please?

e.g.
write-Host "$user & permissions added: Success" -foregroundcolor green

rgs
To Remove the users from the security tab is solved :). This is a good news.

 
Hi Chris,

the code works like a charm. Thanks for the wonderful code.
rgs
Chris a Guru in his domain