WSH(WScript.Shell)技术 - taito的专栏 - CSDNBlog

来源:百度文库 编辑:神马文学网 时间:2024/05/03 12:04:40
1.概述
虽说不是只有NT5才有WSH,但NT5(WINDOWS2000)一定有WSH的。实际上,你在WIN98+PWS里,或者NT4+IIS4里,你就能找到
WSH。
WSH是微软脚本技术系列中的一种,简单讲,就是提供了一种脚本环境,在这个环境中,预定义了一些对象,同时也可以使用
COM里的其他对象。他使用一种脚本引擎来对脚本解释执行,微软自己支持VBscript和Jscript,第三方也可以开发自己的脚本引
擎。
具体点,就是你先编好一些脚本文件(微软自带例子若干,后缀.vbs或 .js),然后用一个程序对他解释执行,这个程序就叫
Windows scripting Host,程序的名字是Wscript.exe(或者命令行的Cscript.exe),你可以查看一下你的机器里有没有这两个
文件,就知道有没有WSH了。这非常像批处理文件,只不过文件里不是命令行,而是脚本语言写的脚本。同时,他完成的功能也非常
像批处理文件,只不过多了些控制。
我主要用WSH来完成一些繁琐的、通常需要我反复操作才能完成的任务,比如给大量目录设置ACL,或者创建大量的目录等等。
虽然这也可以编写VB或VC程序来实现,不过比起脚本来,实在麻烦,至少需要那么大的环境,而脚本只要一个写字板就成。用WSH
技术来配置服务器,包括创建用户,创建邮箱,创建目录,创建站点,设置ACL,设置FrontPage ServerExtention,我将在WSH实
用讲座中分几讲详细介绍。
2.组成
WSH自带的几个内置对象包括:
1.由 Wscript.exe 提供的对象
Wscript 作为 Wscript 公开给脚本引擎。
WshArguments 未公开;通过 Wscript.Arguments 属性访问。
2.由 WSHom.Ocx 提供的对象。
WshShell 自动对象。
ProgID 是 Wscript.WshShell。
WshNetwork 自动对象。ProgID 是 Wscript.WshNetwork。
WshShortcut 未公开;通过 WshShell.CreateShortcut 方法访问。
WshUrlShortcut 未公开;通过 WshShell.CreateShortcut 方法访问。
WshCollection 未公开;通过 WshNetwork.EnumNetworkDrives 或 WshNetwork.EnumPrinterConnection 方法访问。
WshEnvironment 未公开;通过 WshShell.Environment 属性访问。
WshSpecialFolders 未公开;通过 WshShell.Folder 属性访问。
他们主要可以完成环境变量的获取,网络登陆,驱动器映射,快截方式创建,程序加载,特殊文件夹(如系统文件夹)信息获
取等功能。
如果你的系统里支持ADO等COM部件,你同样可以使用。
3.示例
下面这个例子演示打开写字板查看文本文件,同时创建一个文本文件并写入一段话,你可以把他拷贝到写字板中,然后以.vbs
为后缀存盘,之后双击他,
‘test.vbs
Set WshShell = Wscript.CreateObject("Wscript.Shell")
WshShell.Run ("notepad " & Wscript.scriptFullName)
‘上面用SHELL对象启动程序
Set fs = Wscript.CreateObject("scripting.FileSystemObject")
Set a = fs.CreateTextFile("c:\testfile.txt", True)
a.WriteLine("这是一个测试。")
a.Close
‘用COM对象scripting.FileSystemObject操作文本文件
4.哪里找到学习材料
在PWS和IIS4的产品文档里有非常齐全的WSH文档,建议大家先学习学习,了解了解WSH的基础知识。
原文请到WSH(WHITE的小家)(http://wwwasp.yeah.net )
其实就是读注册表,不过如果能获得机器的IP配置等信息,以后配置IIS时就简单了。下面的脚本读出机器的所有可用IP地
址,子网掩码,却省网关等信息:
代码:
--------------------------------------------------------------------------------
Option Explicit Dim WSHShell Dim sNic, sMan Dim Gateway Dim IPAddress Dim SubnetMask Dim i Dim
sTcpipRegKey Dim bIsDHCP Set WSHShell = CreateObject("Wscript.Shell") sNic = WSHShell.RegRead
("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\1\ServiceName") If sTcpipRegKey
<> "Microsoft" And Err.Number = 0 Then   sTcpipRegKey = "HKLM\SYSTEM\CurrentControlSet\Services\" & sNic
& "\Parameters\Tcpip\"   bIsDHCP = WSHShell.RegRead(sTcpipRegKey & "EnableDHCP")   If bIsDHCP Then
Gateway = WSHShell.RegRead(sTcpipRegKey & "DhcpDefaultGateway")     IPAddress = WSHShell.RegRead
(sTcpipRegKey & "DhcpIPAddress")     SubnetMask = WSHShell.RegRead(sTcpipRegKey & "DhcpSubnetMask")
MsgBox ("DefaultGateway: " & Gateway(0) & Chr(10) & Chr(13) & "IPAddress: " & IPAddress & Chr(10) &
Chr(13) & "SubnetMask: " & SubnetMask)   Else     Gateway = WSHShell.RegRead(sTcpipRegKey
& "DefaultGateway")     IPAddress = WSHShell.RegRead(sTcpipRegKey & "IPAddress")     SubnetMask =
WSHShell.RegRead(sTcpipRegKey & "SubnetMask")     For i=0 to Ubound(IPAddress)-1       MsgBox
("DefaultGateway: " & Gateway(0) & Chr(10) & Chr(13) & "IPAddress: " & IPAddress(i) & Chr(10) & Chr(13)
& "SubnetMask: " & SubnetMask(i))     Next   End If End If
--------------------------------------------------------------------------------
说明:机器的网络配置保存在注册表里,网卡项目下面,所以首先必须知道网卡的名字。然后取注册表数据,IP地址和子网掩
码都是数组形式(其实注册表里保存的是二进制数据,VBscript帮我们转换了)。在WSH里读注册表非常的简单,具体请看上面的
程序。
第二讲 创建用户、目录和站点
--------------------------------------------------------------------------------
本讲将使用到ADSI,即活动目录服务接口.可以到15Seconds.com找到一些相关的资料.
1.创建用户
下面这段代码在独立服务器white上创建用户user1,初始口令user1,用到了ADSI.
代码:
--------------------------------------------------------------------------------
Dim Username,UserPass  Dim oDomain,oUser  Username = "user1"  UserPass = "user1"  Set oDomain =
GetObject("WinNT://white")  Set oUser = oDomain.Create ("user", UserName)  If (err.number = 0) Then
oUser.SetInfo    oUser.SetPassword UserPass    oUser.SetInfo  Else    Wscript.Echo "创建用
户" & UserName & "出错!"  End If  Set oUser = Nothing  Set oDomain = Nothing
--------------------------------------------------------------------------------
2.创建目录
使用FileSystemObject创建目录:
代码:
--------------------------------------------------------------------------------
Dim FsObject  Dim tmpFolder  Set FsObject = Wscript.CreateObject("scripting.FileSystemObject")
tmpFolder = "D:\userdate\user1"  If Not FsObject.FolderExists(tmpFolder) Then
FsObject.CreateFolder(tmpFolder)    If Err.Number<>0 Then      Wscript.Echo "创建目录" & tmpFolder
& "失败!"    End If  End If
--------------------------------------------------------------------------------
注意在创建目录前,先检查了目录是否存在,如果存在,则不用创建了.
3.创建站点
下面这个子程序负责创建一个WWW站点,各个参数的意义为:站点IP地址,站点根目录,站点说明,主机名,端口号,计算机名(一搬
为LOCALHOST),是否立即启动,匿名访问时所使用的帐号,匿名访问时所用帐号的口令,LOG文件的目录.
函数返回所建站点在IIS中的序号(在IIS中,所有站点依次编号,第一个为1).
一个调用示例:
代码:
--------------------------------------------------------------------------------
siteid =
ASTCreateWebSite"10.1.3.122","d:\userdata\user1","www_user1","","80","LocalHost",True,"IUSR_user1","8iui%
#","D:\Logfiles")Function ASTCreateWebSite(IPAddress, RootDirectory, ServerComment, HostName, PortNum,
Computer, Start,AnonymousUserName,AnonymousUserPass,LogFileDirectory)  Dim w3svc, WebServer,
NewWebServer, NewDir  Dim Bindings, BindingString, NewBindings, Index, SiteObj, bDone    On Error
Resume Next    Err.Clear    Set w3svc = GetObject("IIS://" & Computer & "/w3svc")    If
Err.Number <> 0 Then      Wscript.Echo "无法打开: "&"IIS://" & Computer & "/w3svc" & VbCrlf & "程序将退
出."      Wscript.Quit (1)    End If    BindingString = IpAddress & ":" & PortNum & ":" &
HostName    For Each WebServer in w3svc      If WebServer.Class = "IIsWebServer" Then
Bindings = WebServer.ServerBindings        If BindingString = Bindings(0) Then
Wscript.Echo "IP地址冲突:" & IpAddress & ",请检测IP地址!." & VbCrlf & "取消创建本站点。"
Exit Function        End If      End If    Next    Index = 1    bDone = False
While (Not bDone)      Err.Clear      Set SiteObj = GetObject("IIS://"&Computer&"/w3svc/" &
Index)      If (Err.Number = 0) Then        Index = Index + 1      Else
Err.Clear        Set NewWebServer = w3svc.Create("IIsWebServer", Index)        If
(Err.Number <> 0) Then          Index = Index + 1        Else          Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/w3svc/" & Index)          If
(Err.Number = 0) Then            bDone = True          Else            Index
= Index + 1          End If        End If      End If      If (Index > 10000)
Then        Wscript.Echo "看起来不能创建站点,正在创建的站点的序号为: "&Index&"." & VbCrlf & "取消创建
本站点。"        Exit Function      End If    Wend    NewBindings = Array(0)
NewBindings(0) = BindingString    NewWebServer.ServerBindings = NewBindings
NewWebServer.ServerComment = ServerComment    NewWebServer.AnonymousUserName = AnonymousUserName
NewWebServer.AnonymousUserPass = AnonymousUserPass    NewWebServer.KeyType = "IIsWebServer"
NewWebServer.FrontPageWeb = True    NewWebServer.EnableDefaultDoc = True    NewWebServer.DefaultDoc
= "Default.htm, Default.asp, Index.htm, Index.asp"    NewWebServer.LogFileDirectory = LogFileDirectory
NewWebServer.SetInfo    Set NewDir = NewWebServer.Create("IIsWebVirtualDir", "ROOT")
NewDir.Path = RootDirectory    NewDir.AccessRead = true    NewDir.AppFriendlyName = "应用程序" &
ServerComment    NewDir.AppCreate True    NewDir.Accessscript = True    Err.Clear
NewDir.SetInfo    If (Err.Number = 0) Then    Else      Wscript.Echo "主目录创建时出错."
End If      If Start = True Then      Err.Clear      Set NewWebServer = GetObject("IIS://"
& Computer & "/w3svc/" & Index)      NewWebServer.Start      If Err.Number <> 0 Then
Wscript.Echo "启动站点时出错!"        Err.Clear      Else      End If    End If
ASTCreateWebSite = IndexEnd Function  下面函数创建FTP站点:Function ASTCreateFtpSite(IPAddress,
RootDirectory, ServerComment, HostName, PortNum, Computer, Start,LogFileDirectory)  Dim MSFTPSVC,
FtpServer, NewFtpServer, NewDir  Dim Bindings, BindingString, NewBindings, Index, SiteObj, bDone
On Error Resume Next    Err.Clear    Set MSFTPSVC = GetObject("IIS://" & Computer & "/MSFTPSVC")
If Err.Number <> 0 Then      Wscript.Echo "无法打开: "&"IIS://" & Computer & "/MSFTPSVC" & VbCrlf
& "程序将退出."      Wscript.Quit (1)    End If    BindingString = IpAddress & ":" & PortNum
& ":" & HostName    For Each FtpServer in MSFTPSVC      If FtpServer.Class="IIsFtpServer" Then
Bindings = FtpServer.ServerBindings      If BindingString = Bindings(0) Then
Wscript.Echo "IP地址冲突:" & IpAddress & ",请检测IP地址!." & VbCrlf & "取消创建本站点。"        Exit
Function      End If      End If    Next    Index = 1    bDone = False    While
(Not bDone)      Err.Clear      Set SiteObj = GetObject("IIS://"&Computer&"/MSFTPSVC/" & Index)
If (Err.Number = 0) Then        Index = Index + 1      Else        Err.Clear
Set NewFtpServer = MSFTPSVC.Create("IIsFtpServer", Index)        If (Err.Number <>
0) Then          Index = Index + 1        Else          Err.Clear
Set SiteObj = GetObject("IIS://"&Computer&"/MSFTPSVC/" & Index)          If (Err.Number = 0)
Then            bDone = True          Else            Index = Index + 1
End If        End If      End If      If (Index > 10000) Then
Wscript.Echo "看起来不能创建站点,正在创建的站点的序号为: "&Index&"." & VbCrlf & "取消创建本站点。"
Exit Function      End If    Wend    NewBindings = Array(0)    NewBindings(0) =
BindingString    NewFtpServer.ServerBindings = NewBindings    NewFtpServer.ServerComment =
ServerComment    NewFtpServer.AllowAnonymous = False    NewFtpServer.AccessWrite = True
NewFtpServer.AccessRead = True    NewFtpServer.DontLog = False    NewFtpServer.LogFileDirectory =
LogFileDirectory    NewFtpServer.SetInfo    Set NewDir = NewFtpServer.Create
("IIsFtpVirtualDir", "ROOT")    NewDir.Path = RootDirectory    NewDir.AccessRead = true
Err.Clear    NewDir.SetInfo    If (Err.Number = 0) Then    Else      Wscript.Echo "主目录创
建时出错."    End If      If Start = True Then      Err.Clear      Set NewFtpServer =
GetObject("IIS://" & Computer & "/MSFTPSVC/" & Index)      NewFtpServer.Start      If
Err.Number <> 0 Then        Wscript.Echo "启动站点时出错!"        Err.Clear      Else
End If    End If      ASTCreateFtpSite = IndexEnd Function
创建邮箱,情况就复杂了,因为你可能采用不同的电子邮件服务器.有些把邮箱信息放在文本文件里,有些把信息放在注册表
里,有些提供ADSI接口,所以,得根据具体情况来定.
对于用户邮箱信息放在文本文件里的,可以直接操作文本文件,下面是一段写文本文件的代码示例:
Dim fs
Dim fw
Set fs = Wscript.CreateObject("scripting.FileSystemObject")
Set fw = fs.CreateTextFile("c:\users.dat")
fw.WriteLine "user1,user1@abc.com,,,"
对于用户信息放在注册表里的,可以用WSH直接操作注册表,从而完成邮箱的创建.比如IMAIL,他的用户信息就放在
HKEY_localmacine\SoftWare\IPswitch\domain\下的.唯一麻烦的邮箱的初始口令,我们不知道他的加密算法.所以只能先手工
创建一个邮箱,然后采用一个固定的口令,看他加密后是多少,我们的脚本在创建别的邮箱时也使用它.这样的问题是,我们必须
告诉用户,他们必须在今后修改口令,否则是不安全的.
Exchange Server提供ADSI接口,创建邮箱就方便了.而且他的邮箱可以与NT的域用户同步.下面是一段示例代码:
objContainer = GetObject("LDAP://SERVERNAME/o=OrgName/ou=SiteName/cn=Recipients")
objUser = objContainer.Create("Remote-Address", "cn=CustRecip")
objUser.cn = "CustRecip"
objUser.Put "Target-Address", "SMTP:CustRecip@msn.com"
objUser.Put "Internet-Encoding", 1310720objUser.UID = "CustRecip"
objUser.textEncodedORaddress = "c=US;a= ;p=DOIT;o=CDO;s=CustRecip;"
objUser.Mail = "CustRecip@msn.com"
objUser.Put "otherMailbox", "MS:OrgName/SiteName/CustRecip"
objUser.Put "Replication-Sensitivity", 20
objUser.Put "MAPI-Recipient", False
objUser.SetInfo
Wscript.Echo objUser.cn
For i = 1 ToobjUser.PropertyCount
Set vProp = objUser.Next
Wscript.Echo vProp.Name
Next
注:由于我现在没有Exchange Server做实验,所以上面这段代码未曾测试过,如果大家有问题,请到他的原出处寻求解决.
这段脚本,稍加修改,也可以用在ASP中.
即配置目录的ACL,至于该如何配置权限,才能让你的服务器是安全的,那得根据你自己的客观实际了,而且,这也是商业秘
密。我这里只是说明用脚本实现的方法。
有两种方法可以完成这个任务(也许还有其他的方法),一种是采用第三方组件(我经常使用的是NTAccess.Permission,这
是个要MONEY的东东,但是我把系统时间改成1997年4月25日,这样,它就不认为我过期了,等执行完脚本,我再改回1999年4月25
日,呵呵。另外一个是SA的FILEMANAGER,功能强大,但体积也大);另一种是在WSH里调用NT的命令行cacls.exe,它的用法为
(摘自NT的帮助文件):
Cacls
显示或修改文件访问控制表(ACL)。
cacls filename [/t] [/e] [/c] [/g user:perm] [/r user [...]] [
/p user:perm [...]] [/d user [...]]
参数
filename
显示文件或指定文件的访问控制表 ACL 。
/t
在当前目录及所有子目录下改变指定文件的 ACL 。
/e
编辑 ACL,但不替换。
/c
继续更改 ACL,并忽略错误。
/g user:perm
将访问权授予指定用户。Perm 可以是:
r  读取
c  更改(写)
f  完全控制
/r user
撤消指定用户的访问权。
/p user:perm
还原指定用户的访问权。Perm 可以是:
n  无
r   读取
c  更改(写)
f  完全控制
/d user
拒绝指定用户的访问。
可以在一个命令中指定多个文件或用户。
使用NTAccess.Permission的一个例子如下:
Rem ----------------------------
Rem 定义常量
Rem ----------------------------
const ntpNoAccess = 1
const ntpRead = 2
const ntpWrite = 4
const ntpExecute = 8
const ntpDelete = 16
const ntpPermissions= 32
const ntpOwnership = 64
const ntpFileRights = 1
const ntpDirRights = 2
ntpChange = ntpRead + ntpWrite + ntpExecute + ntpDelete
ntpFull = ntpChange + ntpPermissions + ntpOwnership
Rem -----------------------------------------------
Rem 开始设置
Rem -----------------------------------------------
Wscript.Echo "开始设置."
Set ntp = CreateObject("NTAccess.Permissions")
set acl = ntp.File("d:\test", true )
‘ add No Access entries first
acl.Add "Users" , ntpNoAccess, ntpFileRights
acl.Add "Users" , ntpNoAccess, ntpDirRights
‘ now delete any ACE‘s we want to remove
acl.Delete "Everyone", ntpFileRights
acl.Delete "Everyone", ntpDirRights
‘ now add any other new ACE‘s
acl.Add "Administrators", ntpFull, ntpFileRights
acl.Add "Administrators", ntpFull, ntpDirRights
acl.Add "white", ntpChange, ntpFileRights
acl.Add "white", ntpChange, ntpDirRights
‘ finally remember to call save
acl.save
Wscript.Echo "已经完成设置!"
使用cacls的一个例子如下:
Set WshShell = Wscript.CreateObject("Wscript.Shell")
userdir = "d:\userdate"
username = "white"
argu = userdir & " /t /e /p " & username & ":f"
WshShell.Run ("c:\winnt\system32\cacls " & argu)