深入探索WSH技术:从脚本操作到远程执行
1. 脚本基础操作
在脚本编程中,有一些常见的操作,比如创建ZIP文件和终止脚本执行。以下是实现这些功能的代码示例:
Function CreateZipFile()
'Create the new ZIP file
'WINZIP32 Command Syntax:
'WINZIP32 [-min] action [options] filename[.zip] files
' -min - Tells WinZip to run minimized
' action – Represents any one of the following arguments
' -a Create new ZIP file
' -f Refresh existing archive
' -u Update an existing archive
' -m Move archive to specified location
' options - Optional arguments that include
' -r Add files and folders when adding to ZIP file
' -p Include information about any added folders
' filename[.zip] – name of ZIP file to be created
' files – names of file to be added to the ZIP file
objWshShl.Run _
"WINZIP32 -a C:\Temp\VBScripts.zip D:\VBScriptGames\*.vbs", 0, True
End Function
Function TerminateScriptExecution()
'Terminate the script’s execution
WScript.Quit()
End Function
上述代码中,
CreateZipFile
函数用于创建一个新的ZIP文件,它使用
WINZIP32
命令,将
D:\VBScriptGames\
目录下所有的
.vbs
文件压缩到
C:\Temp\VBScripts.zip
中。
TerminateScriptExecution
函数则用于终止脚本的执行。
2. HTML应用程序(HTAs)
HTAs可以为脚本提供图形用户界面(GUI),使脚本的使用更加方便,即使是非技术人员也能轻松操作。下面介绍两个HTA的示例。
2.1 为WSH ping脚本添加GUI
以下是一个将
ping
命令封装在GUI中的HTA示例:
<head>
<title>HTA Ping Application</title>
<HTA:APPLICATION ID="htaPingApp"
APPLICATIONNAME="HTA Ping"
BORDER="thin"
BORDERSTYLE="normal"
SINGLEINSTANCE="yes">
<style>
body {
background-color:#AAAAAA;
font:16px “Arial”
}
span {
color:red;
font-weight:bold
}
</style>
<script type="text/vbscript">
Sub Window_OnLoad
self.resizeTo 750, 240
End Sub
Sub submitButton_onClick
textOutput.innerHTML = ""
self.resizeTo 750, 680
strTempFile = "C:\Temp\PingFile.txt"
Set WshFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("Wscript.Shell")
WshShell.Run "cmd.exe /c ping.exe " & textField.value & " > " & _
strTempFile, 0, True
Set objTextFile = WshFSO.OpenTextFile(strTempFile, 1)
Do While objTextFile.AtEndOfStream <> True
strOutput = strOutput & objTextFile.ReadLine & "<br>"
Loop
textOutput.innerHTML = strOutput
objTextFile.Close
End Sub
</script>
</head>
<body>
<p>IP Address/Hostname: <input type="text" name="textField" size="50">
<input type="button" name="submitButton" value="Initiate Ping"></p>
<div id="textOutput">Please be patient when waiting for results. The
ping command can take a while to execute. </div>
</body>
</html>
这个HTA的操作步骤如下:
1. 打开HTA应用程序,会看到一个输入框和一个按钮。
2. 在输入框中输入要ping的IP地址或主机名。
3. 点击 “Initiate Ping” 按钮,程序会执行
ping
命令,并将结果显示在下方的区域。
2.2 自动化Windows关机
以下是一个自动化Windows关机的HTA示例:
<html>
<title>SHUTDOWN IN PROGRESS</title>
<HTA:APPLICATION
ID="htaShutdownApp"
APPLICATIONNAME="Shutdown Demo"
SCROLL="auto"
SINGLEINSTANCE="yes">
<head>
<style>
body {
font-family: Arial;
text-align: center;
}
#msgTitle {
margin: 12px 0 0;
}
#msgCountdown {
color: #FF00FF;
}
</style>
<script type="text/vbscript">
Sub Window_OnLoad
self.resizeTo 700, 300
End Sub
Sub SystemShutdown
Set objSystemSet = GetObject _
("winmgmts:{impersonationLevel=impersonate, (Shutdown )}")_
.InstancesOf("Win32_OperatingSystem")
For Each objSystem In objSystemSet
objSystem.Win32Shutdown 5
Next
End Sub
Sub StopCountdown
Set WshShell = CreateObject("WScript.Shell")
Window.Close
End Sub
</script>
</head>
<body>
<h1 id="msgTitle">Automated System Shutdown</h1>
<p id="msgText">A shutdown of this system has been initiated.
Click on Cancel to override.</p>
<div id="msgCountdown"></div>
<p>
<input type="button" value="Cancel" name="btnCancel"
onclick="StopCountdown">
</p>
<script type="text/vbscript">
noOfIterations = 60
SixtySecondCountdown()
Sub SixtySecondCountdown
timerProcess = _
window.setTimeout("SixtySecondCountdown", 1000, "VBScript")
noOfIterations = noOfIterations - 1
document.getElementById("msgCountdown").innerHTML = noOfIterations
If noOfIterations = 0 Then
window.clearTimeout(timerProcess)
SystemShutdown()
End If
End Sub
</script>
</body>
</html>
这个HTA的操作步骤如下:
1. 打开HTA应用程序,会看到一个提示框,显示系统即将关机,并开始60秒的倒计时。
2. 如果不想关机,可以点击 “Cancel” 按钮,终止关机操作。
3. 如果不进行干预,倒计时结束后,系统将自动关机。
3. 远程WSH技术
Remote WSH是一项在WSH 5.6中引入的新技术,它允许在网络上远程启动和监控脚本的执行。
3.1 使用Remote WSH的要求
要使用Remote WSH,需要满足以下条件:
- 本地计算机必须运行WSH 5.6或更高版本。
- 远程计算机必须运行WSH 5.6或更高版本。
- 本地和远程计算机都必须运行Windows 2000、XP、2003、Vista、2008、2012、7或8。
- 必须在远程计算机上具有管理员权限。
3.2 启用Remote WSH
要在计算机上启用Remote WSH,需要进行以下操作:
1. 在注册表
HKCU\Software\Microsoft\Windows Script Host\Settings\
中添加一个名为
Remote
的新值,并将其设置为
1
。
2. 在远程Windows计算机上执行
WScript –regserver
命令,将
WScript.exe
执行主机注册为远程COM服务器。
3.3 Remote WSH的架构
Remote WSH由三个对象组成,它们分别支持各种方法、属性和事件。以下是这些对象的关系图:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(WshController):::process --> B(WshRemote):::process
B --> C(WshRemoteError):::process
-
WshController对象是最高级的对象,用于创建WshRemote对象。 -
WshRemote对象用于远程执行脚本和终止脚本的执行。 -
WshRemoteError对象用于获取远程脚本执行时的错误信息。
3.4 执行Remote WSH方法
以下是一个远程执行脚本的示例:
Set WshControl = CreateObject("WshController")
Set RemoteScript = WshControl.CreateScript("Test.vbs", "\\DSKTP001")
RemoteScript.Execute
上述代码中,首先创建了一个
WshController
对象,然后使用
CreateScript
方法创建了一个
WshRemote
对象,并指定要执行的脚本和远程计算机的名称。最后,使用
Execute
方法启动远程脚本的执行。
如果要终止远程脚本的执行,可以使用
Terminate
方法:
RemoteScript.Terminate
3.5 响应WSH远程事件
远程执行的脚本会产生三种不同的事件:
| 事件 | 描述 |
| ---- | ---- |
| Start | 远程脚本开始执行时触发 |
| End | 远程脚本停止执行时触发 |
| Error | 远程脚本发生错误时触发 |
要捕获这些事件,可以使用
WScript
对象的
ConnectObject
方法:
WScript.ConnectObject RemoteScript, "RemoteScript_"
Function RemoteScript_Start()
'Add statements here to process the start event.
End Function
上述代码中,使用
ConnectObject
方法将
RemoteScript
对象的事件连接到以
RemoteScript_
为前缀的子程序或函数。然后,创建了一个
RemoteScript_Start
函数,用于处理远程脚本开始执行的事件。
3.6 访问WSH远程属性
如果远程脚本执行时发生错误,可以使用
WshRemote
对象的
Error
属性访问
WshRemoteError
对象,从而获取详细的错误信息。以下是
WshRemoteError
对象的属性列表:
| 属性 | 描述 |
| ---- | ---- |
| Description | 错误的描述 |
| Number | 错误的数字代码 |
| Line | 错误发生的行号 |
| Source | 报告错误的对象 |
| SourceText | 产生错误的代码行 |
| Character | 代码行中错误发生的字符位置 |
此外,
WshRemote
对象还有一个
Status
属性,用于跟踪远程脚本的执行状态:
| 值 | 描述 |
| ---- | ---- |
| 0 | 远程脚本尚未开始执行 |
| 1 | 远程脚本正在执行 |
| 2 | 远程脚本已执行完毕 |
3.7 远程WSH示例
以下是一个完整的远程执行脚本的示例:
'*************************************************************************
'Script Name: WSHRemoteDemo.vbs
'Author: Jerry Ford
'Created: 03/14/14
'Description: This script controls the remote execute of a VBScript named
' Test.vbs on a computer named DSKTP001.
'*************************************************************************
'Initialization Section
Option Explicit
Set wshController = CreateObject("WshController")
Set wshRemote = wshController.CreateScript("Test.vbs", "\\DSKTP001")
'Main Processing Section
WScript.ConnectObject wshRemote, "RemoteScript_"
wshRemote.Execute
Do Until wshRemote.Status = 2
WScript.Sleep 1000
Loop
'Procedure Section
Sub RemoteScript_Start()
MsgBox "Test.vbs has started!"
End Sub
Sub RemoteScript_End()
MsgBox "Test.vbs has terminated!"
End Sub
这个脚本的执行步骤如下:
1. 创建
WshController
对象和
WshRemote
对象,并将
Test.vbs
脚本复制到远程计算机
DSKTP001
上。
2. 使用
ConnectObject
方法定义事件前缀,以便捕获远程脚本执行时的事件。
3. 使用
Execute
方法启动远程脚本的执行。
4. 进入一个循环,每隔1秒检查一次
WshRemote
对象的
Status
属性,直到脚本执行完毕。
5. 定义两个子程序
RemoteScript_Start
和
RemoteScript_End
,分别处理远程脚本开始和结束执行的事件。
4. WSH核心对象模型
WSH核心对象模型提供了对Windows资源的编程访问,它包含14个对象,每个对象都提供了对特定类别的Windows资源的访问。
4.1 WSH核心对象的层次结构
在WSH核心对象模型的顶层是
WScript
对象,它是WSH的根对象,所有其他对象都从这个对象实例化而来。
WScript
对象在执行主机启动时自动建立,因此可以在脚本中直接引用,无需先进行实例化。除了
WScript
对象外,还有
WshController
、
WshShell
和
WshNetwork
这三个公共对象,它们需要使用
WScript
对象的
CreateObject()
方法进行实例化。其他对象则需要通过与
WScript
、
WshController
、
WshShell
和
WshNetwork
对象相关的属性或方法来实例化。以下是这些对象及其实例化方法的列表:
| 对象 | 实例化方法 |
| ---- | ---- |
| WshArguments | WScript.Arguments |
| WshNamed | WScript.Arguments.Named |
| WshUnnamed | WScript.Arguments.Unnamed |
| WshRemote | WshController.CreateScript() |
| WshRemoteError | WshRemote.Error |
| WshShortcut | WshShell.CreateShortcut() |
| WshUrlShortcut | WshShell.CreateShortcut() |
| WshEnvironment | WshShell.Environment |
| WshSpecialFolders | WshShell.SpecialFolders |
| WshScriptExec | WshShell.Exec() |
4.2 WSH核心对象的属性和方法
每个WSH核心对象都提供了对特定Windows功能子集的访问,以下是这些对象的详细描述、属性和方法列表:
| 对象 | 描述 | 属性 | 方法 |
| ---- | ---- | ---- | ---- |
| WScript | 这是WSH的根对象,提供对许多有用属性和方法的访问,也提供对WSH核心对象模型中其他对象的访问 | Arguments, FullName, Interactive, Name, Path, ScriptFullName, ScriptName, StdErr, StdIn, StdOut, Version | ConnectObject(), CreateObject(), DisconnectObject(), Echo(), GetObject(), Quit(), Sleep() |
| WshArguments | 该对象允许访问脚本执行时传递的命令行参数 | Count, Item, Length, Named, Unnamed | Count(), ShowUsage() |
| WshNamed | 该对象提供对一组命名命令行参数的访问 | Item, Length | Count(), Exists() |
| WshUnnamed | 该对象提供对一组未命名命令行参数的访问 | Item, Length | Count() |
| WshController | 该对象提供创建远程脚本进程的能力 | None | CreateScript() |
| WshRemote | 该对象提供通过网络使用脚本管理远程计算机系统的能力 | Status, Error | Execute(), Terminate() |
| WshRemoteError | 该对象提供对远程脚本产生的错误信息的访问 | Description, Line, Character, SourceText, Source, Number | None |
| WshNetwork | 该对象提供对许多不同网络资源(如网络打印机和驱动器)的访问 | ComputerName, UserDomain, UserName | AddWindowsPrinterConnection(), AddPrinterConnection(), EnumNetworkDrives(), EnumPrinterConnection(), MapNetworkDrive(), RemoveNetworkDrive(), RemovePrinterConnection(), SetDefaultPrinter() |
| WshShell | 该对象提供对Windows注册表、事件日志、环境变量、快捷方式和应用程序的访问 | CurrentDirectory, Environment, SpecialFolders | AppActivate(), CreateShortcut(), ExpandEnvironmentStrings(), LogEvent(), Popup(), RegDelete(), RegRead(), RegWrite(), Run(), SendKeys(), Exec() |
| WshShortcut | 该对象为脚本提供创建和操作Windows快捷方式的方法和属性 | Arguments, Description, FullName, HotKey, IconLocation, TargetPath, WindowStyle, WorkingDirectory | Save() |
| WshUrlShortcut | 该对象为脚本提供创建和操作URL快捷方式的方法和属性 | FullName, TargetPath | Save() |
| WshEnvironment | 该对象提供对Windows环境变量的访问 | Item, Length | Remove(), Count() |
| WshSpecialFolders | 该对象提供对特殊Windows文件夹(如开始菜单和桌面文件夹)的访问 | Item | Count() |
| WshScriptExec | 该对象提供对使用Exec方法运行的脚本的错误信息的访问 | Status, StdOut, StdIn, StdErr | Terminate() |
4.3 检查对象属性
通过访问对象属性,脚本在执行时可以收集各种信息。例如,使用
WshNetwork
对象的属性,脚本可以收集运行脚本的用户所登录的Windows域、计算机名称和用户名等信息。这些信息可以用于防止脚本在某些域或计算机上执行。以下是一些常见的WSH对象属性及其描述:
| 属性 | 描述 |
| ---- | ---- |
| Arguments | 设置指向
WshArguments
集合的指针引用 |
| AtEndOfLine | 根据流中是否到达行尾标记返回
true
或
false
|
| AtEndOfStream | 根据输入流是否到达末尾返回
true
或
false
|
| Character | 标识代码行中发生错误的特定字符 |
| Column | 返回输入流中的当前列位置 |
| ComputerName | 获取计算机的名称 |
| CurrentDirectory | 设置或获取脚本的当前工作目录 |
| Description | 获取指定快捷方式的描述 |
| Environment | 设置指向
WshEnvironment
的指针引用 |
| Error | 提供访问
WshRemoteError
对象的能力 |
| ExitCode | 返回使用
Exec()
启动的脚本的退出代码 |
| FullName | 获取快捷方式或可执行程序的路径 |
| HotKey | 获取指定快捷方式关联的热键 |
| IconLocation | 获取图标的位置 |
| Interactive | 提供以编程方式设置脚本模式的能力 |
| Item | 从集合中检索指定的项或提供对
WshNamed
对象中存储的项的访问 |
| Length | 获取枚举项的计数 |
| Line | 返回输入流中当前行的行号或标识脚本中发生错误的行号 |
| Name | 返回表示
WScript
对象名称的字符串 |
| Number | 提供访问错误编号的能力 |
| Path | 返回
CScript.exe
或
WScript.exe
执行主机所在文件夹的位置 |
| ProcessID | 获取使用
WshScriptExec
对象启动的进程的进程ID(PID) |
| ScriptFullName | 返回正在执行的脚本的路径 |
| ScriptName | 返回正在执行的脚本的名称 |
| Source | 获取导致脚本错误的对象的标识 |
| SourceText | 获取产生错误的源代码 |
| SpecialFolders | 提供对Windows开始菜单和桌面文件夹的访问 |
| Status | 提供有关远程执行的脚本或使用
Exec()
启动的脚本的状态信息 |
| StdErr | 使脚本能够写入错误输出流或提供对
Exec
对象的只读错误输出的访问 |
| StdIn | 提供对输入流的读取访问或提供对
Exec
对象的只写输入流的访问 |
| StdOut | 提供对输出流的写入访问或提供对
Exec
对象的只写输出流的访问 |
| TargetPath | 获取快捷方式关联对象的路径 |
| UserDomain | 获取域名 |
| UserName | 获取当前登录用户的名称 |
| Version | 获取WSH版本号 |
| WindowStyle | 获取快捷方式的窗口样式 |
| WorkingDirectory | 返回与指定快捷方式关联的工作目录 |
以下是一个访问
WshNetwork
对象属性的示例脚本:
Set WshNtwk = WScript.CreateObject("WScript.Network")
PropertyInfo = "User Domain" & vbTab & "= " & WshNtwk.UserDomain & _
vbCrLf & "Computer Name" & vbTab & "= " & WshNtwk.ComputerName & _
vbCrLf & "User Name" & vbTab & "= " & WshNtwk.UserName & vbCrLf
MsgBox PropertyInfo, vbOkOnly , "WshNtwk Properties Example"
这个脚本首先创建了一个
WshNetwork
对象的实例,然后将该对象的
UserDomain
、
ComputerName
和
UserName
属性的值组合成一个字符串,并使用
MsgBox
函数显示在一个弹出对话框中。
4.4 检查对象方法
WSH还提供了大量的对象方法,通过在VBScript中使用这些方法,可以操作与对象关联的Windows资源。例如,使用
WshShell
对象的
RegRead()
、
RegWrite()
和
RegDelete()
方法,可以创建访问和操作Windows注册表内容的脚本。以下是一些常见的WSH对象方法及其描述:
| 方法 | 描述 |
| ---- | ---- |
| AddPrinterConnection() | 创建打印机映射 |
| AddWindowsPrinterConnection() | 创建新的打印机连接 |
| AppActivate() | 激活目标应用程序窗口 |
| Close() | 终止或结束打开的数据流 |
| ConnectObject() | 建立与对象的连接 |
| Count | 获取
WshNamed
和
WshUnnamed
对象中找到的开关数量 |
| CreateObject() | 创建对象的新实例 |
| CreateScript() | 实例化一个表示远程运行脚本的
WshRemote
对象 |
| CreateShortcut() | 创建Windows快捷方式 |
| DisconnectObject() | 终止与对象的连接 |
| Echo() | 显示文本消息 |
| EnumNetworkDrives() | 允许访问网络驱动器 |
| EnumPrinterConnections() | 允许访问网络打印机 |
| Exec() | 在子命令shell中执行应用程序并提供对环境变量的访问 |
| Execute() | 启动远程脚本对象的执行 |
| Exists() | 确定指定的键是否存在于
WshNamed
对象中 |
| ExpandEnvironmentStrings() | 获取表示
Process
环境变量内容的字符串 |
| GetObject() | 获取自动化对象 |
| GetResource() | 获取由
<resource>
标签指定的资源的值 |
| LogEvent() | 在Windows事件日志中写入消息 |
| MapNetworkDrive() | 创建网络驱动器映射 |
| Popup() | 在弹出对话框中显示文本消息 |
| Quit() | 终止脚本的执行 |
| Read() | 从输入流中检索一串字符 |
| ReadAll() | 检索由输入流中的字符组成的字符串 |
| ReadLine() | 从输入流中检索包含整行数据的字符串 |
| RegDelete() | 删除注册表键或值 |
| RegRead() | 检索注册表键或值 |
| RegWrite() | 创建注册表键或值 |
| Remove() | 删除指定的环境变量 |
| RemoveNetworkDrive() | 删除与指定网络驱动器的连接 |
| RemovePrinterConnection() | 删除与指定网络打印机的连接 |
| Run() | 启动新进程 |
| Save() | 保存快捷方式 |
| SendKeys() | 模拟按键并将输入的数据发送到指定窗口 |
| SetDefaultPrinter() | 建立默认的Windows打印机 |
| ShowUsage() | 获取有关脚本应该如何执行的信息 |
| Skip() | 从输入流中读取时跳过
x
个字符 |
| SkipLine() | 从输入流中读取时跳过整行 |
| Sleep() | 暂停脚本执行
x
秒 |
| Terminate() | 停止由
Exec()
启动的进程 |
| Write() | 将字符串放入输出流中 |
| WriteBlankLines() | 在输出流中放置空白行 |
| WriteLine() | 将字符串放入输出流中 |
以下是一个使用
WshShell
对象的
LogEvent()
方法向Windows事件日志写入消息的示例脚本:
Set WshShl = WScript.CreateObject("WScript.Shell")
WshShl.LogEvent 0, "EventLogger.vbs - Beginning script execution."
这个脚本首先创建了一个
WshShell
对象的实例,然后使用
LogEvent()
方法向事件日志写入一条消息。要查看写入的消息,可以在Windows 8.1中点击开始按钮,输入 “View Event Logs” 并按回车键,然后点击 “View Event Logs” 打开事件查看器控制台。在事件查看器中,展开 “Windows Logs” 节点并点击 “Application” 日志,即可查看应用程序事件日志中的事件。
总结
通过本文的介绍,我们了解了脚本编程中的一些基础操作,如创建ZIP文件和终止脚本执行。同时,还学习了如何使用HTML应用程序(HTAs)为脚本添加图形用户界面,使脚本的使用更加方便。此外,我们深入探讨了远程WSH技术,包括其使用要求、启用方法、架构、执行方法、事件响应和属性访问等方面。最后,我们详细介绍了WSH核心对象模型,包括对象的层次结构、属性和方法,以及如何通过访问对象属性和方法来操作Windows资源。这些知识将有助于我们更好地进行Windows脚本编程,提高工作效率。
超级会员免费看
9191

被折叠的 条评论
为什么被折叠?



