服务器 频道

实战:实时监控共享文件夹的容量

 【IT168 专稿】一、问题的提出

    在用Windows 2000 Server作为文件服务器的系统平台,采用共享目录的方式为用户提供文件服务时,常有两个问题一直困扰着IT管理员。

    一个是文件服务器总是在扩展存储空间,甚至增加了大容量的SATA磁盘阵列,可是硬盘分区被占满的情况仍旧时有发生,而管理员所能做的只是联系用户做文件整理,删除冗余数据。实际上对于共享给单用户的文件夹便于管理,而对于共享给多用户的文件夹,这种文件存储量的增长趋势就非常难以控制。

    就此问题,管理员都希望有一种能够通过编程的方式检索文件服务器上所有文件共享目录的容量值,显示给所有用户,并且能够做到实时更新或者定时更新。同时在逻辑上设置共享目录配额,对于超出配额的目录提示警告。

    通过这种方式可以使用户能够主动地关注共享目录增长所带来的隐患,并且采取相应措施,例如清理文件等,从而减轻管理员的负担。

    第二个问题就是对于公司中所有的同事都在文件服务器上分配有1000MB的存储空间作为Home Directory,并映射为网络硬盘,便于存储私人数据,并且使用了Quota Entry为每个用户设置了磁盘配额。通过Quota Entry只能让管理员了解到用户使用的存储空间的情况,而且并不直观,对于用户则无法直观地得知当前自己的有效剩余空间。

    针对此问题,管理员希望通过程序建立一种机制能够满足对用户Home Directory容量的监测需求,并以网页报表的形式提供给用户。


二、解决方法

    基于以上两种需求,本文设计了一种用简短的代码,较高的运行效率,降低了系统开销,以一种编程的方式实现对共享目录及Home Directory监测功能。此程序是通过编程模型中的文件系统对象所提供的基于对象的处理文件和文件夹的功能能够高效迅速地获取目录和文件的信息,再使用循环得到所有下一级目录和文件的属性,由此最终得到目标目录的size属性值。

    再建立一种机制可以动态地维护需要监测的所有目录的列表,最好的解决办法就是在创建共享目录的时候尽可能地将共享目录都放在一个或几个共同的父目录或分区中,程序只需检索这些父目录或分区便可动态地维护共享文件夹列表,管理员也只需维护这些父目录或分区的信息即可。

    最后将所创建的应用程序添加到文件服务器的计划任务中,设定运行时间,便可及时地更新信息。而且公司的0I部门可以对共享目录设置逻辑配额值,对于容量超出配额的,提示警告,并且计算公司各部门使用文件服务器的开销。

‘在SQL Server中建立数据表,表的结构实现代码如下:
Sub Main()
If Not App.PrevInstance Then
‘首先更新所有共享目录(Home Directory也属于共享目录)的列表
ly_UpdateFolderList

表一  FolderParents

ColumnName

DataType

Length

Allow Null

Default Value

id

int

4

(no)

 

enabled1

int

4

(yes)

0

parentpath1

text

16

(yes)

 

type

text

16

(yes)

 

表二 FolderSize

ColumnName

DataType

Length

Allow Null

Default Value

id

int

4

(no)

 

enabled1

int

4

(yes)

0

Forced1

int

4

(yes)

0

folderpath1

varchar

50

(yes)

 

type1

text

16

(yes)

 

group1

text

16

(yes)

 

usename1

text

16

(yes)

 

caption1

text

16

(yes)

 

folderbytes1

float

8

(yes)

 

quota1

float

8

(yes)

 

quota2

char

10

(yes)

 

percent1

decimal

9

(yes)

 

duration1

decimal

9

(yes)

 

datetime1

datetime

8

(yes)

 

minihours1

decimal

9

(yes)

1

 

表三  FolderOwner

ColumnName

DataType

Length

Allow Null

Default Value

dept

varchar

50

(yes)

 

logon

varchar

50

(yes)

 

usename

varchar

50

(yes)

 

guid

varchar

50

(yes)

 

 



    然后更新所有共享目录的size值
ly_UpdateFolderSize
End If
End Sub
Sub ly_UpdateFolderList()
On Error Resume Next
Dim lyFSO As New FileSystemObject
Dim obj1 As Object
  
    ‘建立数据连接
Set mycon =New ADODB.Connection
mycon.ConnectionString =“Provider=SQLOLEDB.1;
Password=xxxxx;Persist Security Info=True:User ID =sa;
Initial Catalog=Sizeofhome;DataSource=Tsnj004a”
mycon.Open
Dim rs1 As New ADODB.Recordset
rs1.ActiveConnection=mycon
rs1.Source= “select*from FolderParents”
rs1.LockType=adLockReadOnly
rs1.Open
Do While Not rs1.EOF
If lyFSO.FolderExists(rs1(“parentpath1”))Then
For Each obj1 In lyFSO.GetFolder(rs1(“parentpath1”))
SubFolders
Dim rs2 As New ADODB.Recordset
Dim myobjname As String
myobjname=obi1.Name
Dim mypath As String

    ‘将共享目录的绝对路径赋值给mypath变量
mypath=Trim(UCase(rs1(“parentpath1”)&“\”& myobjname))
rs2.ActiveConnection=mycon
rs2.Source=“select * from FolderSize where folderpath1 =’“+mypath+”’”
rs2.LockType =adLockOptimistic
rs2.Open
If rs2.EOF Then
‘若表FolderSize中没有这个共享目录的记录,则添加一行新的记录
rs2.AddNew
rs2(“folderpath1”)= (UCase(rs1(“parentpath1” )& “\”& myobjname))
‘共享目录的类型值将继承父目录的类型(类型将分为USER或DRIVE)
rs2(“type1”)=rs1(“type”)
‘对于新增加的目录记录,使enabled1开关置1,从而允许对此目录进行容量测量
rs2(“enabled1”)=1
‘对于新增加的目录记录,使forced1开关置1,从而强制对此目录进行容量测量
rs2(“forced1”)=1
‘设逻辑配额为500MB,若需更改也可通过编程方式在web页的维护界面对某个目录单独
‘修改此值
rs2(“quota1”)=500
rs2.Update
End If
rs2.Close:Set rs2 =Nothing
Next
End If
rs1.MoveNext:Loop
rs1.Close:Set rs1=Nothing
End Sub
Sub lyUpdateFolderSize()
On Error Resume Next
Dim dbl As Database
Dim rs1 As Recordset
Dim quota2,folderbytes1 As Double
Dim lyFSO As New FileSystemObject

    ‘建立数据连接
Set mycon2=New ADODB.Connection
mycon2.ConnectionString =“Provider=SQLOLEDB.1;Password=xxxxx;
Persist Security Info=True;User ID=sa;Initial Catalog=Sizeofhome;
Data Source=Tsnj004a”
mycon2.Open
Dim rs3 As New ADODB.Recordset
rs3.ActiveConnection=mycon2
rs3.Source=“select * from FolderSize where enabled1=1 or forced1=1
order by folderpath1”
rs3.LockType=adLockOptimistic
rs3.Open
Do While Not rs3.EOF

    ‘取当前系统时间
datetime1= Now ()
‘以下两种情况的共享目录需要更新:1、赋强制位:2、上次更新到现在的时间大于最
‘小时间段(即一小时,也可根据实际情况定制)
If rs3(“forced1”)=1 Or DateDiff(“h”,rs3(“datetime1”),datetime1)> =
rs3(“minhours1”)Then
‘如果文件夹类型为DRIVE, 则采用文件系统对象的Get-Drive方法进行容量计算
If UCase(rs3(“type1”))=“DRIVE” Then
If lyFSO.DriveExists(rs3(“folderpath1”))Then rs3(“quota1”)=
lyFSO.GetDrive(rs3(“folderpath1”)).TotalSize/(1024^ 2)
rs3(“quota2”)= “MB”
rs3.Update
folderbytes1=lyFSO.GetDrive(rs3(“folderpath1”)).TotalSize -
lyFSO.GetDrive(rs3(“folderpath1”)).FreeSpace
Else
folderbytes1=-1
End If
‘如果文件夹类型为USER,则直接调用GetFolderBytes函数取容量值
Else
folderbytes 1=GetFolderBytes(rs3(“folderpath1”))
End If
If folderbytes1>=0 Then
rs3(“folderbytes1”)=folderbytes1
If rs3(“quota1”)>=0 Then
quota2 = 1
If UCase(rs3(“quota2”))= “KB” Then quota2=1024
If UCase(rs3(“quota2”))= “MB” Thenquota2 =1024^2
If UCase(rs3(“quota2”))= “GB” Thenquota2 =1024^3

    ‘通过逻辑配额计算占用百分率
rs3(“percent1”)=rs3(“folderbytes1”)/(rs3(“quota1”)*quota2)*100
Else
rs3(“percent1”)= -1
End If
rs3(“datetime1”)=datetime1
‘将计算所耗时间以秒为单位存入duration字段
rs3(“duration1”)=DateDiff(“S”,datetime1,Now())
‘强制位置0
rs3(“forced1”)=0
rs3.Update
End If
End If
rs3.MoveNext:Loop
rs3.Close
Set rs3=Nothing
End Sub
Function GetFolderBytes(mypath) As Double
On Error Resume Next
Dim lyFSO As New FileSystemObject
Dim tempValue As Double
Dimobi1 As Object
tempValue = -1
If lyFSO.FolderExists(mypath) Then tempValue=lyFSO.GetFolder(mypath).Size
IftempValue = -1 Then
tempValue =0
‘递归调用GetFolderBytes函数
For Each obj1 In lyFSO.GetFolder(mypath).SubFolders
tempValue=tempValue+GetFolderBytes(obj1.Path)
Next

    ‘计算每一级目录中文件大小的总和
For Each obj1 In lyFSO.GetFolder(mypath).Files
tempValue=tempValue+obj1.Size
Next
End If
Else
tempValue=-1
End If
GetFolderBytes=tempValue
Set lyFSO =Nothing
End Function

    将代码编译为可执行文件,并运行测试,检查SQL数据库中数据是否更新。如果确定无误,就在文件服务器的计划任务中,添加一个相隔若干时间段执行的(或每日定时执行)计划任务即可。读者可以扩展此方法, 另外建立一个基于ASP的Web应用,从而可以使管理员维护数据记录,用户也可通过网页浏览统计结果。
0
相关文章