Recently I’ve wanted to review the account permissions on my home server that I use for backup. It has sometimes served as a sandbox of sorts; not best practice, but reality for hardware/monetary limits. Rather than spend the time right-clicking and checking the permissions on each folder I thought it’d be nice to write a WMI script to generate a report.
I knew this had to have been done before, and after some quick googlefu I can across this script by Amine Abdelkader that basically did everything I wanted.
I didn’t like the HTML output though, I want CSV so that it can be easily sorted, filtered, manipulated in Excel. I also wanted to control the depth of the search into subfolders and the total number of folders it would report on.
The script, modified for these changes, is listed below:
’ Original Author: Abdelkader, Amine
’ Original Date: 10/03/2006
’ Original Ouput: HTML File
’
’ Modified by: Randy Armknecht
’ Modified Date: 2009-11-05
’ Modified Output: CSV File, with ability to control depth of subfolder search (depth)
’ and ability to control total number of folders reported on (max_seen)
’
’========================================================================================
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const FullAccessMask = 2032127, ModifyAccessMask = 1245631, WriteAccessMask = 118009
Const ROAccessMask = 1179817
strComputer = “.“
sParentFolder = InputBox(“Please Enter folder to gather information on”, “Parent Folder”)
SParentFoldern=replace(sParentFolder,”\”,””)
SParentFoldern=replace(sParentFoldern,”:”,””)
max_seen = 1000
depth = 1
count = 0
Set fso = CreateObject(“Scripting.FileSystemObject”)
’File name Same As Folder Name without special Caracteres
fullfilename=SParentFoldern&”.csv“
’WScript.echo fullfilename
Set fsOut = fso.OpenTextFile(fullfilename, ForAppending, True)
On Error Resume Next
fsOut.Writeline “Folder, User Name, Permission“
fsOut.Close
ShowSubFolders FSO.GetFolder(sParentFolder),fullfilename
OutputFolderInfo sParentFolder, fullfilename
Set fsOut = fso.OpenTextFile(fullfilename, ForAppending, True)
fsOut.Writeline strTableFoot
fsOut.Close
MsgBox “Done “
WScript.Quit
Public Sub OutputFolderInfo(FolderName , sOutfile)
Const FullAccessMask = 2032127, ModifyAccessMask = 1245631, WriteAccessMask = 1180095
Const ROAccessMask = 1179817
Const ForReading = 1, ForWriting = 2, ForAppending = 8
strComputer = “.“
‘Build the path to the folder because it requites 2 backslashes
folderpath = Replace(FolderName, “\”, “\\”)
objectpath = “winmgmts:Win32_LogicalFileSecuritySetting.path=’” & folderpath & “‘“
‘Get the security set for the object
Set wmiFileSecSetting = GetObject(objectpath)
‘verify that the get was successful
RetVal = wmiFileSecSetting.GetSecurityDescriptor(wmiSecurityDescriptor)
If Err Then
‘MsgBox (“GetSecurityDescriptor failed” & vbCrLf & Err.Number & vbCrLf & Err.Description)
Err.Clear
End If
Set objWMIService = GetObject(“winmgmts:” & “{impersonationLevel=impersonate}!\\” & strComputer & “\root\cimv2”)
Set colFolders = objWMIService.ExecQuery(“SELECT * FROM Win32_Directory WHERE Name =’” & folderpath & “‘”)
For Each objFolder In colFolders
’ Retrieve the DACL array of Win32_ACE objects.
DACL = wmiSecurityDescriptor.DACL
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set fsOut = fso.OpenTextFile(sOutfile, ForAppending, True)
For Each wmiAce In DACL
’ Get Win32_Trustee object from ACE
Set Trustee = wmiAce.Trustee
fsOut.Write objFolder.Name&”,”&Trustee.Domain&”\”&Trustee.Name&”,“
FoundAccessMask = False
CustomAccessMask = Flase
While Not FoundAccessMask And Not CustomAccessMask
If wmiAce.AccessMask = FullAccessMask Then
AccessType = “Full Control“
FoundAccessMask = True
End If
If wmiAce.AccessMask = ModifyAccessMask Then
AccessType = “Modify“
FoundAccessMask = True
End If
If wmiAce.AccessMask = WriteAccessMask Then
AccessType = “Read/Write Control“
FoundAccessMask = True
End If
If wmiAce.AccessMask = ROAccessMask Then
AccessType = “Read Only“
FoundAccessMask = True
Else
CustomAccessMask = True
End If
Wend
If FoundAccessMask Then
fsOut.Write AccessType&vbCrLf
Else
fsOut.Write “Custom”&vbCrLf
End If
Next
Set fsOut = Nothing
Set fso = Nothing
Next
Set fsOut = Nothing
Set fso = Nothing
end Sub
Sub ShowSubFolders (Folder,fname)
On Error Resume Next
If count < depth then
count = count + 1
total_seen = 0
For Each Subfolder in Folder.SubFolders
if total_seen < max_seen then
total_seen = total_seen + 1
Call OutputFolderInfo(Subfolder.Path,fname)
‘Wscript.Echo Subfolder.Path
call ShowSubFolders (Subfolder,fname)
end if
Next
end if
End Sub