This information is useful for gauging the use of file servers in particular, including the detail of which users are connected and what files they have locked.
Querying information against a single computer:
- Run 'compmgmt.msc /computer=%server%' and look in 'Shared Folders' for Shares, Sessions and 'Open Files'
- Run 'procexp.exe' (Process Explorer - SysInternals) on the machine and view the handles of the server service
- psexec \\%server% net file
- psloggedon \\server
- psexec \\%server% -c handle.exe
Querying against one or more computers:
- for %i in (server1 server2 server3 server4) do wmic /node:"%i" path win32_serverconnection get * /format:csv >> ServerConnections.txt
- for %i in (server1 server2 server3 server4) do wmic /node:"%i" path win32_serversession get * /format:csv >> ServerSessions.txt
- for %i in (server1 server2 server3 server4) do cscript //nologo listOpenFiles.vbs %i >> OpenFiles_%dateflat%.txt
- for %i in (server1 server2 server3 server4) do psexec \\%i net file
$servers = ("server1", "server2") foreach {. .\EnumOpenFiles.ps1 -s $_} write-host
Closing handles:
- The compmgmt.msc GUI
- The .remove method in the VBS below
- net session \\%client% [/delete]
- net file %id% [/close]
' VBScript
On Error Resume Next
If wscript.arguments.count = 1 Then
strserver = wscript.arguments.unnamed(0)
Else
wscript.echo "Error, no server name provided"
wscript.quit(0)
End If
Set objConnection = GetObject("WinNT://" & strServer & "/LanmanServer")
Set colResources = objConnection.Resources
For Each objResource in colResources
Wscript.Echo objResource.User & "," & objResource.LockCount & "," & objResource.Path & "," & objResource.Name
' Remove the session: colResources.Remove(objResource.Name)
Next
-
# PowerShell
# EnumOpenFiles #
#
# 28/07/2008, martinwx, Initial version
#
#
# Description:
# Call NetFileEnum() to enumerate open files on a file server
# the computer that a user is connecting from.
#
# Assumptions, this script works on the assumption that:
# The caller has administrator or server operator rights to the specified machines
#
# Usage
# Enumerate open files from the specified server:
# . .\EnumOpenFiles.ps1 -s server
#
# References
# http://msdn.microsoft.com/en-us/library/bb525378(VS.85).aspx
# http://support.microsoft.com/kb/176738
$server = $null
if (($args.count -eq 2) -or ($args.count -eq 4)) {
for ($i = 0; $i -le $args.count-1; $i+=2) {
if ($args[$i].ToLower().Contains("-s")) {
$server = $args[$i+1]
} elseif ($args[$i].ToLower().Contains("-v")) {
$verbosePreference = $args[$i+1]
}
}
}
$info = ""
if ($server -eq $null) {
write-output "No server specified, listing local files"
}
$provider = new-object Microsoft.VisualBasic.VBCodeProvider
$params = new-object System.CodeDom.Compiler.CompilerParameters
$params.GenerateInMemory = $True
$refs = "System.dll","Microsoft.VisualBasic.dll"
$params.ReferencedAssemblies.AddRange($refs)
# VB.NET EXAMPLE
$txtCode = @'
Imports System
Imports System.Runtime.InteropServices
Imports System.Net
Class EnumFiles
Const ERROR_SUCCESS As Long = 0
Private Const MAX_PREFERRED_LENGTH As Long = -1
Private Const PERM_FILE_READ = &h1
Private Const PERM_FILE_WRITE = &h2
Private Const PERM_FILE_CREATE = &h4
Private Const ACCESS_EXEC = &h08 ' Execute Permission (X)
Private Const ACCESS_DELETE = &h10 ' Delete Permission (D)
Private Const ACCESS_ATRIB = &h20 ' Change Attribute Permission (A)
Private Const ACCESS_PERM = &h40 ' Change ACL Permission (P)
Private Structure FILE_INFO_3
public fi3_id As Integer
public fi3_permissions As Integer
public fi3_num_locks As Integer
public fi3_pathname As String
public fi3_username As String
'fi3_id Specifies a DWORD value that contains the identification number assigned to the resource when it is opened.
'fi3_permissions Specifies a DWORD value that contains the access permissions associated with the opening application. This member can be one or more of the following values.
'fi3_num_locks Specifies a DWORD value that contains the number of file locks on the file, device, or pipe.
'fi3_pathname Pointer to a string that specifies the path of the opened resource.
'fi3_username Pointer to a string that specifies which user (on servers that have user-level security) or which computer (on servers that have share-level security) opened the resource. Note that Windows does not support share-level security.
End Structure
Declare Auto Function NetApiBufferFree Lib "netapi32" (ByVal Buffer As Long) As Long
Declare Function NetFileEnum Lib "netapi32.dll" ( _
ByVal servername As String, _
ByVal basepath As String, _
ByVal username As String, _
ByVal level As Integer, _
ByRef bufptr As Integer, _
ByVal prefmaxlen As Integer, _
ByRef entriesread As Integer, _
ByRef totalentries As Integer, _
ByVal resume_handle As Integer) As Integer
Function Main(Optional ByVal servername As String = Nothing) As String()
Dim result As Long
Dim ptr As IntPtr
Dim bufptr As Long 'out buffer
Dim i As Integer
Dim fi3 As FILE_INFO_3
Dim finfo As Object
Dim dwEntriesread As Long 'out
Dim dwTotalentries As Long 'out
Dim dwResumehandle As Long 'out
Dim iPermissions As Integer
Dim sPermissions As String = ""
If servername = "" Then servername = Nothing
result = NetFileEnum(servername, _
Nothing, _
Nothing, _
3, _
bufptr, _
MAX_PREFERRED_LENGTH, _
dwEntriesRead, _
dwTotalEntries, _
Nothing)
'Console.WriteLine("Entries: " + dwTotalentries.ToString() + ", " + dwEntriesRead.ToString())
Dim output(dwEntriesRead-1) As String ' Re-dim the array for the number of results
if result = 0 then
ptr = BufPtr ' Convert long to pointer
For i = 0 To dwEntriesread -1
sPermissions = ""
ptr = BufPtr ' Convert long to pointer
fi3 = CType(Marshal.PtrToStructure(ptr, GetType(FILE_INFO_3)),FILE_INFO_3) ' Marshal this record of the output buffer to the structure
BufPtr = BufPtr + Marshal.SizeOf(fi3) ' Increment for the next record
iPermissions = fi3.fi3_permissions
If (iPermissions AND PERM_FILE_READ) Then sPermissions = sPermissions + "+Read"
If (iPermissions AND PERM_FILE_WRITE) Then sPermissions = sPermissions + "+Write"
If (iPermissions AND PERM_FILE_CREATE) Then sPermissions = sPermissions + "+Create"
If (iPermissions AND ACCESS_EXEC) Then sPermissions = sPermissions + "+Execute"
If (iPermissions AND ACCESS_DELETE) Then sPermissions = sPermissions + "+Delete"
If (iPermissions AND ACCESS_ATRIB) Then sPermissions = sPermissions + "+Attr"
If (iPermissions AND ACCESS_PERM) Then sPermissions = sPermissions + "+Security"
If sPermissions.Length > 1 Then sPermissions = sPermissions.Remove(0,1)
output(i) = serverName + "," + fi3.fi3_id.ToString() + "," + fi3.fi3_pathname + "," + _
fi3.fi3_username + "," + fi3.fi3_num_locks.ToString() + "," + sPermissions
Next
Else
Output = Nothing
End If
Call NetApiBufferFree(ptr) ' Free the memory
return output
End Function
end class
'@
$cr = $provider.CompileAssemblyFromSource($params, $txtCode)
if ($cr.Errors.Count) {
$codeLines = $txtCode.Split("`n");
foreach ($ce in $cr.Errors)
{
write-output -i "Error: $($codeLines[$($ce.Line - 1)])"
write-output -i $ce
#$ce write-output
}
Throw "INVALID DATA: Errors encountered while compiling code"
}
$mAssembly = $cr.CompiledAssembly
$instance = $mAssembly.CreateInstance("EnumFiles")
#write-output "Enumerating open files from $server"
$result = $instance.main($server) # Call the VB.Net entry point
write-output -i $result
-
References:
IADsResource Property Methods
http://msdn.microsoft.com/en-us/library/aa706125(VS.85).aspx
IADsResource Interface
http://msdn.microsoft.com/en-us/library/aa706124(VS.85).aspx
List Open Sessions and Open Files
http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0216.mspx
Wayne's World of IT (WWoIT)