Tech Line

Auditing Locally Shared Folders

Here’s a script that enumerates all shared folders on all computers in your domain.

Your local group membership enumeration script was excellent. That satisfies part of my local SAM concerns. Now I need one that will get all the local and domain groups that are tied to shares on that system -- sort of like ShareEnum from SysInternals, but one that works for an entire domain and is vbs and command-line-based. This way we can tell how many systems are being managed with local accounts and groups that should be in the domain context instead.
-- Chris

Tech Help—Just An
E-Mail Away

Got a Windows, Exchange or virtualization question or need troubleshooting help? Or maybe you want a better explanation than provided in the manuals? Describe your dilemma in an e-mail to the MCPmag.com editors at mailto:[email protected]; the best questions get answered in this column and garner the questioner with a nifty Redmond T-shirt.

When you send your questions, please include your full first and last name, location, certifications (if any) with your message. (If you prefer to remain anonymous, specify this in your message, but submit the requested information for verification purposes.)

Good question, Chris. Keeping tracking of shared folders across your domain is an important consideration. While GUI tools like GFI LANguard offer this feature, I can see how a script would be useful.

Using the same context as my local administrator group enumeration script, I wrote the following script to solve your problem:

'shareaudit.vbs
On Error Resume Next
Const ForWriting = 2
' Format date/time stamp for output file
strTimeDate = Year(Date) & "-" & Month(Date) & _
  "-" & Day(Date) & "~~" & Hour(Time) & "-" & _
   Minute(Time)
' Output file name and path
strLogFile = "C:\ShareAudit-" & strTimeDate & _
   ".txt"

'Create Log File
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile (strLogFile, _
   ForWriting, True)

' Connect to domain and collect computer accounts
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
set objRootDSE = GetObject("LDAP://RootDSE")
objCommand.CommandText = _
  "SELECT Name, Location FROM 'LDAP://" & _
  objRootDSE.Get("defaultNamingContext") & "'" _
  & "WHERE objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Timeout") = 30
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Cache Results") = False
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

' Output domain computer accounts, connect to each ' computer, and enumerate shares and permissions
Do Until objRecordSet.EOF
  strComputer = objRecordSet.Fields("Name").Value
  objFile.WriteLine "System: " & strComputer
' connect to computer
Set objWMIsvc = GetObject("winmgmts:\\" & _
   strComputer & "\root\cimv2")
  If Err <> 0 Then
   objFile.Writeline("*** System Unreachable ***")
   Err.Clear
  Else
   ' enumerate shares
   Set colShares = objWMIsvc.ExecQuery _
   ("SELECT * FROM Win32_Share")

  

' display ACE
   For Each objShare In colShares
   objFile.WriteLine "Share Name:" & objShare.Name
   objFile.WriteLine " Path: " & objShare.Path
   Set wmiShareSec = objWMIsvc.Get _
   ("Win32_LogicalShareSecuritySetting.Name='" &_
   objShare.Name & "'")
   RetVal = wmiShareSec._
   GetSecurityDescriptor(wmiSecurityDescriptor)
   DACL = wmiSecurityDescriptor.DACL
   For Each wmiACE In DACL
   Set Trustee = wmiACE.trustee
   objFile.Writeline(" Account: " & _
   Trustee.Domain & "\" & Trustee.Name)
   Set ACEType = wmiACE.AceType
   Select Case int(wmiACE.AceType)
   Case 0 PermType = "Allow"
   Case 1 PermType = "Deny"
   End Select
   objFile.Writeline(" Permission Type: " & _
   PermType)
   Select Case Int(wmiACE.AccessMask)
   Case 1179817 SharePerm = "Read"
   Case 1245631 SharePerm = "Change"
   Case 2032127 SharePerm = "Full Control"
   Case Else SharePerm = "Access Mask " & _    wmiACE.AccessMask
   End Select
   objFile.Writeline(" Assigned Permission: " & _
   SharePerm)
   objFile.Writeline()
   Next
   Next
  End If
  objRecordSet.MoveNext
  objfile.writeline("-------------------------------")
  objfile.writeline()
Loop
' All done!
WScript.Echo("Audit Complete!")

This script will collect a list of each domain computer and then attempt to connect to each computer in the domain. Once the connection is established all hidden and non-hidden shares will be written to the text file whose name and format is specified by strLogFile variable. The output will be a log file on the C drive by default. Here is a sample of the file contents from a system in my lab:

System: DC1
Share Name:Records
   Path: c:\records
   Account: BUILTIN\Administrators
   Permission Type: Allow
   Assigned Permission: Full Control

Share Name:C$
   Path: C:\
   Account: BUILTIN\Administrators
   Permission Type: Allow
   Assigned Permission: Full Control

Share Name:Public
   Path: C:\Public
   Account: MCP\cbeltran
   Permission Type: Deny
   Assigned Permission: Read

Account: MCP\dmcnabb
   Permission Type: Deny
   Assigned Permission: Change

Account: MCP\dwright
   Permission Type: Deny
   Assigned Permission: Full Control

Account: MCP\Accounting
   Permission Type: Allow
   Assigned Permission: Read

Account: BUILTIN\Administrators
   Permission Type: Allow
   Assigned Permission: Full Control

-------------------------------

System: RS1
*** System Unreachable ***
-------------------------------

When run without any modifications, the script will create a log file that includes the date and time in which the script was run. For example, you may see an output file named ShareAudit-2006-12-5~~12-52.txt. Note that the time is included after the consecutive tildes. Once the script completes, it will notify you with an "Audit Complete!" pop-up message. Since you would probably want to know when a system is unreachable (such as if it is turned off when the script is run), I have the script include the line "*** System Unreachable ***" for any system that the script could not establish a connection with. Note that for connecting to and auditing Windows XP SP2 systems, you will need to ensure that the XP firewall is configured to allow remote management. Steps for troubleshooting XP SP2-related issues with WMI can be found in the Microsoft Support Article, "How to Troubleshoot WMI-related Issues in Windows XP SP2."

Auditing shares and assigned share permissions is an important part of network administration. Since some of the command line tools out there only show you the non-hidden shares, having a script that can show you all shares on every system can be quite handy. I hope this script will make your job a little easier.

About the Author

Chris Wolf is a Microsoft MVP for Windows --Virtual Machine and is a MCSE, MCT, and CCNA. He's a Senior Analyst for Burton Group who specializes in the areas of virtualization solutions, high availability, storage and enterprise management. Chris is the author of Virtualization: From the Desktop to the Enterprise (Apress), Troubleshooting Microsoft Technologies (Addison Wesley), and a contributor to the Windows Server 2003 Deployment Kit (Microsoft Press).learningstore-20/">Troubleshooting Microsoft Technologies (Addison Wesley) and a contributor to the Windows Server 2003 Deployment Kit (Microsoft Press).

comments powered by Disqus
Most   Popular

Upcoming Training Events