Managing Windows Registry with Scripting (Part 4)

By ServerWatch Staff (Send Email)
Posted Sep 9, 2002


by Marcin Policht

After looking at the ways of displaying permissions on Windows registry, it is time to explore methods of changing them. As you realize by now, this is accomplished by using Access Control Entries associated with each registry key. Despite some differences, these entries work in a manner very similar to the one implemented by permissions on the NTFS file system. Because of this similarity, you might want to refer to another series of my articles dealing with NTFS permissions (they are also published on the Swynk web site). They should help you understand the structure of the Access Control Entries and get familiar with the way these entries can be modified. Besides setting various propeties of Access Control Entries (such as Acces Type, Access Flag, or Trustee), ACEs need to be also rearranged in proper order. You can refer to the Microsoft Knowledge Base article Q269159 for details. The reasons for this additional step are explained briefly in comments to the Sub ReorderDACL in the script RegPerm.vbs below.

In his latest article, Marcin Policht takes an in-depth look at managing permissions in the Windows Registry using Windows Management Instrumentation (WMI) methods.

The script RegPerm.vbs operates in one of two modes, determined by the value of the ACTION input parameter. Value of SET, causes the script to grant or deny the permissions to the registry key (which path is specified as TARGET input parameter) for a user or group account (set with ACCOUNT parameter). Value of SHOW, displays the content of access control entries for an arbitrarily chosen registry key. A separate script offering this functionality has been presented in the Part 3 of the series). This script, however, has been modified to allow references to remote computers. This is done by including a computer name in the TARGET input parameter. This feature can also be used when modifying permissions with SET option.

For example, in order to display the permissions on the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows registry key on the computer SWYNKPC001, you would run the follwing at the Command Prompt from the folder in which the RegPerm.vbs resides:


cscript /nologo RegPerm.vbs ACTION=SHOW 
TARGET="SWYNKPC001\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"

If you omit computer name entry in the target registry path, the script will set the permissions on the local system:


cscript /nologo RegPerm.vbs ACTION=SHOW 
TARGET="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"

Setting permissions requires providing two additional parameters: ACCOUNT and PERM. Domain accounts need to be specified in the format DOMAIN\AccountName, e.g. SWYNK\MPolicht (for MPolicht account in the SWYNK domain). If the account is local, you can use the format COMPUTERNAME\AccountName or simply AccountName. PERM parameter can take one of the following values:

  • FULL
  • WRITE
  • READ
  • NOACCESS
  • "" (empty string)

FULL grants the account you specified with ACCOUNT parameter full control over the key. WRITE allows writing to the registry key by setting three individual permissions (KEY_SET_VALUE, KEY_CREATE_SUB_KEY, and READ_CONTROL). NOACCESS denies Full Control to the key, which effectively prevents any type of access. Finally, if PERM is set to an empty string , the account is removed from the list of Access Control Entries. Note, that removing the account from the list of ACEs is different from setting NOACCESS permissions. The latter will always prevent access for a given account, the former might still allow access if a group that account is a member of has some type of permissions granted.

The permissions set with the script will overwrite any of the existing permissions, but only for the account you specify. They will also be granted only to the key itself (and all of its values), but will not propagate to any of the subkeys. However, you can use the INH input parameter (which can be set to values YES or NO), which determines the permissions inheritance by all subkeys created afterwards. Setting INH to YES, will cause permissions set by the script on the top level key to be inherited by any new subkeys. Correspondingly, setting INH to NO (default) will ensure that permissions on any new subkeys will not contain the ACE set by the script. Note that the INH parameter only affects the entry for the single user account that you specified when running the script.

Here are a few examples of using the SET option:


cscript /nologo RegPerm.vbs ACTION=SET 
TARGET="SWYNKPC001\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows" 
ACCOUNT=SWYNK\MPolicht PERM=FULL INH=NO
will grant the Full Control permissions for the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows key on the SWYNKPC001 computer to the SWYNK\MPolicht account and prevent inheritance.

cscript /nologo RegPerm.vbs ACTION=SET 
TARGET="SWYNKPC001\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows" 
ACCOUNT=SWYNK\MPolicht PERM=READ
will change these permissions to Read (and maintain inheritance settings, since NO is the default)

cscript /nologo RegPerm.vbs ACTION=SET 
TARGET="SWYNKPC001\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows" 
ACCOUNT=SWYNK\MPolicht PERM=
will remove entry for SWYNK\MPolicht account from the list of Access Control Entries.

Remember that the script requires ADsSecurity.dll to be present and registered on the system from which the script is running. As mentioned before, this DLL is included in the ADSI 2.5 Software Development Kit (SDK) downloadable from the Microsoft Web site.


'//////////////////////////////////////////////////////////////////////////
'/// Name:	RegPerm.vbs
'/// Version:	1.0
'/// Date:	09/01/02
'/// Purpose: 	displaying and setting permissions on the registry keys
'/// OS:	Windows 2000, XP
'/// Reqs:	ADsSecurity.dll (registered)
'/// Syntax:	cscript /nologo RegPerm.vbs ACTION=SET TARGET=Registry_Key _
'///			ACCOUNT=Domain\Account PERM=Read|Change|Full|NoAccess INH=YES|NO"
'///		where	ACTION is set to SHOW or SET (to display or set permissions)"
'///			TARGET is full path to registry key (computer name is optional)
'///			e.g. "Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"
'///			if computer name is omitted, local system is used
'///			ACCOUNT is user or group in DOMAIN\AccountName format
'///			PERM specifies type of permissions to be set
'///			INH determines permission inheritance (Yes or No)
'//////////////////////////////////////////////////////////////////////////

Option Explicit
'On Error Resume Next

'////////////////////////////////////////////////////
'/// Constant Declarations

'////////////////////////////////////////////////////
'/// Access Control Entry Inheritance Flags
'/// Allowed 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
'/// Allowed 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

'//////////////////////////////////////////////////
'/// Registry Permission Type Values

Const KEY_QUERY_VALUE 		= &H0001
Const KEY_SET_VALUE 		= &H0002
Const KEY_CREATE_SUB_KEY 	= &H0004
Const KEY_ENUMERATE_SUB_KEYS 	= &H0008
Const KEY_NOTIFY 		= &H0010
Const KEY_CREATE_LINK 		= &H0020
Const DELETE 			= &H00010000
Const READ_CONTROL 		= &H00020000
Const WRITE_DAC 		= &H00040000
Const WRITE_OWNER 		= &H00080000

Dim KEY_READ		'access mask designating read access to registry key
Dim KEY_WRITE		'access mask designating write access to registry key
Dim KEY_ALL_ACCESS	'access mask designating full access to registry key

Dim iOffset		'used for display only (left justifying displayed values)
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 set
Dim sTarget		'string representing path to target registry key
Dim sInh		'value representing inheritance behavior (1 yes, 0 no)

Dim oADSSecurity	'object representing ADsSecurity class
Dim oTargetSD		'object representing security descriptor of registry key
Dim oDACL		'object representing Discretionary Access Control List

'//////////////////////////////////////////////////
'/// Set variables

'/// KEY_READ is a combination of KEY_QUERY_VALUE,
' 	KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and READ_CONTROL access.
KEY_READ = KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + 
READ_CONTROL

'/// KEY_WRITE is a combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY 
access.
KEY_WRITE = KEY_SET_VALUE + KEY_CREATE_SUB_KEY + READ_CONTROL

'/// KEY_FULL_ACCESS is a combination of KEY_QUERY_VALUE, KEY_SET_VALUE,
'	KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY,	KEY_CREATE_LINK,
'	DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access.
KEY_ALL_ACCESS = KEY_QUERY_VALUE + KEY_SET_VALUE + KEY_CREATE_SUB_KEY + _
		KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + KEY_CREATE_LINK + _
		DELETE + READ_CONTROL + WRITE_DAC + WRITE_OWNER

iOffset 		= 20

'//////////////////////////////////////////////////
'/// Retrieve script arguments

Call GetArguments(Wscript.Arguments, sAction, sTarget, sAccount, 
sPermission, sInh)

Set oADSSecurity 	= CreateObject("ADsSecurity")
Set oTargetSD		= oADsSecurity.GetSecurityDescriptor("RGY://" & sTarget)
Set oDACL		= oTargetSD.DiscretionaryACL

Select Case UCase(sAction)

	Case "SHOW"
			Call DisplayACLs()
	Case "SET"
			Call SetACLs(sAccount, sPermission, sInh)
	Case Else
			Call DisplayUsage("ERROR: Incorrect ACTION type")

End Select

Set oDACL		= Nothing
Set oTargetSD		= Nothing
Set oADsSecurity	= Nothing

Wscript.Quit


'///////////////////////////////////////////////////////////////////
'/// Name:	GetArguments
'/// Purpose:	Reading command line arguments
'/// Input:	oArgs		WScript.Arguments collection
'/// Output:	sAction		Action type (SET or SHOW)
'///		sTarget		Registry key
'///		sAccount	Account to set permissions for
'///		sPermission	Type of permissions to set
'///		sInh		Permission inheritance (1 yes, 0 no)
'///////////////////////////////////////////////////////////////////

Sub GetArguments(oArgs, sAction, sTarget, sAccount, sPermission, sInh)

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)
		Case "INH"	sInh		= Split(WScript.Arguments(iCount), "=")(1)
	End Select
Next

If sAction = "" or sTarget = "" or (sAction = "SET" and (sTarget = "" or 
sAccount = "")) Then
	Call DisplayUsage("ERROR: Missing argument(s)")
	WScript.Quit
End If

end sub

'///////////////////////////////////////////////////////////////////
'/// Name:	DisplayUsage
'/// Purpose:	Displaying usage of the script from the command line
'/// Input:	sHeader		Header for Message Box
'///////////////////////////////////////////////////////////////////

sub DisplayUsage(sHeader)

Dim sMsg

	sMsg = "To display permissions on a registry key, run:"
	sMsg = sMsg & VbCrLf & _
		"cscript //nologo RegPerms.vbs ACTION=SHOW TARGET=Registry_Key"
	sMsg = sMsg & VbCrLf & vbCrLf & "To set permissions on a registry key run:"
	sMsg = sMsg & VbCrLf & _
		"cscript //nologo RegPerms.vbs ACTION=SET TARGET=Registry_Key " & _
		"ACCOUNT=Domain\Account PERM=Read|Change|Full|NoAccess INH=YES|NO"
	sMsg = sMsg & VbCrLf & vbCrLf & "Where:"
	sMsg = sMsg & VbCrLf & String(7," ") & "ACTION is set to SHOW or SET (to 
display or set permissions, respectively)"
	sMsg = sMsg & VbCrLf & String(7," ") & "TARGET is full path to the registry 
key (computer name is optional)"
	sMsg = sMsg & VbCrLf & String(7," ") & "e.g. " & 
"""Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows"""
	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"
	sMsg = sMsg & VbCrLf & String(7," ") & "INH determines permission 
inheritance (Yes or No)"

	Call MsgBox(sMsg, vbOKOnly, sHeader)

end sub

'///////////////////////////////////////////////////////////////////
'/// Name:	SetACLs
'/// Purpose:	Setting Access Control List entry
'/// Input:	sAccount	Account to set permissions for
'///		sPermission	Type of permissions to set
'///		sInh		Permission inheritance (yes or no)
'///////////////////////////////////////////////////////////////////

Sub SetACLs(sAccount, sPermission, sInh)

Dim oACE

	For Each oACE in oDACL
        	If UCase(oACE.Trustee) = UCase(sAccount) Then
                	oDACL.RemoveACE oACE
		End if
	Next

	oTargetSD.DiscretionaryACL = oDACL
	oADsSecurity.SetSecurityDescriptor oTargetSD

	Set oACE = CreateObject("AccessControlEntry")
	oACE.Trustee = sAccount

	Select Case UCase(sPermission)
        	Case "FULL"
        		oACE.AccessMask = KEY_ALL_ACCESS
			oACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED
		Case "CHANGE"
			oACE.AccessMask = KEY_WRITE
			oACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED
        	Case "READ"
			oACE.AccessMask = KEY_READ
			oACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED
		Case "NOACCESS"
        		oACE.AccessMask = KEY_ALL_ACCESS
			oACE.AceType = ADS_ACETYPE_ACCESS_DENIED
		Case ""
			Exit Sub
		Case Else
			DisplayUsage("ERROR: Incorrect Permission Type")
	End Select

	If UCase(sInh) = "YES" Then
		oACE.AceFlags = ADS_ACEFLAG_INHERIT_ACE
	Else
		oACE.AceFlags = ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE
	End If

	oDACL.AddAce oACE

	Call ReorderDACL(oDACL)

	oTargetSD.DiscretionaryACL = oDACL
	oADsSecurity.SetSecurityDescriptor oTargetSD

End Sub

'///////////////////////////////////////////////////////////////////
'/// Name:	ReorderDACL
'/// Purpose:	reordering the ACLs (per Q269159)
'/// 		ACEs need to be ordered, since AddAce method does not take care of 
it.
'/// 		For Windows 2000 and later, ACEs should be arranged into two main 
groups
'///		 - non-inherited
'///		 - inherited.
'/// 		Non-inherited ACEs should be listed first, followed by the inherited 
ones.
'///		Within each group, 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
'///		 - access-allowed ACEs that apply to the object itself
'///		 - access-allowed ACEs that apply to subobjects of the object
'///		Since the script does not affect inherited ACEs (but instead, it sets
'///		permission directly on target object), they do not have to be 
rearranged.
'///		Only non-inherited ACEs are rearranged.
'/// Input:	oOrgDACL	object representing discretionary access list for 
registry key
'///////////////////////////////////////////////////////////////////

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 oDenyObjDACL		'object representing list of non-Inherited Deny Object 
ACEs
Dim oAllowDACL			'object representing list of non-Inherited Allow ACEs
Dim oAllowObjDACL		'object representing list of non-Inherited Allow Object 
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")
Set oDenyObjDACL = CreateObject("AccessControlList")
Set oAllowObjDACL = 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
			Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
				oAllowObjDACL.AddAce oACE
			Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
				oDenyObjDACL.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 oDenyObjDACL
	 oNewDACL.AddAce oACE
Next
For Each oACE In oAllowDACL
	  oNewDACL.AddAce oACE
Next
For Each oACE In oAllowObjDACL
	  oNewDACL.AddAce oACE
Next
For Each oACE In oInheritedDACL
	  oNewDACL.AddAce oACE
Next

Set oInheritedDACL = Nothing
Set oDenyDACL = Nothing
Set oAllowDACL = Nothing
Set oDenyObjDACL = Nothing
Set oAllowObjDACL = Nothing

'//////////////////////////////////////////////////
'/// Set appropriate DACL revision level

oNewDACL.AclRevision = oDACL.AclRevision

'//////////////////////////////////////////////////
'/// Reset the original DACL
Set oDACL = Nothing
Set oDACL = oNewDACL

end Sub

'///////////////////////////////////////////////////////////////////
'/// Name:	DisplayACLs
'/// Purpose:	Displaying Access Control List entries
'///////////////////////////////////////////////////////////////////

Sub DisplayACLs()

Dim oACE		'object representing individual ACE
Dim sMsg, sAccessMask	'strings containing message to be displayed
Dim hAccessMask		'number representing Access Mask value

	WScript.Echo "Permissions on " & sTarget

	For Each oACE in oDACL
		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 (oACE.AccessMask AND KEY_QUERY_VALUE) Then
			sAccessMask = String(iOffset, Chr(32)) & "KEY_QUERY_VALUE" & vbCrLf
			hAccessMask = hAccessMask + KEY_QUERY_VALUE
		End If
		If (oACE.AccessMask AND KEY_SET_VALUE) Then
			sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "KEY_SET_VALUE" & 
vbCrLf
			hAccessMask = hAccessMask + KEY_SET_VALUE
		End If
		If (oACE.AccessMask AND KEY_CREATE_SUB_KEY) Then
			sAccessMask = sAccessMask & String(iOffset, Chr(32)) & 
"KEY_CREATE_SUB_KEY" & vbCrLf
			hAccessMask = hAccessMask + KEY_CREATE_SUB_KEY
		End If
		If (oACE.AccessMask AND KEY_ENUMERATE_SUB_KEYS) Then
			sAccessMask = sAccessMask & String(iOffset, Chr(32)) & 
"KEY_ENUMERATE_SUB_KEYS" & vbCrLf
			hAccessMask = hAccessMask + KEY_ENUMERATE_SUB_KEYS
		End If
		If (oACE.AccessMask AND KEY_NOTIFY) Then
			sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "FILE_WRITE_EA" & 
vbCrLf
			hAccessMask = hAccessMask + KEY_NOTIFY
		End If
		If (oACE.AccessMask AND KEY_CREATE_LINK) Then
			sAccessMask = sAccessMask & String(iOffset, Chr(32)) & "KEY_CREATE_LINK" 
& vbCrLf
			hAccessMask = hAccessMask + KEY_CREATE_LINK
		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

		sMsg = "ACE Permissions:" & String(iOffset - Len("ACE Permissions:"), 
Chr(32))
		Select Case hAccessMask
			Case KEY_ALL_ACCESS 	Wscript.Echo sMsg & "FULL CONTROL"
			Case KEY_WRITE 	Wscript.Echo sMsg & "WRITE"
			Case KEY_READ 	Wscript.Echo sMsg & "READ"
			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
	Next
End Sub

Page 1 of 1


Comment and Contribute

Your name/nickname

Your email

(Maximum characters: 1200). You have characters left.