Question

I've found a vbscript at possibly defunct scripting blog that I would like to use on our Windows 7 system. When I attempt to use it, I get an Invalid Object Path from line 38:

Set objSecuritySettings = objWMIService.Get _
        ("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")

Any ideas of why the script would be producing this error? code source: http://www.indented.co.uk/index.php/2008/10/22/listing-explicit-rights/comment-page-1/#comment-3947

Option Explicit

' Looks for a Trustee containing the SECURITY_PRINCIPAL string on
' the file system. Recurses from BASE_PATH down (file and folders).

' Set these values for the search.

Const BASE_PATH = "C:\"
Const SECURITY_PRINCIPAL = "Chris"

Sub FSRecurse(strPath)
' Simple FS recursion

  Dim objFolder, objFile, objSubFolder

  Set objFolder = objFileSystem.GetFolder(strPath)

  For Each objFile in objFolder.Files
    CheckDescriptor objFile.Path
  Next
  For Each objSubFolder in objFolder.SubFolders
    CheckDescriptor objSubFolder.Path

    FSRecurse objSubFolder.Path
   Next

  Set objFolder = Nothing
End Sub

Sub CheckDescriptor(strPath)
  ' Look for the Trustee in the Security Descriptor and filter out
  ' inherited ACEs

  Const ACE_FLAG_INHERITED = &H10 ' 16

  Dim objSecuritySettings, objSecurityDescriptor, objACE, objTrustee

  Set objSecuritySettings = objWMIService.Get _
    ("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
  objSecuritySettings.GetSecurityDescriptor objSecurityDescriptor

  For Each objACE in objSecurityDescriptor.dACL
    If InStr(1, objACE.Trustee.Name, _
        SECURITY_PRINCIPAL, VbTextCompare) > 0 Then

      ' ACEFlags is binary. Must perform binary comparison.
      If objACE.ACEFlags And ACE_FLAG_INHERITED Then
        ' Problems with negation of the above.
        ' This is just easier.
      Else
        EnumAccess strPath, objACE
      End If
    End If
  Next
End Sub

Sub EnumAccess(strPath, objACE)
  ' Most access mask values have matching Folder versions. These are not
  ' numerically different, they only differ when interpreted.

  ' ACE Type

  Const ACCESS_ALLOWED_ACE_TYPE = &h0
  Const ACCESS_DENIED_ACE_TYPE  = &h1

  ' Base Access Mask values

  Const FILE_READ_DATA = &h1
  Const FILE_WRITE_DATA = &h2
  Const FILE_APPEND_DATA = &h4
  Const FILE_READ_EA = &h8
  Const FILE_WRITE_EA = &h10
  Const FILE_EXECUTE = &h20
  Const FILE_DELETE_CHILD = &h40
  Const FILE_READ_ATTRIBUTES = &h80
  Const FILE_WRITE_ATTRIBUTES = &h100
  Const FOLDER_DELETE = &h10000
  Const READ_CONTROL = &h20000
  Const WRITE_DAC = &h40000
  Const WRITE_OWNER = &h80000
  Const SYNCHRONIZE = &h100000

  ' Constructed Access Masks

  Dim FULL_CONTROL
  FULL_CONTROL = FILE_READ_DATA + FILE_WRITE_DATA + FILE_APPEND_DATA + _
    FILE_READ_EA + FILE_WRITE_EA + FILE_EXECUTE + FILE_DELETE_CHILD + _
    FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + FOLDER_DELETE + _
    READ_CONTROL + WRITE_DAC + WRITE_OWNER + SYNCHRONIZE

  Dim READ_ONLY
  READ_ONLY = FILE_READ_DATA + FILE_READ_EA + FILE_EXECUTE + _
    FILE_READ_ATTRIBUTES + READ_CONTROL + SYNCHRONIZE

  Dim MODIFY
  MODIFY = FILE_READ_DATA + FILE_WRITE_DATA + FILE_APPEND_DATA + _
    FILE_READ_EA + FILE_WRITE_EA + FILE_EXECUTE + _
    FILE_READ_ATTRIBUTES + _
    FILE_WRITE_ATTRIBUTES + FOLDER_DELETE + READ_CONTROL + SYNCHRONIZE


  Dim strRights
  Dim intAccessMask

  WScript.Echo "Path: " & strPath
  WScript.Echo "Username: " & objACE.Trustee.Name
  WScript.Echo "Domain: " & objACE.Trustee.Domain
  WScript.Echo "ACE Flags (Decimal): " & objACE.ACEFlags

  ' ACE Type

  If objACE.ACEType = ACCESS_ALLOWED_ACE_TYPE Then
    WScript.Echo "ACE Type: Allow"
  Else
    WScript.Echo "ACE Type: Deny"
  End If

  ' Attempt to generate a basic summary of access rights

  strRights = ""
   intAccessMask = objACE.AccessMask

  If intAccessMask = FULL_CONTROL Then
    strRights = " (FullControl)"
  ElseIf intAccessMask = MODIFY Then

    strRights = " (Modify)"
  ElseIf intAccessMask = READ_ONLY Then
    strRights = " (ReadOnly)"
  End If

  ' Echo the decimal mask with any summarised rights

  WScript.Echo "Access Mask (Decimal): " & intAccessMask & strRights

  WScript.Echo
End Sub

'
' Main code block
'

 Dim objFileSystem, objWMIService

Set objFileSystem = CreateObject("Scripting.FileSystemObject")
' WMI Connection to the local machine
Set objWMIService = GetObject("winmgmts:\\.")

FSRecurse BASE_PATH

Set objWMIService = Nothing
Set objFileSystem = Nothing
Was it helpful?

Solution

You don't escape backslashes in strPath. Backslashes are escape characters in WMI, so unless you turn them into literal backslashes by doubling them, the WMI query won't be able to locate the file.

Also, there's another potential glitch in the command. It uses single quotes for quoting the file name. Single quotes are valid characters in NTFS file names, though. If your script runs into a file whose name contains a single quote that character will prematurely terminate the file name string in the WMI query, and the remainder of the file name will render the query invalid. I ran into the same issue when I wrote this.

Replacing this:

Set objSecuritySettings = objWMIService.Get _
  ("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")

with this:

Set objSecuritySettings = objWMIService.Get _
  ("Win32_LogicalFileSecuritySetting.Path=""" & Replace(strPath,"\","\\") & """")

should get you rid of both problems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top