Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Option Explicit
'**************************************************
'*** Constant Declarations
'**************************************************
'*** Access Control Entry Inheritance Flags
'*** Possible values for the IADsAccessControlEntry::AceFlags property.
const ADS_ACEFLAG_UNKNOWN = &h1
'*** child objects will inherit ACE of current object
const ADS_ACEFLAG_INHERIT_ACE = &h2
'*** prevents ACE inherited by the object from further propagation
const ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = &h4
'*** indicates ACE used only for inheritance (it does not affect permissions on object itself)
const ADS_ACEFLAG_INHERIT_ONLY_ACE = &h8
'*** indicates that ACE was inherited
const ADS_ACEFLAG_INHERITED_ACE = &h10
'*** indicates that inherit flags are valid (provides confirmation of valid settings)
const ADS_ACEFLAG_VALID_INHERIT_FLAGS = &h1f
'*** for auditing success in system audit ACE
const ADS_ACEFLAG_SUCCESSFUL_ACCESS = &h40
'*** for auditing failure in system audit ACE
const ADS_ACEFLAG_FAILED_ACCESS = &h80
'**************************************************
'*** Access Control Entry Type Values
'*** Possible values for the IADsAccessContronEntry::AceType property.
const ADS_ACETYPE_ACCESS_ALLOWED = 0
const ADS_ACETYPE_ACCESS_DENIED = &h1
const ADS_ACETYPE_SYSTEM_AUDIT = &h2
const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &h5
const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &h6
const ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = &h7
'**************************************************
'*** Access Control Entry Permission Type Values
'*** Possible values for the IADsAccessControlEntry::AccessMask property.
'*** permission to read data from file or list contents of directory
'*** corresponds to List Folder / Read Data permissions in Windows UI
const FILE_READ_DATA = &h1 'bit number 0
const FILE_LIST_DIRECTORY = &h1 'bit number 0
'*** permission to write data to file or create file in directory
'*** corresponds to Create Files / Write Data permissions in Windows UI
const FILE_WRITE_DATA = &h2 'bit number 1
const FILE_ADD_FILE = &h2 'bit number 1
'*** permission to append data to file or to create subdirectory
'*** corresponds to Create Folders / Append Data permissions in Windows UI
const FILE_APPEND_DATA = &h4 'bit number 2
const FILE_ADD_SUBDIRECTORY = &h4 'bit number 2
'*** permission to read extended attributes
'*** corresponds to Read Extended Attributes permissions in Windows UI
const FILE_READ_EA = &h8 'bit number 3
'*** permission to write extended attributes
'*** corresponds to Write Extended Attributes permissions in Windows UI
const FILE_WRITE_EA = &h10 'bit number 4
'*** permission to execute file or traverse directory
'*** corresponds to Traverse Folder / Execute File permissions in Windows UI
const FILE_EXECUTE = &h20 'bit number 5
const FILE_TRAVERSE = &h20 'bit number 5
'*** permission to delete directory and all files it contains
'*** corresponds to Delete Subfolders and Files permissions in Windows UI
const FILE_DELETE_CHILD = &h40 'bit number 6
'*** permission to read file or folder attributes
'*** corresponds to Read Attributes permissions in Windows UI
const FILE_READ_ATTRIBUTES = &h80 'bit number 7
'*** permission to change file or folder attributes
'*** corresponds to Write Attributes permissions in Windows UI
const FILE_WRITE_ATTRIBUTES = &h100 'bit number 8
'*** permission to delete file or folder
'*** corresponds to Delete permissions in Windows UI
const DELETE = &h10000 'bit number 16
'*** permission to read security descriptor
'*** corresponds to Read Permissions permissions in Windows UI
const READ_CONTROL = &h20000 'bit number 17
'*** permission to change discretionary ACL
'*** corresponds to Change Permissions permissions in Windows UI
const WRITE_DAC = &h40000 'bit number 18
'*** permission to assign owner
'*** corresponds to Take Ownership permissions in Windows UI
const WRITE_OWNER = &h80000 'bit number 19
'*** permission to synchronize
'*** bit indicating permission to perform synchronize operation, used sometimes during file access
'*** this permission is automaticaly granted with read and write access and revoked when read or
'*** write access is denied. It is not displayed in the list of permissions in Windows UI
const SYNCHRONIZE = &h100000 'bit number 20
const ADS_RIGHT_GENERIC_ALL = &h10000000 'bit number 28
const ADS_RIGHT_GENERIC_EXECUTE = &h20000000 'bit number 29
const ADS_RIGHT_GENERIC_WRITE = &h40000000 'bit number 30
const ADS_RIGHT_GENERIC_READ = &h80000000 'bit number 31
'**************************************************
'*** Variable Declarations
Dim adsFILE_FULL 'value representing sum of access mask corresponding to full file access
Dim adsFOLDER_FULL 'value representing sum of access mask corresponding to full folder access
Dim adsFILE_CHANGE 'value representing sum of access mask corresponding to change file access
Dim adsFOLDER_CHANGE 'value representing sum of access mask corresponding to change folder access
Dim adsFILE_READ 'value representing sum of access mask corresponding to read file access
Dim adsFOLDER_READ 'value representing sum of access mask corresponding to read folder access
Dim adsFILE_NOACCESS 'value representing sum of access mask corresponding to denied full file access
Dim adsFOLDER_NOACCESS 'value representing sum of access mask corresponding to denied full folder access
adsFILE_FULL = FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER Or SYNCHRONIZE
adsFOLDER_FULL = FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER Or SYNCHRONIZE
adsFILE_CHANGE = FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or SYNCHRONIZE
adsFOLDER_CHANGE = FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or SYNCHRONIZE
adsFILE_READ = FILE_READ_DATA Or FILE_READ_EA Or FILE_EXECUTE Or _
FILE_READ_ATTRIBUTES Or READ_CONTROL Or SYNCHRONIZE
adsFOLDER_READ = FILE_LIST_DIRECTORY Or FILE_READ_EA Or FILE_TRAVERSE Or _
FILE_READ_ATTRIBUTES Or READ_CONTROL Or SYNCHRONIZE
adsFILE_NOACCESS = FILE_READ_DATA Or FILE_WRITE_DATA Or FILE_APPEND_DATA Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_EXECUTE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER
adsFOLDER_NOACCESS = FILE_LIST_DIRECTORY Or FILE_ADD_FILE Or FILE_ADD_SUBDIRECTORY Or _
FILE_READ_EA Or FILE_WRITE_EA Or FILE_TRAVERSE Or FILE_DELETE_CHILD Or _
FILE_READ_ATTRIBUTES Or FILE_WRITE_ATTRIBUTES Or DELETE Or _
READ_CONTROL Or WRITE_DAC Or WRITE_OWNER
Dim sAction 'type of action to perform (show or set)
Dim sPermission 'permission type (read, change, full, or no access)
Dim sAccount 'user or group account for which permissions are shown/set
Dim sTarget 'target file or folder path
Dim iTarget 'integer indicating type of target 0 - file, 1 - folder
Dim iOffset 'value used for display only (left justifying displayed values)
Dim oADSSecurity 'object representing ADsSecurity class
Dim oFSO 'object representing Scripting.FileSystemObject ProgID
'**************************************************
'*** Retrieve script arguments
Call GetArguments(Wscript.Arguments, sAction, sTarget, sAccount, sPermission)
'**************************************************
'*** Set variables
iOffset = 20
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oADSSecurity = CreateObject("ADsSecurity")
If oFSO.FileExists(sTarget) Then
iTarget = 0
ElseIf oFSO.FolderExists(sTarget) Then
iTarget = 1
Else
Call MsgBox("Target File or Folder does not exist", vbOKOnly, "Incorrect argument")
WScript.Quit
End If
Select Case UCase(sAction)
Case "SHOW"
Call DisplayACLs(sTarget, sAccount)
Case "SET"
Call RecurseACLs(sTarget, sAccount, sPermission)
Case Else
Call DisplayUsage("ERROR: Incorrect ACTION type")
End Select
Wscript.Quit
'**************************************************
'*** Subroutine reading command line arguments
'
Sub GetArguments(oArgs, sAction, sTarget, sAccount, sPermission)
Dim iCount
For iCount=0 To oArgs.Count - 1
Select Case UCase(Split(WScript.Arguments(iCount), "=")(0))
Case "ACTION" sAction = Split(WScript.Arguments(iCount), "=")(1)
Case "TARGET" sTarget = Split(WScript.Arguments(iCount), "=")(1)
Case "ACCOUNT" sAccount = Split(WScript.Arguments(iCount), "=")(1)
Case "PERM" sPermission = Split(WScript.Arguments(iCount), "=")(1)
End Select
Next
If sAction = "" or sTarget = "" or (sAction = "SET" and (sTarget = "" or sAccount = "" or sPermission = "")) Then
Call DisplayUsage("ERROR: Missing argument(s)")
WScript.Quit
End If
end sub
'**************************************************
'*** Subroutine displaying usage of the script from the command line
'
sub DisplayUsage(sHeader)
Dim sMsg
sMsg = "To display permissions on file/folder (ACCOUNT parameter is optional) run:"
sMsg = sMsg & VbCrLf & _
"cscript //nologo ACLs.vbs ACTION=SHOW TARGET=[File|Folder] [ACCOUNT=Domain\Account]"
sMsg = sMsg & VbCrLf & vbCrLf & "To set permissions on file/folder (ACCOUNT parameter is mandatory) run:"
sMsg = sMsg & VbCrLf & _
"cscript //nologo ACLs.vbs ACTION=SET TARGET=[File|Folder] ACCOUNT=Domain\Account PERM=[Read|Change|Full|NoAccess]"
sMsg = sMsg & VbCrLf & vbCrLf & "Where:"
sMsg = sMsg & VbCrLf & String(7," ") & "ACTION is set to SHOW to display permissions"
sMsg = sMsg & VbCrLf & String(7," ") & "TARGET is full path to the file or folder"
sMsg = sMsg & VbCrLf & String(7," ") & "ACCOUNT is user or group account in the DOMAIN\AccountName format"
sMsg = sMsg & VbCrLf & String(7," ") & "PERM specifies type of permissions to be set"
Call MsgBox(sMsg, vbOKOnly, sHeader)
end sub
'**************************************************
'*** Subroutine displaying list of Trustees, AcL Types, and ACL Masks
'
Sub DisplayACLs(sTarget, sAccount)
Dim oACE 'object representing an Access Control Entry
Dim sMsg, sAccessMask 'strings containing message to be displayed
Dim hAccessMask 'number representing Access Mask value
Dim oTargetSD 'object representing security descriptor of target file or folder
Dim oDACL 'object representing Discretionary Access Control List
set oTargetSD = oADsSecurity.GetSecurityDescriptor("FILE://" & Cstr(sTarget))
set oDACL = oTargetSD.DiscretionaryACL
For Each oACE in oDACL
If sAccount = "" or UCase(sAccount) = UCase(oACE.Trustee) Then
sMsg = vbCrLf & "Trustee:" & String(iOffset - Len("Trustee:"), Chr(32)) & oACE.Trustee & vbCrLf
sMsg = sMsg & "ACE Type:" & String(iOffset - Len("ACE Type:"), Chr(32))
Select Case oACE.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
'Implicit Allow ACE
sMsg = sMsg & "ACCESS_ALLOWED"
Case ADS_ACETYPE_ACCESS_DENIED
'Implicit Deny ACE
sMsg = sMsg & "ACCESS_DENIED"
Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
'Object Allowed ACE
sMsg = sMsg & "ACCESS_ALLOWED_OBJECT"
Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
'Object Deny ACE
sMsg = sMsg & "ACCESS_DENIED_OBJECT"
End Select
Wscript.Echo sMsg
sAccessMask = ""
hAccessMask = 0
If iTarget = 0 Then
If (oACE.AccessMask AND FILE_READ_DATA) Then
sAccessMask = String(iOffset, Chr(32)) & "FILE_READ_DATA" & vbCrLf
hAccessMask = hAccessMask + FILE_READ_DATA
End If
If (oACE.AccessMask AND FILE_WRITE_DATA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_DATA" & vbCrLf
hAccessMask = hAccessMask + FILE_WRITE_DATA
End If
If (oACE.AccessMask AND FILE_APPEND_DATA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_APPEND_DATA" & vbCrLf
hAccessMask = hAccessMask + FILE_APPEND_DATA
End If
If (oACE.AccessMask AND FILE_READ_EA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_READ_EA" & vbCrLf
hAccessMask = hAccessMask + FILE_READ_EA
End If
If (oACE.AccessMask AND FILE_WRITE_EA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_EA" & vbCrLf
hAccessMask = hAccessMask + FILE_WRITE_EA
End If
If (oACE.AccessMask AND FILE_EXECUTE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_EXECUTE" & vbCrLf
hAccessMask = hAccessMask + FILE_EXECUTE
End If
If (oACE.AccessMask AND FILE_DELETE_CHILD) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_DELETE_CHILD" & vbCrLf
hAccessMask = hAccessMask + FILE_DELETE_CHILD
End If
If (oACE.AccessMask AND FILE_READ_ATTRIBUTES) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_READ_ATTRIBUTES" & vbCrLf
hAccessMask = hAccessMask + FILE_READ_ATTRIBUTES
End If
If (oACE.AccessMask AND FILE_WRITE_ATTRIBUTES) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_ATTRIBUTES" & vbCrLf
hAccessMask = hAccessMask + FILE_WRITE_ATTRIBUTES
End If
If (oACE.AccessMask AND DELETE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "DELETE" & vbCrLf
hAccessMask = hAccessMask + DELETE
End If
If (oACE.AccessMask AND READ_CONTROL) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "READ_CONTROL" & vbCrLf
hAccessMask = hAccessMask + READ_CONTROL
End If
If (oACE.AccessMask AND WRITE_DAC) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "WRITE_DAC" & vbCrLf
hAccessMask = hAccessMask + WRITE_DAC
End If
If (oACE.AccessMask AND WRITE_OWNER) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "WRITE_OWNER" & vbCrLf
hAccessMask = hAccessMask + WRITE_OWNER
End If
If (oACE.AccessMask AND SYNCHRONIZE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "SYNCHRONIZE" & vbCrLf
hAccessMask = hAccessMask + SYNCHRONIZE
End If
End If
If iTarget = 1 Then
If (oACE.AccessMask AND FILE_LIST_DIRECTORY) Then
sAccessMask = String(iOffset, Chr(32)) & "FILE_LIST_DIRECTORY" & vbCrLf
hAccessMask = hAccessMask + FILE_LIST_DIRECTORY
End If
If (oACE.AccessMask AND FILE_ADD_FILE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_ADD_FILE" & vbCrLf
hAccessMask = hAccessMask + FILE_ADD_FILE
End If
If (oACE.AccessMask AND FILE_ADD_SUBDIRECTORY) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_ADD_SUBDIRECTORY" & vbCrLf
hAccessMask = hAccessMask + FILE_ADD_SUBDIRECTORY
End If
If (oACE.AccessMask AND FILE_READ_EA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_READ_EA" & vbCrLf
hAccessMask = hAccessMask + FILE_READ_EA
End If
If (oACE.AccessMask AND FILE_WRITE_EA) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_EA" & vbCrLf
hAccessMask = hAccessMask + FILE_WRITE_EA
End If
If (oACE.AccessMask AND FILE_TRAVERSE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_TRAVERSE" & vbCrLf
hAccessMask = hAccessMask + FILE_TRAVERSE
End If
If (oACE.AccessMask AND FILE_DELETE_CHILD) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_DELETE_CHILD" & vbCrLf
hAccessMask = hAccessMask + FILE_DELETE_CHILD
End If
If (oACE.AccessMask AND FILE_READ_ATTRIBUTES) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_READ_ATTRIBUTES" & vbCrLf
hAccessMask = hAccessMask + FILE_READ_ATTRIBUTES
End If
If (oACE.AccessMask AND FILE_WRITE_ATTRIBUTES) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_ATTRIBUTES" & vbCrLf
hAccessMask = hAccessMask + FILE_WRITE_ATTRIBUTES
End If
If (oACE.AccessMask AND DELETE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "DELETE" & vbCrLf
hAccessMask = hAccessMask + DELETE
End If
If (oACE.AccessMask AND READ_CONTROL) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "READ_CONTROL" & vbCrLf
hAccessMask = hAccessMask + READ_CONTROL
End If
If (oACE.AccessMask AND WRITE_DAC) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "WRITE_DAC" & vbCrLf
hAccessMask = hAccessMask + WRITE_DAC
End If
If (oACE.AccessMask AND WRITE_OWNER) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "WRITE_OWNER" & vbCrLf
hAccessMask = hAccessMask + WRITE_OWNER
End If
If (oACE.AccessMask AND SYNCHRONIZE) Then
sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "SYNCHRONIZE" & vbCrLf
hAccessMask = hAccessMask + SYNCHRONIZE
End If
End If
sMsg = "ACE Permissions:" & String(iOffset - Len("ACE Permissions:"), Chr(32))
Select Case hAccessMask
Case adsFILE_FULL Wscript.Echo sMsg & "FULL CONTROL"
Case adsFOLDER_FULL Wscript.Echo sMsg & "FULL CONTROL"
Case adsFILE_CHANGE Wscript.Echo sMsg & "CHANGE"
Case adsFOLDER_CHANGE Wscript.Echo sMsg & "CHANGE"
Case adsFILE_READ Wscript.Echo sMsg & "READ"
Case adsFOLDER_READ Wscript.Echo sMsg & "READ"
Case adsFILE_NOACCESS Wscript.Echo sMsg & "NO ACCESS"
Case adsFOLDER_NOACCESS Wscript.Echo sMsg & "NO ACCESS"
Case Else WScript.Echo sMsg & "" & oACE.AccessMask
WScript.Echo sAccessMask
End Select
sMsg = "ACE Flags:" & String(iOffset - Len("ACE Flags:"), Chr(32))
If (oACE.AceFlags AND ADS_ACEFLAG_INHERIT_ACE) Then
WScript.Echo sMsg & "ADS_ACEFLAG_INHERIT_ACE"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE) Then
WScript.Echo sMsg & "ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_INHERIT_ONLY_ACE) Then
WScript.Echo sMsg & "ADS_ACEFLAG_INHERIT_ONLY_ACE"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_INHERITED_ACE) Then
WScript.Echo sMsg & "ADS_ACEFLAG_INHERITED_ACE"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_VALID_INHERIT_FLAGS) Then
WScript.Echo sMsg & "ADS_ACEFLAG_VALID_INHERIT_FLAGS"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_SUCCESSFUL_ACCESS) Then
WScript.Echo sMsg & "ADS_ACEFLAG_SUCCESSFUL_ACCESS"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_FAILED_ACCESS) Then
WScript.Echo sMsg & "ADS_ACEFLAG_FAILED_ACCESS"
End If
If (oACE.AceFlags AND ADS_ACEFLAG_UNKNOWN) Then
WScript.Echo sMsg & "ADS_ACEFLAG_UNKNOWN"
End If
End If
Next
WScript.Echo "Total ACE entries:" &_
String(iOffset - Len("Total ACE entries:"), Chr(32)) & oDACL.AceCount
WScript.Echo "ACL revision:" &_
String(iOffset - Len("ACL revision:"), Chr(32)) & oDACL.ACLRevision
End Sub
'**************************************************
'*** Subroutine recursing through content of folder (when setting permissions)
'*** necessary to propagate permissions set on parent folder (per Q266461)
'
Public Sub RecurseACLs(sTarget, sAccount, sPermission)
Dim oTarget 'object representing target folder or file
Dim oSubfolders 'collection representing subfolders of target folder
Dim oFiles 'collection representing files in target folder
Dim oSubfolder 'object representing a subfolder (used for enumeration)
Dim oFile 'object representing a file (used for enumeration)
If oFSO.FileExists(sTarget) Then
Call SetACLs(sTarget, sAccount, sPermission)
Else
Set oTarget = oFSO.GetFolder(sTarget)
WScript.Echo "Processing folder " & sTarget
Call SetACLs(oTarget.Path, sAccount, sPermission)
Set oFiles = oTarget.Files
'*** Apply permissions to files
For Each oFile in oFiles
WScript.Echo "Processing file " & oFile.Path
Call SetACLs(oFile.Path, sAccount, sPermission)
Next
Set oSubFolders = oTarget.SubFolders
'*** Apply permissions to subfolders
For Each oSubFolder in oSubFolders
Call RecurseACLs(oSubFolder.Path, sAccount, sPermission)
Next
Set oSubFolders = Nothing
Set oFiles = Nothing
End If
End Sub
'**************************************************
'*** Subroutine applying permissions for specified account
'
Sub SetACLs(sTarget, sAccount, sPermission)
Dim hMask 'value representing Access Mask
Dim hType 'value representing Access Type
Dim oSID 'object representing SID of a Security Principal
Dim oACE 'object representing ACE of target object
Dim hSID 'hexadecimal representation of SID
Dim oTarget 'object representing target folder or file
Dim oTargetSD 'object representing security descriptor of target file or folder
Dim oDACL 'object representing Discretionary Access Control List
Select Case UCase(sPermission)
Case "FULL"
hType = ADS_ACETYPE_ACCESS_ALLOWED
If iTarget = 0 Then
hMask = adsFILE_FULL
Else
hMask = adsFOLDER_FULL
End If
Case "CHANGE"
hType = ADS_ACETYPE_ACCESS_ALLOWED
If iTarget = 0 Then
hMask = adsFILE_CHANGE
Else
hMask = adsFOLDER_CHANGE
End If
Case "READ"
hType = ADS_ACETYPE_ACCESS_ALLOWED
If iTarget = 0 Then
hMask = adsFILE_READ
Else
hMask = adsFOLDER_READ
End If
Case "NOACCESS"
hType = ADS_ACETYPE_ACCESS_DENIED
If iTarget = 0 Then
hMask = adsFILE_NOACCESS
Else
hMask = adsFOLDER_NOACCESS
End If
Case Else
Call DisplayUsage("ERROR: Incorrect permission type.")
WScript.Quit
End Select
set oTargetSD = oADsSecurity.GetSecurityDescriptor("FILE://" & Cstr(sTarget))
set oDACL = oTargetSD.DiscretionaryACL
For Each oACE in oDACL
If UCase(oACE.Trustee) = UCase(sAccount) Then
oDACL.RemoveACE oACE
End If
Next
Set oACE = CreateObject("AccessControlEntry")
oACE.Trustee = sAccount
oAce.AceType = hType
oAce.AccessMask = hMask
oACE.AceFlags = ADS_ACEFLAG_INHERIT_ACE Or ADS_ACEFLAG_UNKNOWN
oDACL.AddAce oACE
Call ReorderDACL(oDACL)
oTargetSD.DiscretionaryACL = oDACL
oADsSecurity.SetSecurityDescriptor oTargetSD
End Sub
'**************************************************
'*** Subroutine reordering the ACLs (per Q279682)
'*** ACEs need to be properly ordered, since AddAce method does not perform ordering.
'*** If an access-allowed ACE appears before access-denied, a trustee will be granted access.
'*** The preferred order of ACEs in a DACL is described in MSDN Library (at msdn.microsoft.com).
'*** For Windows 2000, ACEs should be arranged into two main groups - non-inherited and inherited.
'*** Non-inherited ACEs should be listed first, followed by the inherited ones. Within each group
'*** (non-inherited and inherited), ACEs are arranged in the following fashion:
'*** - access-denied ACEs that apply to the object itself
'*** - access-denied ACEs that apply to subobjects of the object (including its properties)
'*** - access-allowed ACEs that apply to the object itself
'*** - access-allowed ACEs that apply to subobjects of the object (including its properties)
'***
'*** Since the script does not affect inherited ACEs (it sets permission directly on target object)
'*** they do not have to be rearranged. We only need to rearrange non-inherited ACEs
Sub ReorderDACL(oDACL)
Dim oNewDACL 'object used to temporarily store DACL (during ordering)
Dim oInheritedDACL 'object representing list of all Inherited ACEs
Dim oDenyDACL 'object representing list of non-Inherited Deny ACEs
Dim oAllowDACL 'object representing list of non-Inherited Allow ACEs
Dim oACE 'object representing ACE (used for enumeration)
'**************************************************
'*** Create Access Control List objects
Set oNewDACL = CreateObject("AccessControlList")
Set oInheritedDACL = CreateObject("AccessControlList")
Set oAllowDACL = CreateObject("AccessControlList")
Set oDenyDACL = CreateObject("AccessControlList")
'**************************************************
'*** Add individual ACEs into each of the lists
'*** based on the ACE Flags and ACE Type values
For Each oACE In oDACL
If ((oACE.AceFlags AND ADS_ACEFLAG_INHERITED_ACE) = ADS_ACEFLAG_INHERITED_ACE) Then
'**************************************************
'*** as explained, no sorting is needed for Inherited ACEs, they are simply
'*** added to the list and retrieved at the end of the sub in the same order
oInheritedDACL.AddAce oACE
Else
'**************************************************
'*** non-Inherited ACEs need to be placed in their respective list to be re-ordered
Select Case oACE.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
oAllowDACL.AddAce oACE
Case ADS_ACETYPE_ACCESS_DENIED
oDenyDACL.AddAce oACE
End Select
End If
Next
'**************************************************
'*** Recreate the Access Control List following the appropriate order
'*** - non-Inherited Deny ACEs
'*** - non-Inherited Allow ACEs
'*** - Inherited ACEs
For Each oACE In oDenyDACL
oNewDACL.AddAce oACE
Next
For Each oACE In oAllowDACL
oNewDACL.AddAce oACE
Next
For Each oACE In oInheritedDACL
oNewDACL.AddAce oACE
Next
Set oInheritedDACL = Nothing
Set oDenyDACL = Nothing
Set oAllowDACL = Nothing
'**************************************************
'*** Set appropriate DACL revision level
oNewDACL.AclRevision = oDACL.AclRevision
'**************************************************
'*** Reset the original DACL
Set oDACL = Nothing
Set oDACL = oNewDACL
end Sub