Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Change NTFS permissions on specific folders

268 views
Skip to first unread message

René Zimmermann

unread,
Jun 3, 2009, 2:04:01 PM6/3/09
to
Hi everyone

I'm trying to do following:

I have a folder with around 500 subfolder. Each folder which has a specific
user as owner should be granted modify right for a specific group.

For example.
Folder A has owner User1
Folder B has owner User2
Folder C has owner User1
etc.

Those folders which have User1 as owner, should be granted modify right for
user group domain\group-1.

Could anyone put me in a direction on how to do that with PowerShell? I'm a
complete novice on PowerShell.

I know, that with something like this I can get the folders which have
user-a as owner.
$user = "domain\user-a"
get-childitem | get-acl | where {$_.owner -contains $user}

But how do I combine getting childitems and settings NTFS permissions with
PowerShell?

This PowerShell script should run as a scheduled task at the end...

Any help is greatly appreciated.

Thanks in advance
Reneé

Vadims Podans [MVP]

unread,
Jun 3, 2009, 2:55:38 PM6/3/09
to
mm..something like this:
# define user
$user = "domain\user-a"
# create access rule using FileSystemAccessRule class
# (refer to:
http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemaccessrule(VS.80).aspx )
# ContainerInherit and ObjectInherit represent "This folder, subfolders and
files" in GUI console
$AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule
`
($user,"Modify","ContainerInherit, ObjectInherit", "none", "Allow")
# get folders, where particular user is owner
get-childitem | get-acl | where {$_.owner -contains $user} | `
# pass all these folders to Foreach-Object loop
%{$acl = $_
# since input objects are DirectorySecurity object we can use
# AddAccessRule method to add another ACE to existing ACL
$acl.AddAccessRule($AccessRule)
# write new ACL to folders ACL
$acl | Set-Acl $acl.path}
--
WBR, Vadims Podans
MVP: PowerShell
PowerShell blog - www.sysadmins.lv

"René Zimmermann" <RenZim...@discussions.microsoft.com> rakstīja
ziņojumā "news:9408A893-3230-4132...@microsoft.com"...

René Zimmermann

unread,
Jun 4, 2009, 1:20:01 AM6/4/09
to
Hi

Thanks for the script. It looks great and every statement seems to be
accepted. The only problem is, the new NTFS rights are not applied to the
specified folders.

After your last statement:
$acl | Set-Acl $acl.path}

shouldn't PowerShell return to something like:
PS D:\Test>
???

My PowerShell console still stands at:
>>

which seems to me, like it's waiting for further commands and not executing
the ones, given before...

Regards, Rene

René Zimmermann

unread,
Jun 4, 2009, 2:18:01 AM6/4/09
to
Yes, I've just figured out the same. But now I'm getting the following error
message:
Set-Acl : The security identifier is not allowed to be the owner of this
object.
At D:\Test\script.ps1:12 char:15
+ $acl | Set-Acl <<<< $acl.path}

I did a search for that error message, and for me it seems, that I'm unable
to take ownership of the folder, but the script isn't doing that. It's only
setting a group to modify rights...

Can you probably explain that message?

"Vadims Podans [MVP]" wrote:

> you should press Enter twice.


> --
> WBR, Vadims Podans
> MVP: PowerShell
> PowerShell blog - www.sysadmins.lv
>
> "René Zimmermann" <RenZim...@discussions.microsoft.com> rakstīja

> ziņojumā "news:70E3759A-342B-441A...@microsoft.com"...

Vadims Podans [MVP]

unread,
Jun 4, 2009, 3:37:08 AM6/4/09
to
sorry, I forgot about this issue. You cannot use Set-Acl cmdlet on objects,
where you are (or your group) not owner. So, you can do this through WMI:

dir | Get-Acl | ?{$_.owner -like "domain\user-a"| % {
# take path
$path = $_.pspath -replace "Microsoft.PowerShell.Core\\FileSystem::"
# convert path from C:\Path to C:\\Path format (with double slashes)
$path = [regex]::Escape($path)
# specify user
$user = "domain\group-1"
# Create all neccessary SecurityDescriptor classes instances
$SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
$ace = ([WMIClass] "Win32_ace").CreateInstance()
$Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
# Translate user to SID
$SID = (new-object security.principal.ntaccount `
$user).translate([security.principal.securityidentifier])
# Get SID binary form
[byte[]] $SIDArray = ,0 * $SID.BinaryLength
$SID.GetBinaryForm($SIDArray,0)
# fill Trustee object properties that describes user
$Trustee.Name = $user
$Trustee.SID = $SIDArray
# set access mask
$ace.AccessMask = `
[System.Security.AccessControl.FileSystemRights]"Modify"
# set inheritances and propagation flags
$ace.AceFlags = "0x7"
# grant Allow
$ace.AceType = 0
$ace.Trustee = $trustee
# get folders current security descriptor
$oldDACL = (gwmi Win32_LogicalFileSecuritySetting -filter `
"path='$path'").GetSecurityDescriptor().Descriptor.DACL
# write information about user and access mask to SecurityDescriptor
$SD.DACL = $oldDACL
# append new security descriptor to existing SD
$SD.DACL += @($ace.psobject.baseobject)
# set SE_DACL_PRESENT flag which tell us that we change only DACL
# information.
$SD.ControlFlags="0x4"
# get folder object
$wPrivilege = gwmi Win32_LogicalFileSecuritySetting -filter "path='$path'"
# enable SeSecurityPrivilege and SeRestorePrivilege
$wPrivilege.psbase.Scope.Options.EnablePrivileges = $true
# apply new SACL to real folder object
$wPrivilege.setsecuritydescriptor($SD)
}

so, may be it would be more easy to use icacls utility?
dir | ?{$_.psiscontainer} | get-acl | %{
$path = $_.pspath -replace "Microsoft.PowerShell.Core\\FileSystem::"
cmd /c "icacls $path /grant domain\group-1:(OI)(CI)(M,WDAC)"


}
--
WBR, Vadims Podans
MVP: PowerShell
PowerShell blog - www.sysadmins.lv

"René Zimmermann" <RenZim...@discussions.microsoft.com> rakstīja
ziņojumā "news:8308FCBE-CE51-42F0...@microsoft.com"...

0 new messages