NTFS ACLs

Hello,

I have been using the following method for some time to set some NTFS permissions on a folder using powershell. However recently - possibly a patch, It has stopped working and now flags up an error for me.

My main question is - what is the best way for doing NTFS permissions so this includes things like… adding groups with certain rights, removing inheritance and removing groups.
Is this method the best way and i simply need to iron out this bug? Or is there another method without having to tap into .NET

#setting permission level
$objModify = [System.Security.AccessControl.FileSystemRights]::Modify
$objList = [System.Security.AccessControl.FileSystemRights]::ListDirectory
$objFull = [System.Security.AccessControl.FileSystemRights]::FullControl

#Define inheritance
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]“ContainerInherit, ObjectInherit”
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None

#Define if we are going to allow or deny access to an object
$objType =[System.Security.AccessControl.AccessControlType]::Allow

#Create a new object representing the user to be assigned these rights
$objAdministrator = New-Object System.Security.Principal.NTAccount(“Domain\Administrator”)
$objDomainAdmin = New-Object System.Security.Principal.NTAccount(“domain\Domain Admins”)
$objEveryone = New-Object System.Security.Principal.NTAccount(“Everyone”)
$objProject = New-Object System.Security.Principal.NTAccount(“Domain\Project_$($project)”)

#Create above
$objAdministrator = New-Object System.Security.AccessControl.FileSystemAccessRule ($objAdministrator, $objFull, $InheritanceFlag, $PropagationFlag, $objType)
$objDomainAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule ($objDomainAdmin, $objFull, $InheritanceFlag, $PropagationFlag, $objType)
$objEveryone = New-Object System.Security.AccessControl.FileSystemAccessRule ($objEveryone, $objList, $InheritanceFlag, $PropagationFlag, $objType)
$objEveryoneFull = New-Object System.Security.AccessControl.FileSystemAccessRule ($objEveryone, $objFull, $InheritanceFlag, $PropagationFlag, $objType)
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($objProject, $objModify, $InheritanceFlag, $PropagationFlag, $objType)

$objACL.AddAccessRule($objvnxDomainAdmin)
$objACL.AddAccessRule($objvnxAdministrator)
$objACL.AddAccessRule($objACE)

$objACL.RemoveAccessRuleAll($objvnxEveryoneFull)
$objACL.AddAccessRule($objvnxEveryone)

Thanks!

Adnan

What error do you get

Its a strange one. I get the following:

However I have putted the variables at each stage and tried to troubleshoot this… however something somewhere is not going right. I know the code does work because it works for me for a good while then suddenly just stopped.

The ‘some or all identity references could not be translated’ i thought one of the variables is going wrong, but it does output normally.

Exception calling “AddAccessRule” with “1” argument(s): “Some or all identity references could not be translated.”
At E:\Automation\v0.14.ps1:259 char:1

  • $objACL.AddAccessRule($objACE)
  •   + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : IdentityNotMappedException

When do to this setting up our shared drives, it cycles through things like this:

$GroupFolder_ACL = Get-Acl -Path RootLevel:\$FolderName
# Disable Inheritance, remove previous ACLs
$GroupFolder_ACL.SetAccessRuleProtection($true, $false)
$GroupFolder_ACL.Access | ForEach-Object { $GroupFolder_ACL.RemoveAccessRule($_) }

# Set rights on object in memory
# Domain Admins
$Rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule("Domain Admins", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$GroupFolder_ACL.AddAccessRule($Rule)

# Authenticated Users
$Rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule("Authenticated Users", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
$GroupFolder_ACL.AddAccessRule($Rule)

# Commit memory object to file system
Set-Acl -Path $FolderName -AclObject $GroupFolder_ACL -ErrorVariable ACLError -ErrorAction 'SilentlyContinue'
if ($ACLError)
{
	Write-Output -InputObject "An error was caught attempting to apply security rights, `n`tyou may have to take ownership of the `'$ParentPath\$FolderName`' folder"
	Write-Verbose -Message "$ACLError"
	$ACLError = $false
} # if ACLError

This is just what I got to work for me and its pretty much the same thing you have going, but the error you mention I tend to get if there is an issue with mapping the AD account when I make up the rule.

Ah i see! thats quite helpful that you get a similar error with AD groups - i did think it was something to do with that, so i put a couple of ‘sleeps’ between functions so to give it a chance to actually register the groups, however it didn’t make any different and i dismissed it.

I will go back to that and look at it again, perhaps with the AD group already created and see how it behaves.

thanks!

Hey Raymond your right mate.

It is to do with the AD group, i replaced it with just the group name rather than the variables and it works perfect so something going wrong there - but thats kool i know what to focus on.

thanks for your help!

I’ll post what exactly it is when i figure it out :slight_smile:

Glad it provided some light for you. I found when trying to troubleshoot things, I ended up putting the Set-ACL between every rule as it only throws the error when it actually attempts to set the ACL, so that might help you pinpoint which group/user is causing the issue.

If you use the AD tools, or want do write specific ADSI commands, you could find the AD account first, and then use that or something like $ADAccount.samaccountname give you another step of checking.

You’re working with .Net classes, so you should look at MSDN as a resource to see what properties are expected;

http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemaccessrule(v=vs.110).aspx

You can also look at the information from Powershell:

PS C:\> [System.Security.AccessControl.FileSystemAccessRule] | Get-Member -MemberType Property


   TypeName: System.RuntimeType

Name                       MemberType Definition                                                                          
----                       ---------- ----------                                                                          
Assembly                   Property   System.Reflection.Assembly Assembly {get;}                                          
AssemblyQualifiedName      Property   string AssemblyQualifiedName {get;}                                                 
Attributes                 Property   System.Reflection.TypeAttributes Attributes {get;}                                  
BaseType                   Property   type BaseType {get;}                                                                
ContainsGenericParameters  Property   bool ContainsGenericParameters {get;}                                               
CustomAttributes           Property   System.Collections.Generic.IEnumerable[System.Reflection.CustomAttributeData] Cus...
DeclaredConstructors       Property   System.Collections.Generic.IEnumerable[System.Reflection.ConstructorInfo] Declare...
DeclaredEvents             Property   System.Collections.Generic.IEnumerable[System.Reflection.EventInfo] DeclaredEvent...
DeclaredFields             Property   System.Collections.Generic.IEnumerable[System.Reflection.FieldInfo] DeclaredField...
DeclaredMembers            Property   System.Collections.Generic.IEnumerable[System.Reflection.MemberInfo] DeclaredMemb...
DeclaredMethods            Property   System.Collections.Generic.IEnumerable[System.Reflection.MethodInfo] DeclaredMeth...
DeclaredNestedTypes        Property   System.Collections.Generic.IEnumerable[System.Reflection.TypeInfo] DeclaredNested...
DeclaredProperties         Property   System.Collections.Generic.IEnumerable[System.Reflection.PropertyInfo] DeclaredPr...
DeclaringMethod            Property   System.Reflection.MethodBase DeclaringMethod {get;}                                 
DeclaringType              Property   type DeclaringType {get;}                                                           
FullName                   Property   string FullName {get;}                                                              
GenericParameterAttributes Property   System.Reflection.GenericParameterAttributes GenericParameterAttributes {get;}      
GenericParameterPosition   Property   int GenericParameterPosition {get;}                                                 
GenericTypeArguments       Property   type[] GenericTypeArguments {get;}                                                  
GenericTypeParameters      Property   type[] GenericTypeParameters {get;}                                                 
GUID                       Property   guid GUID {get;}                                                                    
HasElementType             Property   bool HasElementType {get;}                                                          
ImplementedInterfaces      Property   System.Collections.Generic.IEnumerable[type] ImplementedInterfaces {get;}           
IsAbstract                 Property   bool IsAbstract {get;}                                                              
IsAnsiClass                Property   bool IsAnsiClass {get;}                                                             
IsArray                    Property   bool IsArray {get;}                                                                 
IsAutoClass                Property   bool IsAutoClass {get;}                                                             
IsAutoLayout               Property   bool IsAutoLayout {get;}                                                            
IsByRef                    Property   bool IsByRef {get;}                                                                 
IsClass                    Property   bool IsClass {get;}                                                                 
IsCOMObject                Property   bool IsCOMObject {get;}                                                             
IsConstructedGenericType   Property   bool IsConstructedGenericType {get;}                                                
IsContextful               Property   bool IsContextful {get;}                                                            
IsEnum                     Property   bool IsEnum {get;}                                                                  
IsExplicitLayout           Property   bool IsExplicitLayout {get;}                                                        
IsGenericParameter         Property   bool IsGenericParameter {get;}                                                      
IsGenericType              Property   bool IsGenericType {get;}                                                           
IsGenericTypeDefinition    Property   bool IsGenericTypeDefinition {get;}                                                 
IsImport                   Property   bool IsImport {get;}                                                                
IsInterface                Property   bool IsInterface {get;}                                                             
IsLayoutSequential         Property   bool IsLayoutSequential {get;}                                                      
IsMarshalByRef             Property   bool IsMarshalByRef {get;}                                                          
IsNested                   Property   bool IsNested {get;}                                                                
IsNestedAssembly           Property   bool IsNestedAssembly {get;}                                                        
IsNestedFamANDAssem        Property   bool IsNestedFamANDAssem {get;}                                                     
IsNestedFamily             Property   bool IsNestedFamily {get;}                                                          
IsNestedFamORAssem         Property   bool IsNestedFamORAssem {get;}                                                      
IsNestedPrivate            Property   bool IsNestedPrivate {get;}                                                         
IsNestedPublic             Property   bool IsNestedPublic {get;}                                                          
IsNotPublic                Property   bool IsNotPublic {get;}                                                             
IsPointer                  Property   bool IsPointer {get;}                                                               
IsPrimitive                Property   bool IsPrimitive {get;}                                                             
IsPublic                   Property   bool IsPublic {get;}                                                                
IsSealed                   Property   bool IsSealed {get;}                                                                
IsSecurityCritical         Property   bool IsSecurityCritical {get;}                                                      
IsSecuritySafeCritical     Property   bool IsSecuritySafeCritical {get;}                                                  
IsSecurityTransparent      Property   bool IsSecurityTransparent {get;}                                                   
IsSerializable             Property   bool IsSerializable {get;}                                                          
IsSpecialName              Property   bool IsSpecialName {get;}                                                           
IsUnicodeClass             Property   bool IsUnicodeClass {get;}                                                          
IsValueType                Property   bool IsValueType {get;}                                                             
IsVisible                  Property   bool IsVisible {get;}                                                               
MemberType                 Property   System.Reflection.MemberTypes MemberType {get;}                                     
MetadataToken              Property   int MetadataToken {get;}                                                            
Module                     Property   System.Reflection.Module Module {get;}                                              
Name                       Property   string Name {get;}                                                                  
Namespace                  Property   string Namespace {get;}                                                             
ReflectedType              Property   type ReflectedType {get;}                                                           
StructLayoutAttribute      Property   System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute {get;}   
TypeHandle                 Property   System.RuntimeTypeHandle TypeHandle {get;}                                          
TypeInitializer            Property   System.Reflection.ConstructorInfo TypeInitializer {get;}                            
UnderlyingSystemType       Property   type UnderlyingSystemType {get;}      

The property Name (e.g. Domain Admins) or FullName (e.g mydomain\Domain Admins) is looking for String:

PS C:\> $objDomainAdmin = New-Object System.Security.Principal.NTAccount("mydomain\Domain Admins")

PS C:\> $objDomainAdmin.GetType()

IsPublic IsSerial Name                                     BaseType                                                       
-------- -------- ----                                     --------                                                       
True     False    NTAccount                                System.Security.Principal.IdentityReference                    



PS C:\> $objDomainAdmin.Value
mydomain\Domain Admins

PS C:\> $objDomainAdmin.Value.GetType()

IsPublic IsSerial Name                                     BaseType                                                       
-------- -------- ----                                     --------                                                       
True     True     String                                   System.Object    

You were passing System.Security.Principal.IdentityReference, so you’re getting a exception. You could use the .Value property, but for simplicity you should just do:

$objDomainAdmin = "mydomain\Domain Admins"

Edit: Is there anyway to enumerate the Constructors in Powershell?

Raymond thanks for the advice. The issue was definitely related to AD Groups.

Rob Simmers - That information was so useful! I understood quite a lot more from that info. Also i took your advice and it the simple way which works a lot better than before - appreciate that.

In terms of constructors, i have no idea how we would see those in powershell. I have only been able to see them on the MSDN website.

So i have managed to figure out what was going on by rewriting my entire script. So firstly because my script was written poorly (just the learning curve im going through right now) i wasn’t being able to test in the best way. So i rewrote each function and parametrised it. The functions are basically… Create a AD Group… Copy couple template folders… Start setting the permissions.

I tested the permissions function numerous times without any AD groups and each time it would work without any hiccups at all. I then added the AD group in and saw that it was causing a problem.

I think what was happening is that, when the script was being executed, it seems it was creating the group and moving onto the permissions part so fast that when it came to adding the AD group it couldn’t find it and was reporting back null. So i put in a 15 second sleep between the AD group creation and the permissions setting - I have run the script about 5 times and each time had no errors come back to me.

I will continue to test this but i think that was the main issue, because even when i changed everything to a string it still wouldn’t work.

Thanks for the help with this - I actually really enjoyed looking at the .NET stuff, I think i will look into that some more too :slight_smile:

As for constructors,

(not PowerShell but calling .Net from PowerShell) :

$X = [System.Security.Principal.NTAccount]
$x.GetConstructors()