VBS经典代码大全

发布时间:2020-05-27   来源:文档文库   
字号:
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. VBS代码片断大全[] 1 VBS
取得本机IP strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2" Set IPConfigSet = objWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled=TRUE" For Each IPConfig in IPConfigSet
If Not IsNull(IPConfig.IPAddress Then For Each strAddress in IPConfig.IPAddress WScript.Echo strAddress Next End If Next

-------------------------------------------------------------------------------- 2 取得本机计算机名 strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2"
Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem"

For Each objComputer in colComputers Wscript.Echo objComputer.Name Next

-------------------------------------------------------------------------------- 4 检查升级包 strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2" Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem"
For Each objOperatingSystem in colOperatingSystems
Wscript.Echo objOperatingSystem.ServicePackMajorVersion & "." & objOperatingSystem.ServicePackMinorVersion Next

-------------------------------------------------------------------------------- 5 检查 Hot Fix strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2" Set colQuickFixes = objWMIService.ExecQuery ("Select * from Win32_QuickFixEngineering"
For Each objQuickFix in colQuickFixes
Wscript.Echo "Description: " & objQuickFix.Description
1
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Wscript.Echo "Hot Fix ID: " & objQuickFix.HotFixID Next

-------------------------------------------------------------------------------- 6 检查本地管理员数目

Set objNetwork = CreateObject("Wscript.Network" strComputer = objNetwork.ComputerName
Set objGroup = GetObject("" & strComputer & "/Administrators,group" For Each objUser in objGroup.Members Wscript.Echo objUser.Name Next

-------------------------------------------------------------------------------- 7 磁盘系统

strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2"
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = 3"
For Each objDisk in colDisks
Wscript.Echo "Disk drive: "& objDisk.DeviceID & " -- " & objDisk.FileSystem Next

-------------------------------------------------------------------------------- 8 检测自动登录是否开启

Const HKEY_LOCAL_MACHINE = &H strComputer = "."
Set objReg=GetObject("winmgmts:\" & strComputer & "\root\default:StdRegProv" strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\WinLogon" strValueName = "AutoAdminLogon"
objReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName,dwValue If dwValue = 1 Then
Wscript.Echo "Auto logon is enabled." Else
Wscript.Echo "Auto logon is disabled." End If

-------------------------------------------------------------------------------- 9 关闭自动登录

Const HKEY_LOCAL_MACHINE = &H strComputer = "."
Set objReg=GetObject("winmgmts:\" & strComputer & "\root\default:StdRegProv" strKeyPath = "Software\Microsoft\Windows NT\CurrentVersion\WinLogon" strValueName = "AutoAdminLogon" dwValue = 0
2
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. oReg.SetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue

------------------------------------------------------------------------- 10 检查Guest是否禁用

Set objNetwork = CreateObject("Wscript.Network" strComputer = objNetwork.ComputerName
Set objUser = GetObject("" & strComputer & "/Guest" If objUser.AccountDisabled Then
Wscript.Echo "The Guest account is disabled." Else
Wscript.Echo "The Guest account is enabled." End If

------------------------------------------------------------------------- 11 关闭Guest
Set objNetwork = CreateObject("Wscript.Network" strComputer = objNetwork.ComputerName
Set objUser = GetObject("" & strComputer & "/Guest" If objUser.AccountDisabled Then
Wscript.Echo "The Guest account is already disabled." Else
objUser.AccountDisabled = True objUser.SetInfo
Wscript.Echo "The Guest account has been disabled." End If

-------------------------------------------------------------------------------- 12 检索本地共象 strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2" Set colShares = objWMIService.ExecQuery("Select * from Win32_Share" For each objShare in colShares
Wscript.Echo "Name: " & objShare.Name Wscript.Echo "Path: " & objShare.Path Wscript.Echo "Type: " & objShare.Type Next

-------------------------------------------------------------------------------- 13 脚本检索一个文件夹下.txt文件 汗哦值得学习


Set objWMIService = GetObject("winmgmts:\\.\root\cimv2" Set colFiles = objWMIService.ExecQuery("SELECT * FROM CIM_DataFile WHERE Path = '\\Documents and Settings\\Administrator\\桌面\\' AND Drive = 'E:' AND Extension =
'txt'" Wscript.Echo "Number of .txt files found: " & colFiles.Count
3
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. for each aa in colFiles NL=NL & vbcrlf & aa.name next Wscript.Echo NL
作者: 2005-4-21 19:39 回复此发言

-------------------------------------------------------------------------------- 14 我如何向用户显示一个用来选择文件的对话框? 问:
嗨,Scripting Guy!有没有什么方法可以让我使用脚本向用户显示一个对话框,供用户选择文件使用? -- BF 答:
您好,BF。如果您使用的是 Windows 2000,我们不知道实现此操作的方法,至少操作系统中没有内置这样的方法。但如果您使用的是 Windows XP,情况就不同了。在 Windows XP
上,您可以使用“UserAccounts.CommonDialog”对象向用户显示一个标准的文件打开对话框。可以用类似以下代码的脚本:
Set objDialog = CreateObject("UserAccounts.CommonDialog" objDialog.Filter = "All Files|*.*" objDialog.InitialDir = "C:\" intResult =
objDialog.ShowOpen If intResult = 0 Then Wscript.Quit Else Wscript.Echo objDialog.FileName End If
UserAccounts.CommonDialog
对象的对象引用(名为“objDialog”。接着,我们设置对话框的筛选属性。我们要显示所有文件,所以我们将筛选设置成这样: objDialog.Filter = "All Files|*.*"
假如我们只想显示文本文件,那该怎么办?在这种情况下,我们将使用以下筛选: objDialog.Filter = "Text Files|*.txt"
您也许能够看出它是如何运行的:我们为文件类型提供说明 (Text Files,然后插入一个竖线分隔符 (|,最后使用标准的通配符来指示所有 .txt 文件

(*.txt。是不是想默认显示 .txt 文件,然后为用户提供查看所有文件的选项?那么可以使用以下代码:
objDialog.Filter = "Text Files|*.txt|All Files|*.*" 试一试,您就明白我们的意思了。
然后,我们指定默认文件夹。默认情况下,我们希望对话框显示位于驱动器 C 的根文件夹中的文件,所以我们这样设置“InitialDir”属性: objDialog.InitialDir = "C:\"
希望显示 C:\Windows 文件夹中的文件吗?那么可以使用以下代码: objDialog.InitialDir = "C:\Windows" 不必担心:这是一个真正的文件打开对话框,所以您可以随意单击,并且可以随时停下来。您从 C:\Windows 开始并不意味着您只能打开该文件夹中的文件。 最后,我们使用下面这行代码显示对话框: intResult = objDialog.ShowOpen
现在,我们只需坐下来,等待用户选择文件并单击确定(或者等待用户单击取消。如4
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 果用户单击取消,则变量 intResult 将被设置为

0。在我们的脚本中,我们检查 intResult 的值,如果是 0,我们将只需要使用 Wscript.Quit 来终止此脚本。
但是如果用户实际上选择了文件并单击了确定那该怎么办?在这种情况下,intResult 被设置为

-1“FileDialog”属性将被设置为所选文件的路径名。我们的脚本只回显路径名,这意味着我们将得到类似以下内容的输出: C:\WINDOWS\Prairie Wind.bmp
不用说,您并不局限于只回显文件路径。实际上,您可以使用 WMIFileSystemObject 或一些其他技术来绑定该文件,然后对其执行删除、复制、压缩或检索文件属性等操作 对文件能够执行的操作差不多都可以对它执行。 但无论如何,您都需要使用脚本。
顺便说一句,使用此方法,您一次只能选择一个文件,而不能按住“Ctrl”键选择多个文件。有一种方法可以选择多个文件,至少在 XP
计算机上可以,但是我们只能将此问题留到以后的专栏中讨论了。

-------------------------------------------------------------------------------- 15 我如何确定进程是在哪个帐户下运行的? 问:
嗨,Scripting Guy!我有一个脚本,它返回关于计算机上运行的所有进程的信息,只是我不知道如何获得这些进程在其下运行的用户帐户的名称。您可以帮助我吗? -- DL 答:
您好,DL。是的,我们可以帮助您。确定进程是在哪个帐户下运行的,实际上相当简单,只是如何着手执行此操作并不是特别显而易见的。如果您与大多数人一样,那么您可能会通过扫描

Win32_Process 类的属性来查找名为 Account UserName
或类似的属性。您很有可能找不到。出现这种情况的原因是:Win32_Process 没有可以告诉您进程在哪个帐户下运行的属性。
您需要使用“GetOwner”方法来捕捉此信息。下面这个脚本可以告诉您 Microsoft Word (Winword.exe 在哪个帐户下运行:
strComputer = "."Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process
Where Name = 'Winword.exe'" For Each objProcess in colProcessList objProcess.GetOwner strUserName,
strUserDomain Wscript.Echo "Process " & objProcess.Name & " is owned by " _ & strUserDomain & "\" & strUserName & "."Next 我们最感兴趣的是下面这行代码:
objProcess.GetOwner strNameOfUser, strUserDomain 我们在此所做的就是调用“GetOwner”方法。GetOwner
返回两个输出参数,一个返回负责该进程的用户的名称,一个返回该用户所属的域。为捕获这两个输出参数,我们需要为 GetOwner
方法提供两个变量。在这个示例脚本中,我们使用了两个分别叫做 strUserName
5
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. strUserDomain 的变量。名称可以随意选择;您可以将变量称为 A B X Y 或任何其他您想要的名称。 不过,变量的顺序不能随意设置:返回的第一个值总是用户名,第二个值总是域。这意味着,如果您希望用 X 表示用户名,用 Y
表示域,那么您要确保您的代码像下面这行代码一样: objProcess.GetOwner X, Y
调用 GetOwner 之后,我们就可直接回显进程名和所有者。请注意,我们可以稍微来点儿花样儿

使用域\用户格式。这样,我们就可以回显类似于“fabrikam\kenmyer”的名称。
下面附带提供了另一个脚本,该脚本可以列出计算机上的所有进程以及各个进程的所有者: strComputer = "."Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process" For Each objProcess in colProcessList objProcess.GetOwner strUserName,
strUserDomain Wscript.Echo "Process " & objProcess.Name & " is owned by " _ & strUserDomain & "\" & strUserName & "."Next
可能有人感到奇怪,2005 1 3 日正好是 Microsoft 员工的正式休息日。那么今天为什么会有嗨,Scripting
Guy专栏?这只能是由于 Microsoft 脚本专家表现出来的对工作的难以置信的奉献和投入精神。或者,也可能是由于某个脚本专家 还说不出他或她的名字 没有意识到今天是假日,所以照常来了(而且是在早上 7 点啊!

-------------------------------------------------------------------------------- 16 可以将脚本的输出复制到剪贴板吗? 问:
嗨,Scripting Guy!有办法将脚本输出复制到剪贴板吗? -- ZW, Marseilles, France 答:
您好,ZW.如果您不介意用一些疯狂的解决方法,那么实际上将脚本输出复制到剪贴板相当容易。首先,您需要构造一个字符串,其中包含想要的输出。然后,创建

Internet Explorer 的一个实例,然后在其中打开一个空白页。接着,利用 Internet Explorer 对象模型的内置功能,将字符串复制到剪贴板;特别是, 可以使用 clipboardData.SetData 方法来实现这个技巧。将某些数据复制到剪贴板的示例脚本如下: strCopy = "This text has been copied to the clipboard." Set objIE = CreateObject("InternetExplorer.Application" objIE.Navigate("about:blank" "text", strCopy objIE.Quit 运行脚本,然后打开 Notepad,然后单击粘贴;应该可以看到所复制的字符串。
顺便说一下,所有这一切都是在幕后发生的,Internet Explorer 并不会真的出现在屏幕上。这是因为,在默认情况下,通过脚本创建的任何 IE
实例在运行时都是隐藏的,除非您利用如下语句将其显示出来: objIE.Visible = True

6
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. -------------------------------------------------------------------------------- 17 可以在运行脚本时修改当前命令窗口的标题吗? 问:
嗨,Scripting Guy在我运行一个批文件的时候,可以使用 Title 命令修改命令窗口的标题。我可以在脚本中修改命令窗口的标题吗? -- AA, Yokohama, Japan 答:
你好,AA.可以。只要您愿意打开一个新的命令窗口。如果您愿意,可以使用类似下面的这些代码:
Set objShell = CreateObject("Wscript.Shell" objShell.Run _ ("%comspec% /K title My Command Window |ping.exe ", _
1, TRUE 请注意我们在这里所做的。我们 创建了 Wscript.Shell 对象的一个实例,然后使用 Run 法运行

Ping.exe。但是,请看看我们用来运行脚本所用的这个长的命令字符串?我们做的就是调 %comspec%
打开一个新的命令窗口。我们使用“/K”开关参数确保窗口可以在脚本运行完毕后保持打开,而且我们将窗口的标题设置为“My Command Window”。非常简单明了。
在我们运行 Ping 的时候用了一些技巧;我们必须使用管道分隔符(| 字符)打开一个命令窗口,并且运行 Ping
命令,所有工作都在一个动作中完成。我的意思就是:打开一个命令窗口,设置窗口标题,然后运行

Ping.exe,所有这些都同时完成。如果不使用管道,脚本会打开一个标题为“My Command Window”的命令窗口,但是接着再打开 第二个命令窗口(带有默认标题),并在第二个窗口中运行 Ping。如果您想看看我们说的是否属实,可以试试这段脚本:
Set objShell = CreateObject("Wscript.Shell" objShell.Run("%comspec% /K title My Command Window ", 1, TRUE objShell.Run("ping.exe ", 1, TRUE 顺便说一下,如果您希望弄的美观漂亮(或者至少在命令行外壳允许的情况下尽可能地美观),可以在修改标题的同时修改窗口的前景和背景颜色。是否厌倦了在绿色背景上看淡黄色文字?那么可以运行这个脚本:
Set objShell = CreateObject("Wscript.Shell" objShell.Run _ ("%comspec% /T:2E /K title My Command Window|ping.exe " & _
"", 1, TRUE The secret here is the mysterious little switch /T:2E, which enables you to
change the foreground and background colors. For more information, open up a command window and type this: color /? 这里的秘密在于神秘的小开关参数“/T:2E”,它允许您修改前景和背景的颜色。更多相关信息,请打开一个命令窗口,并且在其中输入:
7
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. color /?

-------------------------------------------------------------------------------- 18 如何使用脚本管理计划任务? 问:
嗨,Scripting Guy!是否有简便的办法可以使用脚本来管理计划任务? -- RC 答:
嗨,RC。您就是要问这个问题,是吗?老实说,这正是脚本的强项之一,不过您在听了回答以后可能会比提问以前更为困惑。但先不管这个了。
这里我们碰到的问题是,实际上 Windows 具有两套——并且,令人感到沮丧的是还不完全兼容——API(应用程序编程接口)用于管理计划任务。对于其中一个,有

Task Scheduler API 用于任务计划程序 Schtasks.exeSchtasks.exe Windows XP Windows
Server 2003 附带的命令行任务管理工具。对于另一个来说,则有所谓的 At API 用于 At.exe WMI’s
Win32_ScheduledJob 类。
那么,会有什么问题呢?好吧,我们假设您使用 WMI
来创建计划任务(稍候我们会提供一个用于此用途的示例脚本)。如果您是这样的话,您就可以使用类似如下的脚本来检索有关使用 At API 创建的这个任务和其他任何任务的信息:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colScheduledJobs = objWMIService.ExecQuery _ ("Select * from Win32_ScheduledJob" For Each objJob in colScheduledJobs Wscript.Echo "Caption: " & objJob.Caption
Wscript.Echo "Command: " & objJob.Command Wscript.Echo "Days Of Month: " & objJob.DaysOfMonth Wscript.Echo "Days Of Week: " & objJob.DaysOfWeek Wscript.Echo "Description: " & objJob.Description Wscript.Echo "Elapsed Time: " & objJob.ElapsedTime
Wscript.Echo "Install Date: " & objJob.InstallDate Wscript.Echo "Interact with Desktop: " & objJob.InteractWithDesktop
Wscript.Echo "Job ID: " & objJob.JobID Wscript.Echo "Job Status: " & objJob.JobStatus Wscript.Echo "Name: " & objJob.Name Wscript.Echo "Notify: " & objJob.Notify Wscript.Echo "Owner: " & objJob.Owner
Wscript.Echo "Priority: " & objJob.Priority Wscript.Echo "Run Repeatedly: " & objJob.RunRepeatedly Wscript.Echo "Start Time: " & objJob.StartTime
Wscript.Echo "Status: " & objJob.Status
8
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Wscript.Echo "Time Submitted: " & objJob.TimeSubmitted Wscript.Echo "Until Time: " & objJob.UntilTime Next 除此以外,如果您打开任务计划程序,您还会在其中看到这个任务。So far so good, huh? 然而,假设您对自己这么说:既然我打开了任务计划程序,那我应该可以再计划第二个任务。假设您真的这么做了。那个使用任务计划程序创建的任务对 WMI
来说是不可见的。任务计划程序可以处理 WMI 创建的任务,但 WMI 却不能处理任务计划程序创建的任务。
更糟的是,假如您使用任务计划程序来修改原本使用 WMI 创建的任务。您可以成功修改这个任务,但是以后再也无法使用 WMI
来访问这个任务,即使一开始创建这个任务时使用的是 WMI 也一样。是的,我们知道。希望这个问题会在以后版本的 Windows
得到修正。并且,是的,我们也知道:现在这对您实际上没有多大帮助,对吧?抱歉。 那么,说了这么多意味着什么呢?好吧,这意味着使用 WMI 来管理计划任务是一件冒险的事情。如果您确定其他人没有使用任务计划程序来安排任务,那么 WMI
可以工作得很好。但如果其他人使用 WMI 脚本和任务计划程序,管理就会变得非常复杂。
那么,如何使用脚本来创建计划任务呢?对于初学者请尝试使用以下示例:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set objNewJob = objWMIService.Get("Win32_ScheduledJob" errJobCreated = objNewJob.Create _ ("Cleanup.exe", "********123000.000000-420", _ True , 1 OR 4 OR 16, , , JobID
Wscript.Echo errJobCreated A bit cryptic, isn’t it?以上脚本安排一个假想的程序 Cleanup.exe 在每周一、周三和周五下午 12:30
运行。有关此脚本中使用的不同参数的更多信息,请参阅以下地址的相关部分:Microsoft Windows 2000 脚本编写指南》中的相关部分.

-------------------------------------------------------------------------------- 19 如何使用命令行参数和默认值? 问:
嗨,Scripting
Guy!我希望有个脚本可以将计算机名作为命令行参数接收,然后对这些计算机中的每台计算机运行这个脚本。但是,如果不输入命令行参数,我希望它默认对本地计算机运行。你们能帮我吗? -- TS 答:
嗨,TS。当然,我们可以帮你。我们假设您在命令行提示符处输入以下命令来启动您的假想脚本:
cscript my_script.vbs atl-ws-01 atl-ws-02 atl-ws-03 这种情况下,您可能希望对以下三台计算机运行这个脚本:atl-ws-01; atl-ws-02; and atl-ws-03.
9
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 但如果您输入一个类似如下所示的没有任何命令行参数的命令,情况又会怎样呢: cscript my_script.vbs 这种情况下,您希望脚本说:哦,没有命令行参数,对吧?那好,我会对本地计算机运行。 那么,如何做到呢?好吧,您可以通过以下代码来实现: If
= 0 Then arrComputers = Array("." Else Dim arrComputers( For i = 0 to
- 1
Redim Preserve arrComputers(i arrComputers(i = Wscript.Arguments(i Next End If For Each strComputer in arrComputers
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colItems = objWMIService.ExecQuery _ ("Select * from Win32_OperatingSystem" For Each objItem in colItems Wscript.Echo objItem.Caption Next Next 我们稍微解释一下这段代码的工作原理。我们首先检查是否输入了命令行参数;我们通过 ,这会告诉我们脚本启动时被提供的参数数目)来检查这个值。假如这个值等于

0。这说明您没有提供命令行参数。因此,我们将数组 arrComputers 的值设为圆点 (“.”为什么设为圆点?这是因为在 WMI 中,圆点表示本地计算机。
那为什么使用数组?好吧,那是因为我们想要尽可能写入几行代码。通过使用数组,我们就不需要为没有指定命令行参数的情况编写一组代码,而为指定了一个(或是两个)命令行参数的情况另外编写一组代码。相反,我们只要使用 If-Then 语句来检查 的值就可以了。上面说过,如果这个值为 0(即没有输入命令行参数)那么我们就将

arrComputers 的值设为圆点。因此,我们就有了一个由单个项目组成的数组。 但如果 Count 不等于 0 呢?这种情况下,我们就要获取所有命令行参数,并将这些参数填充到 arrComputers 中。以下就是它的工作原理: 首先,我们使用以下代码创建一个动态数组:Dim
arrComputers(。动态数组就是事先不指定大小的数组;我们可以根据需要动态增加数组的大小。通过这种方式,我们就可以不必考虑所输出的命令行参数的个数,只要根据所有参数的数目调整数组的大小就可以了。
接下来,我们创建一个从 0 运行到 1 For Next 循环。这看来有点疯狂,但我们这么做是因为

VBScript 数组是从项目 0 开始的。因此,最后一个项目就自然是所有项目的总数减去 1例如,假设我们有三个项目。第一个项目是项目 0;第二个项目是项目 1;那么第三个项目就是项目 2 (3 1
10
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 对于每个项目,我们使用以下代码来重新调整数组大小:Redim Preserve arrComputers(i.会将数组大小设置为 i 的值(i
是循环变量,它告诉我们正在处理的是 Wscript.Arguments 中的哪些参数)。开始运行循环时,i 等于 0,因此我们实际上使用的是以下代码:Redim Preserve arrComputers(0,它为我们提供了一个单元素数组。
顺便说一下,代码中的 Preserve 部分用于确保在每次重新调整数组的维数时不会丢失所有现有数据。假设我们处在 Redim
arrComputers(,这时数组大小会被重新调整,但系统将会检测数组中原有的任何数据。 然后,我们将这个参数添加到数组中。如果我们提供 atl-ws-01 atl-ws-02 作为命令行参数,那么循环结束时 arrComputers
将是一个具有以下两个元素的数组:atl-ws-01 atl-ws-02
剩下的就简单了。我们创建一个可以对数组 arrComputers 中的所有元素循环运行的 For-Each 循环;我们知道,arrComputers 中可能包含一个圆点(表示本地计算机)也可能包含从命令行参数中获取的计算机名列表。每次循环运行都会连接到相应的计算机并检索

Win32_OperatingSystem 类的 Caption 属性。以上就是对您的问题的全部解答!

-------------------------------------------------------------------------------- 20 如何中止某个具有特定 PID 的进程? 问:
嗨,Scripting Guy!如果我知道进程的 PID,是否可以使用脚本中止这个进程? -- JV 答:
嗨,JV。当然可以。致那些不太熟悉缩写的同志们:PID 进程标识符”(Process Identifier 的缩写,这是创建进程时分配给它的唯一的身份证号码。(好吧,是暂时唯一:进程中止后,这个号码就会被回收,并可能被分配给另一个新进程。WMI Win32_Process 中有一个属性 (ProcessId 对应于 PID假设您想要中止 PID 2576 的进程,以下脚本就可以做这件事情:
strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process Where ProcessID = 2576" For Each objProcess in colProcessList objProcess.Terminate( Next 当然,您要记住 PID 是会经常变化的:尽管您现在要中止的进程的 PID 可能是 2576,但下一次创建时它可能就不会具有相同的 PID。因此,将 PID
值硬编码进来是不行的,您可能需要对这个脚本进行修改,以便它可以接受任何 PID 作为命令行参数: If
= 0 Then Wscript.Echo "You must enter a PID." Wscript.Quit End If 11
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. intPID =
strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process Where ProcessID = " & intPID & "" For Each objProcess in colProcessList objProcess.Terminate( Next 在上述脚本中,我们首先检查是否输入了命令行参数;如果没有输入任何命令行参数,我们就回显一条错误信息 (“You must enter a
PID.”,然后退出。如果输入了一个参数,我们就使用以下代码将第一个参数分配给变量 intPID intPID =
那么如果我们输入多个命令行参数呢?哦,在上述这段简单的脚本中,我们会忽略其他参数。不过您可以修改这个脚本,以便中止与您具有的 PID
对应的多个进程。有关如何实现的更多信息,请访问以下脚本故事专栏。
intPID 赋值后,我们使用 Win32_Process 类来定位这个进程并中止它。注意我们不是将 PID 硬编码进来,而是使用变量 intPID
("Select * from Win32_Process Where ProcessID = " & intPID & "" 如果您不调用这段代码,也可以使用名称(而不用 PID)来中止进程。例如,以下脚本可中止计算机上运行的所有 Notepad.exe 实例:
strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name = 'Notepad.exe'" For Each objProcess in colProcessList objProcess.Terminate( Next 上面说过,这段代码中止的是所有 Notepad 实例。如果您只想中止特定实例,请使用 PID这是因为 PID
对正在运行的进程来说是唯一的,而名称则不是。换句话说,PID 2576 的进程只有一个,但名称为 Notepad.exe 的进程却可能有很多。
有关使用脚本管理进程的更多信息,请参阅以下地址的相关部分“Microsoft Windows 2000 脚本编写指南”.
21 如何暂停一个脚本,然后在用户按下键盘上的一个键时恢复它的运行? 如何暂停一个脚本,然后在用户按下键盘上的一个键时恢复它的运行? 问:
嗨,Scripting Guy!我想暂停脚本,然后在用户按下键盘上的任意按键时恢复它的运行。我怎样才能做到? -- AL 答:
嗨,AL。哦,这个问题让我们回溯到:按任意键继续,以及终止、重试或失败这一计12
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 算机史上最著名的词组之一。对不起,我们需要一点时间来感叹以前那些美好的时光。……
过去,按任意键继续几乎是每个批处理文件的基本要素。以前,只要在批处理文件当中插入一个暂停命令;那样,批处理文件就会暂停——就像忠实的老狗,呆在那里,等您按键盘上的按键。只要按一个键——任意键,批处理文件就会继续运行。有兴趣追忆往事的人可以试着运行这个简单的小批处理文件,来了解具体情况: echo off pause echo The batch file is complete. 注意:将其保存为 .bat 文件,而不是 .vbs 文件。
无疑您们当中有许多人会想:哇,脚本比批处理文件好得多,也强大得多。我打赌会有非常棒的方法用以在脚本中执行按任意键继续的操作。老实说,我们也会这么认为。但您猜怎么样:没有办法在脚本中实现这一功能。
那么,可能有某种笨一些的变通方法,可是我们绞尽脑汁也想不出一个法子。问题在于 Windows Script Host
不是设计作为一个以事件驱动的环境;换句话说,WSH
不知道如何等待某个事件(比如:按键盘上的键)的发生。加上与命令行交互的能力有限,因此只能得到无法实现暂停命令功能的脚本环境。
我们知道:这不是您真正希望得到的答案。而我们确实可以给您一个安慰奖。我们无法复制暂停命令(可让计算机等到您按了键盘上的任意键后再继续执行操作)。但是,我们可以给您一些代码,从而让计算机等到您按了键盘上的“ENTER”键后再继续执行操作(是的,必须是“ENTER”键)。这与您想要的并不完全相符,但却行得通: strMessage = "Press the ENTER key to continue. " strMessage Do While Not Input =
Loop WScript.Echo “The script is complete.”
这个脚本所做的就是在屏幕上显示一条消息,然后使用 StdIn(仅包含在 WSH 5.6 中,这表示只有安装了 WSH 5.6
才可以运行该脚本)等待用户在命令行中输入数据。StdIn
将等待您按“ENTER”键;只要一按“ENTER”键,该脚本就将继续运行。如果按了“ENTER”键以外的其他键又会怎么样?没什么大不了:所按的任何其他键的值将显示在屏幕上。在最终按到“ENTER”键之前,脚本只会显示所按的任何其他键的值。那时,脚本会结束循环并继续运行。
假如您有疑惑,记得 StdIn
确实是使用命令行向脚本输入数据的一种方法。例如,您的脚本可能会提示您输入用户名或文件名。因此等您按“ENTER”键,作为指示数据输入完成的一种方法。否则,可能键入用户名的第一个字母时,StdIn
就会开始运行。“ENTER”是表示数据输入完成的官方信号。

-------------------------------------------------------------------------------- 22 如何知道哪些脚本正在计算机上运行? 如何知道哪些脚本正在计算机上运行?
13
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 问:
嗨,Scripting Guy!如何知道哪些脚本正在计算机上运行? -- NW 答:
嗨,NW。这个问题我们通常不大愿意回答,因为有 50% 的概率您可能对所听到的解答感到不满意。如果运行的是 Windows 2000(或 Windows 的以前版本),那么答案很简单:办不到。诸如下方的脚本——可查找在 Cscript.exe Wscript.exe
下运行的所有进程——可以告诉您有脚本正在计算机上运行:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colItems = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name = 'cscript.exe'" & _ " OR Name = 'wscript.exe'" For Each objItem in colItems Wscript.Echo objItem.Name Next 但是,该脚本无法告诉您相关脚本的名称。实际上,据我们所知,操作系统中内置的程序无法识别在 Windows 2000
计算机上运行的各个脚本;即便任务管理器也只能进程名称(Cscript.exe Wscript.exe 但是,如果运行的是 Windows XP Windows Server 2003,那么我们就可以为您提供不同——更好的——的解答。Windows XP

Win32_Process 类别添加了一个新的属性——CommandLine。正如其名,CommandLine 可告诉您用以启动进程的确切命令。例如,假设您在命令提示符中通过键入 cscript my_script.vbs 来启动一个脚本。该脚本的 CommandLine 属性将为:
cscript my_script.vbs 换句话说,现在您已经知道名为 My_Script.vbs 的脚本正在计算机上运行。
但是如果不使用命令提示符来启动脚本又如何?如果在 Windows 资源管理器中双击文件图标并在 Wscript 下运行该脚本又会怎么样?没有问题。假如双击文件 C:\Scripts\My_Script.vbs;将得到如下的 CommandLine 值:
C:\WINDOWS\System32\WScript.exe "C:\Scripts\My_Script.vbs" 正如您所看到,我们得到了 Wscript 可执行文件的路径以及正在运行的脚本的路径。现在差不多了吧?
无论如何,如果运行的是 Windows XP Windows Server 2003,那么这里有一个脚本可以帮您实现这一技巧:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colItems = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name = 'cscript.exe'" & _ " OR Name = 'wscript.exe'" For Each objItem in colItems 14
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Wscript.Echo objItem.CommandLine Next

-------------------------------------------------------------------------------- 23 如何向本地管理员组中添加一个域用户? 如何向本地管理员组中添加一个域用户? 问:
嗨,Scripting Guy!如何向本地管理员组中添加一个域用户? -- MB 答:
嗨,MB。我们推出该专栏的原因之一是想要了解有关系统管理所从事的日常工作(以及脚本)的更多信息。实际上,呆在 Microsoft
学院顶楼的豪华套间里,我们常常无法完全了解外界所发生的事情。例如,我们在脚本中里提供了一个示例脚本,向您展示如何对本地管理员帐户添加用户:
strComputer = "atl-ws-01" Set objGroup = GetObject("" & strComputer & "/Administrators" Set objUser = GetObject("" & strComputer & "/kenmyer" objGroup.Add(objUser.ADsPath 那么,这个脚本有什么问题吗?没问题,只是这可能不是最实用的例子。毕竟,这个脚本向您展示了如何对管理员组添加其他本地用户。这没错,但是您们当中大部分人确实想知道(可以从我们已经收到的电子邮件的数量获悉)如何对本地管理员组添加域用户。收到的信息清清楚楚:让我们告诉您如何对本地管理员组添加域用户。 顺便提一下,执行该任务的脚本与为管理员组添加本地用户的脚本几乎完全相同。唯一的区别(稍候我们将看到)在第三行中。在前面所述的脚本中,我们使用这行代码绑定到计算机的本地用户帐户上:
Set objUser = GetObject("" & strComputer & "/kenmyer" 然后,我们将该用户帐户的 ADsPath 传递给 Add 方法(可将用户添加到组中)
objGroup.Add(objUser.ADsPath 我们想借助新的脚本实现同样的目的,但是我们不想绑定到本地用户帐户,而要绑定到域用户帐户。那么,这就是我们所要做的,用新的代码替换第三行代码:
Set objUser = GetObject("" 这里,我们使用了 WinNT 提供程序来绑定到 fabrikam 域;更确切地说,我们使用了 WinNT 提供程序来绑定到 fabrikam 域中的

kenmyer 用户帐户上。哈,我们看到您们当中有些人对此感到不安。您嘴里会嘀咕:他们为何使用 WinNT 提供程序?他们不是应该使用 LDAP 提供程序来绑定 Active Directory 吗?
大多数时候,这个问题的答案是肯定的。但是,假设我们使用了 LDAP 提供程序来检索 kenmyer ADsPath,使用如下代码:
Set objUser = GetObject(“,OU=Finance,dc=fabrikam,dc=com” 这看起来没问题,除了得到如下的 ADsPath 以外:
,OU=Finance,dc=fabrikam,dc=com 这也不错……至少当您试着将该值传递给本地计算机时是如此。请记住,本地计算机上的安全帐户管理器支持 WinNT,但不支持 LDAP。如果尝试将 LDAP 路径传递给本地计算机,那么该脚本将无效。
15
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 相反,我们传递类似如下所示的 ADsPath

您知道吗?如果使用 WinNT 提供程序绑定到 fabrikam 域,那恰好是我们将取回的那种 ADsPath。如果严格使用 Active
Directory,那么应该使用 LDAP 提供程序。但是如果要从 Active Directory
中取出一个帐户,并在本地计算机组中使用该帐户,那么就必须使用 WinNT 提供程序。 我们知道:有关提供程序和 ADsPaths 以及各个注意事项已经让您晕头转向了。但是不要对此过于烦恼。只要使用该脚本将域用户(fabrikam 域中名为

kenmyer 的用户)添加到计算机 atl-ws-01 上的本地管理员组就行了:
strComputer = "atl-ws-01" Set objGroup = GetObject("" & strComputer & "/Administrators" Set objUser = GetObject("" objGroup.Add(objUser.ADsPath

-------------------------------------------------------------------------------- 24 如何确定文件的拥有者是谁? 如何确定文件的拥有者是谁? 问:
嗨,Scripting Guy!有没有办法使用脚本来确定文件的所有者是谁? -- BD 答:
嗨,BD。事实上,有一个办法可以使用脚本来确定文件的所有者,虽然可以理解您为何无法自己找到该信息。毕竟,有两种主要的脚本编写界面用以管理文件:Script Runtime FileSystemObject WMI 类别

CIM_DataFile由于这两种界面都不包含用以确定文件所有权的属性或方法,因此逻辑结论为:噢,我想您们根本就办不到这一点。 但您知道如何通过编写脚本来实现:事情总可以办到,即便具体的方法与您所预料的不尽相同。在这种情况下,需要同时结合使用 WMI

Win32_LogicalFileSecuritySetting 类别和 Win32_LogicalFileOwner
关联类别来确定文件所有权。正如您可能预料的,LogicalFileSecuritySetting
Win32_LogicalFileOwner 类别将发挥作用:其将取得所有者的

SID(安全识别符)并将其中转给 Win32_SID 类别。然后,Win32_SID 类别可以查找并报告所有者名称和域。
昏了吗?这不怪您;关联类别并不那么直观。但是,幸好不必了解关联类别的工作原理;只要确认其确实有用就行了。例如,这里有一个脚本可报告文件 C:\Scripts\My_script.vbs 的所有者: On Error Resume Next strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" strFile = "C:\Scripts\My_script.vbs" Set colItems = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_LogicalFileSecuritySetting='" & strFile & "'}" _
16
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. & " WHERE AssocClass=Win32_LogicalFileOwner ResultRole=Owner" For Each objItem in colItems Wscript.Echo objItem.ReferencedDomainName Wscript.Echo objItem.AccountName Next 看起来有点疯狂,但确实管用。倘若需要获得其他文件的所有者信息,又该怎么办呢?没有问题:只要将 strFile 变量的值设为相关文件的完整路径就行了。
不要让名称误导了您:这两个类别还可用以确定文件夹的所有者。例如,该脚本将报告文件 C:\Scripts 的所有者: On Error Resume Next strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" strFile = "C:\Scripts" Set colItems = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_LogicalFileSecuritySetting='" & strFile & "'}" _ & " WHERE AssocClass=Win32_LogicalFileOwner ResultRole=Owner" For Each objItem in colItems Wscript.Echo objItem.ReferencedDomainName Wscript.Echo objItem.AccountName Next

-------------------------------------------------------------------------------- 25 如何向文档的备注字段写入信息? 如何向文档的备注字段写入信息? 问:
嗨,Scripting Guy!能否使用脚本向文件的备注字段添加文字? -- EF 答:
嗨,EF。如果您们当中有谁不明白 EF 所说的问题,请在 Windows
资源管理器中右击一个文档,然后单击属性。在弹出的对话框中,单击摘要选项卡。看到了标注为备注的文本框了吗?那就是 EF 想要使用脚本填充的字段。
那么,可以办到吗?实际上可以,前提是先访问Microsoft.com 上的下载中心并下载 DsofileDsofile 会安装一个新的 COM
对象,使您可以在文档的摘要信息字段中进行读写操作。例如,这里有一个脚本可以在文档备注字段中加入灵活的备注:“This is a comment”
Set objPropertyReader = CreateObject("DSOleFile.PropertyReader" Set objDocument = objPropertyReader.GetDocumentProperties _
("C:\Scripts\Test.doc"
objDocument.Comments = "This is a comment." 非常不错吧?可使用脚本修改的摘要信息字段包括:作者类别备注公司键字最后一次保存者管理器主题标题 当然,也可以读取摘要信息字段:
Set objPropertyReader = CreateObject("DSOleFile.PropertyReader"
17
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Set objDocument = objPropertyReader.GetDocumentProperties _
("C:\Scripts\Test.doc" Wscript.Echo "App name: " & objDocument.AppName Wscript.Echo "Author: " & objDocument.Author Wscript.Echo "Byte count: " & objDocument.ByteCount Wscript.Echo "Category: " & objDocument.Category Wscript.Echo "Character count: " & objDocument.CharacterCount Wscript.Echo "Character count with spaces: " &
objDocument.CharacterCountWithSpaces
Wscript.Echo "CLSID: " & objDocument.CLSID Wscript.Echo "Comments: " & objDocument.Comments Wscript.Echo "Company: " & objDocument.Company Set colCustomProperties = objDocument.CustomProperties For Each strProperty in colCustomProperties Wscript.Echo vbTab & strProperty.Name & ": " & strProperty.Value Next Wscript.Echo "Date created: " & objDocument.DateCreated Wscript.Echo "Date last printed: " & objDocument.DateLastPrinted Wscript.Echo "Date last saved: " & objDocument.DateLastSaved Wscript.Echo "Has macros: " & objDocument.HasMacros Wscript.Echo "Hidden slides: " & objDocument.HiddenSlides Wscript.Echo "Icon: " & objDocument.Icon Wscript.Echo "Is read only: " & objDocument.IsReadOnly Wscript.Echo "Keywords" & objDocument.Keywords Wscript.Echo "Last edited by: " & objDocument.LastEditedBy Wscript.Echo "Line count: " & objDocument.LineCount Wscript.Echo "Location: " & objDocument.Location Wscript.Echo "Manager: " & objDocument.Manager Wscript.Echo "Multimedia clips: " & objDocument.MultimediaClips Wscript.Echo "Name: " & objDocument.Name Wscript.Echo "Page count: " & objDocument.PageCount Wscript.Echo "Paragraph count: " & objDocument.ParagraphCount Wscript.Echo "Presentation format: " & objDocument.PresentationFormat Wscript.Echo "Presentation notes: " & objDocument.PresentationNotes Wscript.Echo "ProgID: " & objDocument.ProgID Wscript.Echo "Revision number: " & objDocument.RevisionNumber Wscript.Echo "Slide count: " & objDocument.SlideCount Wscript.Echo "Subject: " & objDocument.Subject Wscript.Echo "Template: " & objDocument.Template Wscript.Echo "Thumbnail: " & objDocument.Thumbnail Wscript.Echo "Title: " & objDocument.Title Wscript.Echo "Version: " & objDocument.Version Wscript.Echo "Word count: " & objDocument.WordCount 在您提问之前,我们不知道操作系统内部中有任何方法可以让您修改摘要信息字段;必须下18
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Dsofile 来完成此任务。当然可以使用 Windows Shell外壳)对象至少读取部分这类信息。如需详细信息,请参见Microsoft Windows 2000 本指南.

-------------------------------------------------------------------------------- 26 如何确定驱动器剩余空间所占的百分比? 如何确定驱动器剩余空间所占的百分比? 问:
嗨,Scripting Guy!我知道如何确定驱动器的剩余空间量,但如何确定驱动器剩余空间所占的百分比呢? -- MS 答:
嗨,JP。没错:确定驱动器有多少剩余空间非常简单。例如,以下脚本可以告诉您计算机的 C 盘上剩余多少空间(单位为字节)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colDisks = objWMIService.ExecQuery _ ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'" For Each objDisk in colDisks Wscript.Echo objDisk.FreeSpace Next 有一个好消息要告诉您的是:确定磁盘剩余空间所占的百分比也差不多同样简单。这是因为剩余空间的百分比只要计算一下就可以知道了:您可以将剩余空间除以整个驱动器的大小。假设我们有一个很小的驱动器,10 字节的驱动器, 2 字节剩余空间。若要确定磁盘剩余空间所占的百分比,我们只要将 2 10(剩余空间除以全部大小),然后我们就会得到

.20。换句话说,就是我们的小型驱动器上有 20% 的剩余空间。
这是一个简单的等式,等式的一半我们已经有了:Win32_LogicalDisk 类的 FreeSpace 属性可以告诉我们剩余多少空间。尽管您可能没有意识到,我们也有了等式的另一半:同一个类的 Size 属性可以告诉我们驱动器的大小。而脚本所要做的就是将 FreeSpace 除以 Size,然后我们就可以得到百分比:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colDisks = objWMIService.ExecQuery _ ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'" For Each objDisk in colDisks intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size pctFreeSpace = intFreeSpace / intTotalSpace Wscript.Echo pctFreeSpace
Next 简单吧?这个脚本的唯一问题就是它报告的是一个小数,例如

19
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 0.101427。是的,从技术上来说它是比较精确,但是这个答案看来似乎不像百分比。因此,我们使用 VBScript

FormatPercent 函数以便得到一个类似于 22.45% 的值:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colDisks = objWMIService.ExecQuery _ ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'" For Each objDisk in colDisks intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size pctFreeSpace = intFreeSpace / intTotalSpace Wscript.Echo FormatPercent(pctFreeSpace Next 这看来好多了。
哎呀,这里还有另外一个变量。默认情况下,Win32_LogicalDisk 类会查找计算机上的所有磁盘驱动器,包括软盘驱动器、可移动 Zip
驱动器等等。因此如果您只希望得到硬盘上的剩余空间,请修改 WQL Query,以便它仅选 DriveType 3 的所有驱动器(在 WMI 中表示硬盘)。换句话说:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2" Set colDisks = objWMIService.ExecQuery _ ("Select * from Win32_LogicalDisk Where DriveType = 3" For Each objDisk in colDisks intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size
pctFreeSpace = intFreeSpace / intTotalSpace Wscript.Echo objDisk.DeviceID, FormatPercent(pctFreeSpace Next

-------------------------------------------------------------------------------- 27 如何确定我的用户是否在他们的计算机上有某些特定的文件? 如何确定我的用户是否在他们的计算机上有某些特定的文件? 问:
嗨,Scripting Guy!是否可以在计算机上搜索用户本不该有的 .MP3 文件或其他文件? -- AK 答:
嗨,AK。又是一个可以用 WMI 解决的问题。使用 CIM_DataFile 类可以很容易地在计算机上搜索特定类型的文件。不是想要知道您的用户计算机上是否有 .MP3 文件吗?那就用类似如下的脚本吧:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
20
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * from CIM_DataFile where Extension = 'mp3'" For Each objFile in colFiles Wscript.Echo objFile.Name
Next 您可以看到,这是一段标准的 WMI 脚本:我们要查找的就是所有扩展为 MP3 CIM_DataFile 类的实例(注意不要将句号包括进来;我们要查找的是 MP3 而不是 .MP3这是一个非常简单小巧的脚本,但是在具有 512 MB 内存和 30 G 盘空间的 2.39 GHz
便携式计算机上却运行得非常快,我们在不到 30 秒钟的时间内就得到了所有 .MP3 文件的列表。
我们甚至可以使用一个查询搜索多个文件类型。例如,以下脚本可以搜索 .WMA 文件 .MP3 文件:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * from CIM_DataFile where Extension = 'mp3' OR Extension = 'wma'" For Each objFile in colFiles Wscript.Echo objFile.Name
Next 但这还不够好。您说过这些文件是您的用户不该有的,我们猜想您可能希望从您的用户计算机上删除这些文件。上述脚本不能执行这项任务,它只能报告在某台计算机上发现的所有 .MP3

.WMA。您仍然需要自己去联系每个用户,并请他或她删除这些文件。这对您来说是不小的工作量,然后您就得依赖于用户删除这些文件(并且不能误删其他文件)。为什么不使用脚本来做这些麻烦事呢?以下脚本不仅可以跟踪计算机上所有 .MP3 .WMA 文件,它还可以在发现这些文件时删除它们:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * from CIM_DataFile where Extension = 'mp3' OR Extension = 'wma'" For Each objFile in colFiles objFile.Delete
Next 而且记住,这段脚本对远程计算机同样有效,并且速度和对本地计算机一样快。我们只要将变量 strComputer
的值更改为远程计算机的名称就可以对远程计算机执行这段脚本。

-------------------------------------------------------------------------------- 28 可以使用脚本确定远程计算机上某个文件夹的大小吗? 可以使用脚本确定远程计算机上某个文件夹的大小吗?
21
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 问:
嗨,Scripting Guy!可以使用脚本确定远程计算机上某个文件夹的大小吗? -- SS 答:
嗨,SS。伙计,您想自己应该可以办到这一点,不是吗?如果您已经关注 WMI 类别 Win32_Directory 并注意到 FileSize 属性,那么尤其会这么想。这时,您会想:显然可以编写 WMI 脚本来获知文件夹的大小。那样,您可能会编写一个非常类似下方所示的脚本(试图确定计算机 atl-ws-01 上的文件夹 C:\Scripts 的大小): strComputer = "atl-ws-01" Set objWMIService = GetObject _ ("winmgmts:" & "!\\" & strComputer & "\root\cimv2" Set colFolders = objWMIService.ExecQuery _ ("Select * from Win32_Directory where Name = " _
& "'c:\\scripts'" For Each objFolder in colFolders Wscript.Echo objFolder.FileSize Next 可惜,这个脚本帮不了什么忙,但这不是因为脚本代码或脚本语法存在问题,只是由于 FileSize
属性起不了作用。不管连接到的是哪个文件夹,也不管该文件夹是在本地计算机上还是在远程计算机上,都没有关系。FileSize 将总返回 Null 值。
说明:应该提一下,CIM_DataFile 类别(用于管理文件的 WMI 类别)中也有一个 FileSize 属性。那个 FileSize
属性可以用;它将告诉您文件的大小(以字节为单位)
那么,现在该怎么办呢?总是可以使用 FileSystemObject 来确定文件夹的大小。例如,这里有一个脚本可以告诉您 C:\Scripts 文件夹的大小:
Set objFolder = objFSO.GetFolder("C:\Documents and Settings" Set objFile = objFSO.CreateTextFile("c:\scripts\folder_size.txt" Wscript.Echo objFolder.Size 唯一的问题是:FileSystemObject 设计用于在本地使用,而要确定其大小的文件夹却位于远程计算机上。那么知不知道有办法可以解决这个问题呢?至少我们知道一个解决办法。
如果正在使用 Administrative 共享(比如:C$ D$,那么可以通过连接到正确的 Administrative
共享获得该文件夹信息。也就是说,您可以使用类似如下所示的脚本(使用 UNC 路径 \\atl-ws-01\C$\Scripts 来获取远程计算机上的 C:\Scripts 文件夹:
Set objFSO = CreateObject("Scripting.FileSystemObject" Set objFolder = objFSO.GetFolder("\\atl-ws-01\C$\Scripts" Wscript.Echo objFolder.Size 这很好,但前提是正在使用 Administrative 共享。但如果这些共享在计算机上已被禁用,该怎么办呢?什么?
老实说,很不幸,除非您想作为登录或注销脚本来运行文件夹大小脚本。如果您在远程计算22
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 机上有某种共享文件夹,那么也可以将文件夹大小脚本复制到远程机器上,在本地运行,取有关数据,然后再删除;我们在较早的嗨,Scripting Guy 专栏中介绍过相似的技巧。 如果在远程计算机上没有共享文件夹,又该怎么办呢?不幸的是,我们在这方面不能向您提供多少建议。您可以在 Internet
上搜索可获知远程机器上的文件和文件夹大小的第三方工具。

-------------------------------------------------------------------------------- 29 可以使用脚本创建和删除一个 DSN 吗? 可以使用脚本创建和删除一个 DSN 吗? 问:
嗨,Scripting Guy!能否迅速创建 ODBC 数据源名称 (DSN 并在完成后即刻将其删除? -- KC 答:
嗨,KC。能否创建 ODBC DSN 然后再将其删除?老实说,我们不能肯定。但是,答案是:只要您愿意编写脚本来修改注册表,那么是的,您可以通过编程来创建并删除 DSN
说明:如果您不能确定 DSN 是什么,那么只要引用该 DSN
名称,就有办法连接到数据库,而不必对该数据库指定完整的路径。如果您有访问该数据库的大量脚本,这将非常方便。如果您将路径硬编码到脚本中,然后将该数据库从一台服务器移动到另一台服务器,那么必须对每个脚本编辑路径。但是,如果使用

DSN,那么完全不必编辑脚本;只需修改 DSN。一次更改取代了几百次更改(这取决于您有多少个脚本)
我们将向您展示可创建使用 SQL Server DSN 的脚本。这一点重要吗?相同。您可以创建使用其他 ODBC
数据库(AccessOracleFoxPro 等等)的 DSN。但是,创建 DSN 来访问 Oracle 数据库时所用的注册表项和值不必与用于访问 SQL
Server 数据库的注册表项和值完全相同。如果正在使用 SQL
Server,只要复制我们的脚本并更改数据库、服务器等的名称就可以了。如果正在使用其他数据库,建议您手动创建

DSN。完成之后,启动您最常用的注册表编辑器,并在此查找 DSN HKLM\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources 以及这里:
HKLM\SOFTWARE\ODBC\ODBC.INI\Name You Gave the DSN 看一下这类数据库所需的注册表项和值,然后将有关信息插入该脚本。如果您无法确定具体的实现方法,给我们一两周时间,到时我们就可以知道能否在脚本中心内发布一些示例脚本。
无论如何,这里有一个脚本可以创建使用 SQL Server DSN Const HKEY_LOCAL_MACHINE = &H strComputer = "." Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv" strKeyPath = "SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources" strValueName = "Script Repository"
23
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. strValue = "SQL Server" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue strKeyPath = "SOFTWARE\ODBC\ODBC.INI\Script Repository" objReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath strKeyPath = "SOFTWARE\ODBC\ODBC.INI\Script Repository" strValueName = "Database" strValue = "Script Center" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue strValueName = "Driver" strValue = "C:\WINDOWS\System32\SQLSRV32.dll" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue strValueName = "Server" strValue = "atl-sql-01" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue strValueName = "Trusted_Connection" strValue = "Yes" objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue 没错,我们知道这个脚本有点长,但是这是因为必须创建许多注册表项和值。但是,脚本的绝大部分都相当简洁。首先,我们将 HKEY_LOCAL_MACHINE 常量设为 &H(需要连接到注册表的 HKLM 部分的值)。然后,绑定到 WMI 服务以及 StdRegProv 类别(正如我们经常提醒您的那样,该类别恰好在 root\default 命名空间里)
我们在那里创建了一个新的注册表值 (HKLM\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources\Script
Repository,名为“Script Repository”(赋予新的 DSN 的名称)。我们将该值设为“SQL Server”,因为这是我们所要连接的数据库类型。
HKLM\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources\Script Repository(请注意,该项的名称与我们的 DSN 名称相同)然后,需要配置下列注册表值: Database——我们所要连接的数据库的名称。该例中,数据库名为“ScriptCenter”
Driver——SQL Server ODBC C:\WINDOWS\System32\SQLSRV32.dll
Server——在其上找到该数据库的服务器的名称。这里,服务器的名称为“atl-sql-01” Trusted_Connection——当我们访问该数据库时,告诉 SQL Server 使用我们的登录凭据。样,不用提供用户名和密码就可以连接到该数据库。 就是这样;运行该脚本,就将获得功能全面的 DSN
用完之后,如何将该 DSN 删除呢?这也一样简单:毕竟,只需删除我们的第一个脚本所创建的注册表项和值。这里有一个脚本可删除 DSN Script Repository
Const HKEY_LOCAL_MACHINE = &H strComputer = "." Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv" strKeyPath = "SOFTWARE\ODBC\ODBC.INI\Script Repository" objReg.DeleteKey HKEY_LOCAL_MACHINE, strKeyPath
24
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. strKeyPath = "SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources" strValueName = "Script Repository" objReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName 请注意,该脚本所做的就是删除我们刚才创建的第一个注册表值 (Script
Repository,再删除我们所创建的注册表项。不必删除该项中的各个注册表值,因为删除 HKLM\SOFTWARE\ODBC\ODBC.INI\ODBC
Data Sources\Script Repository 也将同时删掉所有的值。

-------------------------------------------------------------------------------- 30 如何使用 CDO 将一个文件附加到电子邮件中发送出去? 问:
嗨,Scripting Guy!我知道如何使用 CDO 来发送电子邮件,但是如何在电子邮件中加入附件呢? -- RT 答:
嗨,RT。顺便说一下,感谢您提出这个问题。至少有一名 Scripting Guys 成员几乎整个感恩节周末都在吃东西,而在不吃东西的那一点点时间里,他与一大群比他更高大但年轻的多的侄子外甥们一起玩橄榄球。说实话,这位 Scripting Guy 成员希望能够顺利地恢复工作状态,而这个问题正是一个非常好的开端。
对于不熟悉 CDOCollaboration Data Objects 的简称)的人而言,这项技术提供了一条通过脚本发送电子邮件的途径。只要网络中有 SMTP
服务器,就可以使用类似下方所示的代码创建并发送电子邮件: Set objEmail = CreateObject("CDO.Message" objEmail.From = "" objEmail.To = "" objEmail.Subject = "Server down"
objEmail.Textbody = "Server1 is no longer accessible over the network."
_ ("/configuration/sendusing" = 2
_ ("/configuration/smtpserver" = _ "smtpmailer"
_ ("/configuration/smtpserverport" = 25
objEmail.Send 今天我们不会详细介绍这个脚本;如需快速了解此处所用的各个属性,请参见Microsoft Windows 2000 脚本指南. 可能不需要费多大力气,您就可以设好 FromToSubject Textbody
属性。URI(比如:/configuration/sendusing)属于样本代码,通常可以保留不动;在多数情况下,只需更改

smtpserver。在我们的示例代码中,我们已经引用了一台 SMTP 邮件服务器(我们称之为 smtpmailer;您将需要把它替换为您的 SMTP 邮件服务器的名称。
25
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 顺便说一下,这些 URI 关联到许多人:他们疑惑为何需要连接到 Microsoft 来发送电子邮件。事实是,不会真的连接到 Microsoft;这些 URI
只是属性而已。为何要怎样引用呢?老实说,我们不清楚。但是别担心:您的邮件不会通过 Microsoft
进行路由,而且这里的人也不会阅读您的信件。相信我们,我们自己的电子邮件已经让我们够头疼了,没有时间去读别人的邮件。
那么,如何在电子邮件中加入附件呢?只要再加一行代码就行了,比如这行代码(将文件 C:\Scripts\Output.txt 附加到电子邮件中)
objEmail.AddAttachment "C:\Scripts\Output.txt" 就是这样;在脚本中加入这行代码,就可以得到附件了。整个脚本的内容将为: Set objEmail = CreateObject("CDO.Message" objEmail.From = "" objEmail.To = "" objEmail.Subject = "Server down"
objEmail.Textbody = "Server1 is no longer accessible over the network." objEmail.AddAttachment "C:\Scripts\Output.txt"
_ ("/configuration/sendusing" = 2
_ ("/configuration/smtpserver" = _ "smtpmailer"
_ ("/configuration/smtpserverport" = 25
objEmail.Send 请注意,有几个人问过我们,如果 SMTP
服务器要求身份验证,该如何发送电子邮件呢?说实话,我们很难回答这个问题,因为(由于各种原因),我们无法测试这种情景。但是,可以在脚本中添加用户名和密码:
_ ("/configuration/sendusername" = "fabrikam\kenmyer" _

("/configuration/sendpassword" = "&gr54#wgha" 上面的代码将让您作为 fabrikam\kenmyer 登录 SMTP 服务器,密码为

&gr54#wgha。请注意,这样确实将以明文形式发送用户名和密码。因此,您可能不想使用管理员帐户发送电子邮件。那么,创建一个有权发送电子邮件的用户帐户,并使用该帐户进行登录。如需更多信息,请参见 MSDN 上的官方CDO 文档

-------------------------------------------------------------------------------- 31 如何确定快捷方式所对应的可执行文件? 如何确定快捷方式所对应的可执行文件? 问:
嗨,Scripting Guy!如何确定 .lnk 快捷方式文件所对应的可执行文件名?
26
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. -- AM 答:
嗨,DE。我们很高兴您提出这个问题,与我们收到的某些问题(例如,如何使用脚本来禁 Windows 2000
计算机上的文件和打印共享功能?)不同,这个问题恰好是我们可以解答的。
WMI “Win32_ShortcutFile” Win32_ShortcutFile
类并请求“Target”属性;它就是在双击快捷方式时调用的可执行文件(或脚本、文档及任何其他内容)的名称。以下是一个简短的脚本,它可以列出计算机上的所有快捷方式文件,并指定您在我的电脑 Windows
资源管理器中看到的图标标题(“FileName”、对应的可执行文件的名称(“Target”)以及快捷方式本身的文件路径(“Description”
strComputer = "."
Set objWMIService = GetObject _
("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery("Select * From Win32_ShortcutFile" For Each objFile in colFiles
Wscript.Echo "Name: " & objFile.FileName Wscript.Echo "Shortcut target: " & objFile.Target Wscript.Echo "File name: " & objFile.Description Next 当然,您不必费力地逐一浏览计算机中的所有快捷方式。假设您只想查找某个快捷方式对应的可执行文件。如果是这种情况,您可以使用类似下面的脚本:
strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From Win32_ShortcutFile WHERE FileName = 'Adobe Photoshop Elements
2.0'"
For Each objFile in colFiles
Wscript.Echo "Name: " & objFile.FileName Wscript.Echo "Shortcut target: " & objFile.Target Wscript.Echo "File name: " & objFile.Description Next 以下是另一个示例,它用于检查计算机上是否有引用 Microsoft Virtual PC 的快捷方式。请注意,按照 WMI
约定,在查询中使用文件路径时,必须在路径名中使用两个(而不是一个)\\
strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From Win32_ShortcutFile WHERE Target = " & _
"'C:\\Program Files\\Microsoft Virtual PC\\Virtual PC.exe'"
27
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. For Each objFile in colFiles
Wscript.Echo "Name: " & objFile.FileName Wscript.Echo "Shortcut target: " & objFile.Target Wscript.Echo "File name: " & objFile.Description Next 本文为您介绍了有关获取快捷方式信息的一些基础知识。有些人提出了有关创建和删除快捷方式的问题,我们很快就这些问题给予答复。

-------------------------------------------------------------------------------- 32 我如何对现有 Excel 电子表格进行更改并重新保存? 我如何对现有 Excel 电子表格进行更改并重新保存? 问:
嗨,Scripting Guy!我如何打开一个现有的 Excel 电子表格,向该电子表格添加一些其他信息,然后保存我的更改?每次调用另存为方法时,总弹出一个对话框,询问我是否要保存我的更改。 -- RW 答:
您好,RW。一般来说,您可以通过使用保存而不是另存为方法来避免出现该对话框。如果您打开一个现有的电子表格并对它进行一些更改,只调用保存方法即可;这样将直接保存您的文档而不显示确认对话框。例如,下面是一个示例脚本,该脚本打开文件 C:\Scripts\Test.xls,在单元格 A1 中写入当前日期和时间,保存该文件,然后退出: Set objExcel = CreateObject("Excel.Application" objExcel.Visible = True Set objWorkbook = "C:\Scripts\Test.xls" Set objWorksheet =
objWorkbook.Worksheets(1 objWorksheet.Cells(1, 1.Value = Now objWorkbook.Save( objExcel.Quit
在大多数情况下,应当采用此方法。不过,另存为方法提供的选项确实比保存方法多。如果您要对电子表格添加密码保护、创建文件的备份版本或以另一种格式保存,您将需要使另存为同样,假定您每天上午都运行一个脚本来获取一些数据并填充到一个全新电子表格的单元格中。您每天上午都想要将该文件保存为

C:\Scripts\Daily_report.xls。因为这是一个新的电子表格(请记住,您没有打开现有的 Daily_report.xls,所以您需要使用另存为方法。当您发出此命令时,将弹出一个对话框,告诉您已存在一个同名文件,询问您是否要替换该文件。
那么如何避免出现这些对话框呢?方法就是将“DisplayAlerts”属性(Excel Application 对象的一部分)设置为“FALSE”DisplayAlerts 属性禁止显示对话框和警告消息;Excel 将不允许您选择是执行甲操作、乙操作还是丙操作,它将自动为您选择默认操作。对于是否要覆盖现有文件,默认操作是。所以当 DisplayAlerts 设置为

False 时,将会保存修订过的工作表,而您不会再受到对话框的打扰。下面是一个示例脚本,该脚本先将 DisplayAlerts 设置为

FALSE,然后使用另存为方法保存更改:
Set objExcel = CreateObject("Excel.Application" objExcel.Visible = True
objExcel.DisplayAlerts = FALSE Set objWorkbook = "C:\Scripts\Test.xls" Set
objWorksheet = objWorkbook.Worksheets(1 objWorksheet.Cells(1, 1.Value = Now objWorkbook.SaveAs("C:\Scripts\Test.xls"
28
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. objExcel.Quit
另外,下面还有一个脚本,该脚本创建了一个新的工作表,也通过将 DisplayAlerts 设置为 FALSE 并使用另存为覆盖现有的工作表:
Set objExcel = CreateObject("Excel.Application" objExcel.Visible = True
objExcel.DisplayAlerts = FALSE Set objWorkbook = Set objWorksheet =
objWorkbook.Worksheets(1 objWorksheet.Cells(1, 1.Value = Now objWorkbook.SaveAs("C:\Scripts\Test.xls" objExcel.Quit

-------------------------------------------------------------------------------- 33 如何知道启动可执行文件时使用了哪些开关? 如何知道启动可执行文件时使用了哪些开关? 问:
嗨,Scripting Guy!如何知道启动可执行文件时使用了哪些命令行参数(如果有)? -- TO 答:
您好,TO。我们并不想在脚本编写界制造丑闻,好吧,我们不想在脚本编写界制造更多丑闻。不过,屏住气,我们要在此耍个小花招。这是第一次有人问这个问题,要回答此问题,我们先回顾一下几个月前曾有人提过的另一个问题的答案。 即:只要您运行 Windows XP Windows Server
2003,那么,是的,很容易就能说出启动可执行文件时使用了哪些命令行参数(如果有)那是因为在这两个版本的 Windows(非先前的版本)中,WMI

Win32_Process 包含一个名为“CommandLinethat”的属性,该属性提供用于启动可执行文件的完整命令行(包括开关)
例如,假设 Netstat.exe 正运行于计算机上,您想了解哪些命令行开关用于启动该程序。使用这个脚本可获得该信息:
strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2" Set colItems = objWMIService.ExecQuery _ ("Select * From Win32_Process Where Name =
'netstat.exe'" For Each objItem in colItems Wscript.Echo objItem.CommandLine Next
如您所见,这是一个很简单的小脚本:我们返回一个包含所有名为 Netstat.exe 的进程的集合,然后,我们回显其中每个进程的 CommandLine
属性。假定我们使用如下命令启动 Netstatnetstat.exe a 30在此情况下,如下所示是我们的脚本报告的 CommandLine 属性: netstat.exe a 30
正是您所期望它报告的内容。
关于 CommandLine 属性的有趣之处在于即使您并没有使用命令行,它也经常会提供有用的信息。例如,假设您有一个名为 C:\Scripts\Inventory.vbs
的脚本,并且您右键单击我的电脑中的文件,然后选择编辑。这样将在记事本(假设记事本是默认的脚本编辑器)中打开该脚本。以下是该记事本实例的 CommandLine 属性:
29
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. C:\WINDOWS\System32\Notepad.exe C:\scripts\inventory.vbs
换言之,我们不但知道记事本打开了,还知道哪个文件”(inventory.vbs
打开了。尽管许多不同的应用程序都会以这种相同的方式运行,出于某种原因,Microsoft Word Excel“不会如此运行。(但很有趣的是 PowerPoint 会如此运行。)使用 Word Excel 应用程序,可以获得启动程序的

CommandLine,但不能指示打开了哪个文档。而是得到一个如下的普通命令行字符串: "C:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE" /e 我们一定另找时间研究这个谜。
顺便说一下,如果机器长时间挂起,我们对该问题的回答是相同的(Win32_Process 类的 CommandLine 属性):如何了解计算机上正在运行哪些脚本?为此,查看任意 Wscript.exe CScript.exe 进程的 CommandLine
属性,CommandLine 将包含在某个脚本宿主之下正运行的脚本的名称。或者,以编程方式实现:
strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2" Set colItems = objWMIService.ExecQuery _ ("Select * From Win32_Process Where Name = 'wscript.exe' OR Name = ‘cscript.exe’"
For Each objItem in colItems Wscript.Echo objItem.CommandLine Next

-------------------------------------------------------------------------------- 34 如何更改我的电脑图标的标题? 如何更改我的电脑图标的标题? 问:
嗨,Scripting Guy!我不想让桌面上我的电脑图标显示为我的电脑,我希望用计算机名称来替代它。用脚本可以实现吗? -- TG 答:
您好,TG。很多人向我们提了这个问题;显然,其中许多人都发现将计算机名称放在桌面上很方便,用户很容易就可以知道他们登录的是哪台计算机。如果您希望自动更改我的电图标的标题,只需运行一个这样的脚本:
Const MY_COMPUTER = &H11& Set objNetwork = CreateObject("Wscript.Network" strComputer =
objNetwork.ComputerName Set objShell = CreateObject("Shell.Application" Set
objFolder = objShell.Namespace(MY_COMPUTER Set objFolderItem = objFolder.Self objFolderItem.Name = strComputer
该脚本开始时声明一个名为 MY_COMPUTER 的常量并为其赋值 &H11&;这是 Windows Shell
对象用于定位我的电脑的值。然后使用这两行代码确定本地计算机的名称并将其名称存储 strComputer 变量中:
Set objNetwork = CreateObject("Wscript.Network" strComputer = objNetwork.ComputerName
目前为止还好吧,对不对?下一步,创建 Shell Application 对象的实例,使用 Namespace 方法将其绑定到与我的电脑相应的特定文件夹。然后使用下面一行代码绑定到我的电脑30
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. FolderItem 对象:
Set objFolderItem = objFolder.Self
绑定到 FolderItem 之后,我们就可以访问文件夹属性,如文件夹名称。要想将我的电脑标题设置为计算机名称,仅需将名称属性设置为 strComputer 这一包含计算机名称的变量: objFolderItem.Name = strComputer
就这样,不仅桌面图标,还有开始菜单中我的电脑的链接名称都会更改。 如果您以后决定再将标题改回我的电脑,可以运行该脚本:
Const MY_COMPUTER = &H11& Set objShell = CreateObject("Shell.Application" Set objFolder =
objShell.Namespace(MY_COMPUTER Set objFolderItem = objFolder.Self objFolderItem.Name = "My Computer"
请记住,这不能更改您的计算机名称,它仅仅更改我的电脑特定文件夹的标题。重新命名计算机完全是另外一回事,我们将在别的时间讨论。您大概也注意到了,即使更改了我的电脑标题,如变为

atl-ws-01Shell Application 脚本仍然可以轻易找到我的电脑特定文件夹。这是因为脚本并不使用字符串值“My
Computer”来定位我的电脑,而是使用常量 &H11& 来定位特定文件夹。

-------------------------------------------------------------------------------- 35 我如何更改脚本的工作文件夹? 我如何更改脚本的工作文件夹? 问:
嗨,Scripting Guy!我的脚本需要有与脚本启动的应用程序相同的工作文件夹。我如何更改脚本的工作文件夹? -- JM 答:
您好,JM。要更改脚本的当前文件夹(或工作文件夹),只需设置 Wscript Shell “CurrentDirectory”Windows Script Host 5.6 CurrentDirectory
属性,因此我们今天将要介绍给您的脚本要求您运行该版本的 WSH)例如,下面这个演示脚本先回显脚本的当前目录,然后将当前目录更改为 C:\Windows,最后再次回显当前目录: Set objShell = CreateObject("Wscript.Shell" Wscript.Echo objShell.CurrentDirectory objShell.CurrentDirectory = "C:\Windows" Wscript.Echo objShell.CurrentDirectory 与您所期望的一样,在脚本的最后一行,“C:\Windows”被作为当前目录的名称来回显。 既然我们知道如何更改当前文件夹,那么我们所需要做的就是编写一个简单小脚本。该脚本先启动一个应用程序,然后更改当前目录,使其与该应用程序的工作文件夹相匹配。例如,此脚本启动记事本

(C:\Windows\System32\Notepad.exe通过分析 Notepad.exe 的路径确定所需的工作文件夹,然后将当前目录更改为 C:\Windows\System32
31
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Set objShell = CreateObject("Wscript.Shell" strApp = "C:\Windows\System32\Notepad.exe" arrPath = Split(strApp, "\" For i = 0 to Ubound(arrPath - 1 strAppPath = strAppPath & arrPath(i & "\" Next
objShell.CurrentDirectory = strAppPath Wscript.Echo objShell.CurrentDirectory objShell.Run(strApp 我们所做的只是将应用程序路径 (C:\Windows\System32\Notepad.exe 存储在名为 strApp 的变量中。然后我们使用

VBScript Split 函数将此路径拆分到一个数组中(使用 \ 作为分隔符);这样我们就有了一个包含这些元素的数组:
C: Windows System32 Notepad.exe 我们为什么需要一个包含这些元素的数组?正如您所看到的,前三个元素 加上两个 \’s – 构成了我们想要的路径:C:\Windows\System32。这样拆分路径,我们就可以通过提取前三项并丢弃可执行文件名 (Notepad.exe 来确定文件夹路径。这就是以下这行代码的作用,它使用数组中除最后一项以外的所有其他项重新构建路径:
For i = 0 to Ubound(arrPath - 1 strAppPath = strAppPath & arrPath(i & "\" Next 您可能感到奇怪,数组总是从第 0 项开始,这就是我们的 For-Next 循环从 0
开始的原因。反过来,“Ubound”属性表示数组中的最后一项。我们不想使用最后一项,我们只想到达倒数前二项。因此,“Ubound – 1”表示数组中的最后一项减去 1或倒数第二项。在此处显示的示例脚本中,存在以下等式: C: + \ + Windows + \ + System32 + \ 或者,C:\Windows\System32\(最后那个 \ 是多余的,没有任何作用,所以,我们尽可放心地删除它。
从这里我们将当前目录更改为 C:\Windows\System32;回显当前目录的值(只有这样您才能知道已经发生了更改);然后启动记事本。问题就解决了!

-------------------------------------------------------------------------------- 36 我如何共享远程计算机上的文件夹? 我如何共享远程计算机上的文件夹? 问:
嗨,Scripting Guy!我如何共享远程计算机上的文件夹? -- RS 答:
您好,RSWMI 带来的好处之一是:除了少数一些很不明显的例外情况外,在本地计算机上能够做到的任何32
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 事情也同样能够在远程计算机上做到。这是脚本与命令行工具相比体现出来的一大优点;多命令行工具(包括网络共享之类的工具)只能在本地计算机上运行。您要是想进行远程操作,通常,使用

WMI 脚本是唯一的方法。
那么,如何共享远程计算机上的文件夹呢?下面提供了一种方法:
Const FILE_SHARE = 0 Const MAXIMUM_CONNECTIONS = 25 strComputer = "atl-ws-01" Set objWMIService = GetObject _ ("winmgmts:\\" &
strComputer & "\root\cimv2"
Set objNewShare = objWMIService.Get("Win32_Share" errReturn = objNewShare.Create _ ("C:\Public", "PublicShare", FILE_SHARE, _
MAXIMUM_CONNECTIONS, "Public share for Fabrikam employees." 上述脚本将名为 atl-ws-01 的计算机上的文件夹 C:\Public 设置成了共享文件夹。该脚本首先设置一对常量。第一步,我们将值 0 分配给常量

FILE_SHARE(它用于说明我们正在创建的共享资源的类型);如果我们将此常量的值设置

48 MAXIMUM_CONNECTIONS 分配值

25该常量用于设置最大同时连接数。如果不限制同时连接的数量,我们根本不必使用此常量。我们在创建共享时保留此参数为空就行了。
连接到远程计算机上的 WMI 服务之后,再连接到 Win32_Share 类。此时,我们只需调用 Create 方法,传递以下五个参数: 参数 说明
“C:\Public”
要共享的文件夹的本地路径。 “PublicShare”
共享文件夹的共享名。
FILE_SHARE 要创建的共享的类型。
MAXIMUM_CONNECTIONS 能够同时连接到共享上的用户的最大数量。 “Fabrikam share for Fabrikam employees.” 可以为共享文件夹添加的说明。
这是关于该脚本的所有信息;运行该脚本,文件夹 C:\Public 将作为 PublicShare 共享。请注意,文件夹 C:\Public 必须已存在于计算机

atl-ws-01 上;Win32_Share Create 方法不能为您创建该文件夹。如果您不知道文件夹 C:\Public
是否存在,这里有一个快速检查方法:
strComputer = "atl-ws-01" Set objWMIService = GetObject _ ("winmgmts:\\" &
strComputer & "\root\cimv2" Set colFolders = objWMIService.ExecQuery _ ("Select * From Win32_Directory Where Name = 'C:\\Public'" Wscript.Echo colFolders.Count 此脚本回显位于计算机 atl-ws-01 上的名为

C:\Public(请注意,在查询自身中,必须将此文件夹指定为“C:\\Public”)的文件夹的数量。33
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 如果文件夹数等于 0,则 C:\Public
不存在。如果文件夹数等于 1,则该文件夹已存在。 顺便说一句,我们知道有很多人都想询问有关在共享文件夹上设置权限的问题。这些都可以使用脚本来实现,但过程稍复杂些,需要进行更详细的讨论,而本专栏文章已经不能再提供这些信息了。不过我们计划不久将发布大量介绍如何使用安全描述符的资料。

-------------------------------------------------------------------------------- 37 我如何返回 Internet Explorer 的下载控件和 Applet 的列表? 我如何返回 Internet Explorer 的下载控件和 Applet 的列表? 问:
嗨,Scripting Guy!要找出已为 Internet Explorer 下载了哪些程序,有没有简便的方法(这些项目在文件夹

C:\Windows\Downloaded Program Files 中)?我可以使用一个脚本获得可执行文件名和依存文件,但是我想获得它们显示在文件夹中的文件名。 -- AC 答:
AC您下 ActiveX Java 些项通常“Downloaded Program”文件夹中。您可以在

Windows 资源管理器中或从 Internet Explorer 中查看这些项目。(单击“Internet 选项,然后在常规选项卡上单击设置。在设置对话框中,单击查看对象

当您使用 Windows 资源管理器查看文件夹内容时,您会看到“MSN File Upload Control”类的友好名称。不过,如果您使用 dir
命令或使用 FileSystemObject 之类的脚本访问此文件夹,您就会看到“MsnUpld.cab”之类的可执行文件名。您希望能够使用脚本返回您在 Windows 资源管理器中看到的这些友好名称。
那么您该怎么做呢?当然了,您可以使用下面的这个脚本:
strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & _
"\root\cimv2\Applications\MicrosoftIE" Set colIESettings = objWMIService.ExecQuery _ ("Select * from MicrosoftIE_Object" For Each strIESetting in colIESettings Wscript.Echo "Code base: " & strIESetting.CodeBase Wscript.Echo "Program file: " & strIESetting.ProgramFile Wscript.Echo "Status: " & strIESetting.Status Wscript.Echo Next 此脚本依赖于类 MicrosoftIE_Object 和命名空间

root\cimv2\Applications\MicrosoftIE,据我们所知,这个类和这个命名空间都还未经过证明。但是,似乎这个脚本可以使用;运行此脚本,您将得到与以下内容类似的输出: Code base: .com/controls/FileUC/MsnUpld.cab Program file: MSN File Upload Control 34
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Status: Installed 正如您看到的那样,“ProgramFile”属性为您提供了与显示在“Downloaded Programs”文件夹中相同的友好名称。

-------------------------------------------------------------------------------- 38 我如何从剪贴板中抓取一个 URL 然后在浏览器中打开该 Web 站点? 我如何从剪贴板中抓取一个 URL 然后在浏览器中打开该 Web 站点? 问:
嗨,Scripting Guy!我如何从剪贴板中抓取一个 URL 然后在浏览器中打开该 Web 站点? -- CL 答:
您好,CL。这是很有趣的问题,或者我们应当说,这是两个很有趣的问题。因为您实际上问了两个问题。第一个问题很简单:我可以使用脚本打开特定的 Web
站点吗?您大概已经知道答案了,我可以大声地回答您,可以!下面是一个示例脚本,它将脚本中心 URL 存储在一个名为 strURL
的变量中。然后,此脚本会创建 WSH Shell 对象的一个实例,并使用 Run 方法来打开默认的 Web 浏览器并导航到指定的 URL strURL = “/scriptcenter/default.mspx”
Set objShell = CreateObject("Wscript.Shell" objShell.Run(strURL 第二个问题有点棘手:我可以使用脚本从剪贴板中抓取信息吗?这个问题的答案也是,尽管您必须通过后门程序到达剪贴板。

WSH VBScript 都不能与剪贴板进行交互:它们都不允许您将数据复制到剪贴板或从剪贴板粘贴数据。另一方面,Internet Explorer 却可以和剪贴板进行交互。(瞧,Internet Explorer 真是无所不能啊!)所以,就让 IE
来为我们做这项工作吧。如果您想从剪贴板抓取数据,您可以使用与以下代码类似的代码: Set objIE = CreateObject("InternetExplorer.Application" objIE.Navigate("about:blank" strURL = "text" objIE.Quit Wscript.Echo strURL 这里,我们所做的事情就是:创建 Internet Explorer 的一个实例,并在一个空白页中将其打开。请注意,您实际上并不能看到此 IE
实例,因为我们并没有将 Visible 属性设置为 TRUE。所有的事情都是在后台发生的。 然后,我们使用 clipboardData.GetData 方法来获取放置在剪贴板上的文本并将其存储在变 strURL 中;这也就是下面这行代码所做的工作:
strURL = "text" 我们关闭此 IE 实例 (objIE.Quit,然后回显我们从剪贴板检索出来的值。
请做以下尝试:将一些文本复制到剪贴板,然后运行该脚本。您应当会得到一个消息框,其中包含您刚才复制到剪贴板的文本。 现在就剩下一件事情要做:将这两半段脚本合在一起构成一个完整的脚本。下面这个脚本就可以从剪贴板中抓取一个 URL 然后在默认的 Web 浏览器中打开该 Web 站点:
Set objIE = CreateObject("InternetExplorer.Application"
35
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. objIE.Navigate("about:blank" strURL = "text" objIE.Quit Set objShell = CreateObject("Wscript.Shell" objShell.Run(strURL 这个脚本还不赖吧。它还有一个优点 它并不是只能用来打开 Web
站点。假定您的剪贴板上有一个文件路径,例如“C:\Scripts\ScriptLog.txt”。运行此脚本,则该文件将在记事本(或任何您设置为与 .txt
文件相关联的应用程序)中打开。如果您的剪贴板上有一个 .doc 文件的路径,则此脚本将 Microsoft Word
中打开该文档。它实际上是一个通用的文件打开脚本,而不仅仅是一个只能用于 Web 站点的打开脚本。

-------------------------------------------------------------------------------- 39 应该如何将输出保存到一个文本文件? 应该如何将输出保存到一个文本文件? 问:
嗨,Scripting Guy!有没有简单的办法可以将脚本输出保存到一个文本文件而不是显示在屏幕上?
-- KP, Ogden, UT 答:
你好,KP.如果您总是希望将脚本数据保存到一个文本文件,而不是在屏幕上显示,那么使 FileSystemObject
以及它的文件写入功能可能是比较好的选择。但是,如果您是 有时希望将数据保存到文本文件,有时希望在命令行窗口中显示数据。那么您是否能创建一个这样的多重用途脚本呢? 好的,您可以这么做,但是更为容易的方法是在启动脚本时使用命令行外壳的重定向字符。例如,您通常可以以下面这种方式启动脚本:
cscript myscript.vbs 脚本会运行,并且通过 Wscript.Echo 命令将输出显示在命令行窗口中。 不过,您也可以用如下方式启动脚本,使用“>”重定向命令:
cscript myscript.vbs > c:\scripts\log.txt 此时,屏幕上不会显示任何内容;所有的 Wscript.Echo 命令都会将输出写入到文本文件“C:\Scripts\Log.txt”中。
在前面的例子中,如果 C:\Scripts\Log.txt 已经存在,它将被脚本所生成的新信息所覆盖。如果您希望新的信息附加

C:\Scripts\Log.txt 的后面,可以使用以下命令启动脚本: cscript myscript.vbs >> c:\scripts\log.txt

-------------------------------------------------------------------------------- 40 可以使用脚本打印文本文件吗? 可以使用脚本打印文本文件吗? 问:
嗨,Scripting Guy!我在一个文件夹中有一大堆文本文件。有没有办法使用脚本打印这些文件呢?我知道可以通过脚本用 Microsoft Word
36
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 来打印文件,但是我没有在那台计算机上安装 Microsoft Word -- MA 答:
嗨,MA。不要告诉任何 Microsoft 公司的人这是我们说的,但是没有关系;只打印几个文本文件,并不需要 Microsoft Word。相反,可以使用 Shell外壳)对象——内置于操作系统中——来打印文本文件。而且,很棒的是:即便 Shell 对象没有 Print
方法,也可以打印这些文件。听起来很奇怪,但事实确是如此!
可以办到这一点,因为 Shell 对象有一个称为 InvokeVerbEx 的方法,可帮助执行右击 Windows
资源管理器中的文件所显示的任务。右击一个文本文件,查看弹出的上下文菜单。您会看到打开打印编辑剪切复制删除等项目。Shell
对象让您可以通过编程执行所有这些任务。实际上,这里有一个脚本可打印文件夹 C:\Logs 中的所有文件:
TargetFolder = "C:\Logs"
Set objShell = CreateObject("Shell.Application" Set objFolder = objShell.Namespace(TargetFolder Set colItems = objFolder.Items For Each objItem in colItems objItem.InvokeVerbEx("Print" Next 我们在此所做的就是连接到 C:\Logs 文件夹,然后获得在该文件夹中找到的所有项目。我们使用这行代码将这组文件保存在 colItems 变量中:
Set colItems = objFolder.Items 请注意,我们通过确定 C:\Logs 仅包含日志文件并且要打印每个文件,简化了这个例子。如果 C:\Logs 包含其他文件,而这些文件是我们不想打印的,那么就必须加入用以区分所要打印和不要打印的文件的代码。
在隐藏了 colItems 中的那组文件后,我们使用了一个 For Each 循环来循环集合中的所有项目。对于集合中的每个项目(也可以说是文件夹中的每个文件)我们使用了 InvokeVerbEx 方法,并告诉 InvokeVerbEx 我们要打印每个文件:
objItem.InvokeVerbEx("Print" 没错。运行该脚本,将逐一打印所有文件。
那么,倘若我们想执行别的任务,比方说编辑每个文件,又该怎么办呢?没问题;只要在上下文菜单中用恰当的参数名替换 Print 参数就行了: TargetFolder = "C:\Logs"
Set objShell = CreateObject("Shell.Application" Set objFolder = objShell.Namespace(TargetFolder Set colItems = objFolder.Items For Each objItem in colItems objItem.InvokeVerbEx("Edit" Next 得记住一件事:使用 InvokeVerbEx 时,脚本将执行您在 Windows 资源管理器中所看到的37
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 任务。例如,如果在 Windows
资源管理器中右击一个文件并选择删除会发生什么事情呢?没错:该文件不会自动被删除,将弹出一个对话框询问您是否确实要将该文件发送到回收站。这一点很重要,因为如果

Delete 命令传递给 InvokeVerbEx也会出现相同的对话框。这个脚本不会自动删除 C:\Logs 中的文件,而是对该文件夹中的每个文件弹出一个确认对话框: TargetFolder = "C:\Logs"
Set objShell = CreateObject("Shell.Application" Set objFolder = objShell.Namespace(TargetFolder Set colItems = objFolder.Items For Each objItem in colItems objItem.InvokeVerbEx("Delete" Next 也要记住,可能无法使用上下文菜单中的所有选项。有关如何确定哪些选项可用哪些不可用的更多信息,请参见Microsoft Windows 2000 脚本指南.

-------------------------------------------------------------------------------- 41 如何更改用户密码? 如何更改用户密码? 问:
嗨,Scripting Guy!如何使用脚本更改用户密码? -- GO 答:
嗨,GO。您没有说清楚是要更改本地用户的密码还是更改 Active Directory
用户的密码。但这也没关系:过程是一样的,等一会我们会告诉您怎么做这两件事。这就像是将两篇嗨,Scripting Guy 专栏合而为一了。
无论是删除本地用户密码还是删除 Active Directory 用户密码,您都需要执行两个步骤。首先您需要绑定到这个问题所涉及的用户帐户,然后使用 ADSI
SetPassword 方法为这个用户分配一个新密码。情况就是这样了:您有两个步骤要做。 为了验证上述说法,我们先从更改本地用户密码开始。在以下脚本中,我们绑定到 atl-ws-01 计算机上的 kenmyer 用户帐户,并为 Ken 分配密码 i5a2sj*!
Set objUser = GetObject(""
objUser.SetPassword("i5A2sj*!" 以下是整个脚本:首先绑定到这个用户帐户,接着调用 SetPassword 方法,然后将用户的新密码传递给

SetPassword。这个方法唯一需要注意的就是提供程序名称的格式。它必须是 WinNT,并且 W NT 必须大写。如果使用任何其他格式(例如 winnt,则脚本就会失败。对于 VBScript 来说,大小写通常无关紧要,这是其中大小写比较重要的一次。除此以外,就没有什么可说的了。
当然,您可能在想:哦,这帮家伙从本地用户脚本开始说起,这是因为本地用户帐户相对 Active Directory
用户帐户来说比较简单。等着瞧吧,看你们如何更改 Active Directory 用户帐户的密码。好吧,不用等了,以下脚本可用于更改 fabrikam.com
38
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 域中 kenmyer 用户帐户的密码:
Set objUser = GetObject(",ou=Finance,dc=fabrikam,dc=com" objUser.SetPassword("i5A2sj*!"
没错:它和更改本地用户密码的脚本非常相似。唯一的不同是我们使用 LDAP 提供程序来绑定到用户帐户(LDAP 提供程序用于与 Active Directory
情况打交道, WinNT 提供程序则用于本地帐户和 Windows NT 4.0 域的情况)当然了,取决于帐户存储在本地或 Active Directory
中,指向实际帐户的路径也会有所不同。但除此以外,这两个脚本是完全相同的。
我们想要提醒您的是,这段脚本可用于更改任何用户帐户,包括本地 Administrator 帐户。只需将 kenmyer 替换为 Administrator 即可:
Set objUser = GetObject(""
objUser.SetPassword("i5A2sj*!" 事实上,既然说到这里,我们干脆将三个专栏的内容合而为一好了。我们经常被问到的一个问题就是:如何更改一个 OU 中所有计算机的本地 Administrator 密码?好吧,以下就是答案:
Set objOU = GetObject(", DC=fabrikam, DC=com" objOU.Filter = Array("Computer" For Each objItem in objOU
strComputer = objItem.CN Set objUser = GetObject("" & strComputer & "/Administrator" objUser.SetPassword("i5A2sj*!" Next 那么,在这个 脚本中我们做了什么呢?哦,我们首先绑定到 fabrikam.com 中的 Finance OU。然后,我们对所得到的集合应用一个筛选器,以便确保只处理计算机帐户。应用筛选器后,我们对计算机帐户集合运行循环。我们得到第一台计算机的 CN(实质上是 NetBIOS 名),然后将这个名称存储在变量 strComputer 中。然后我们连接到这台计算机上 Administrator
帐户,并更改密码。这个脚本会不断循环,并对集合中的其他计算机重复上述过程,直到它 OU 中的每台计算机都执行了上述过程。 我们知道这很简单。但我们不会告诉您的老板它有多么容易。当您告诉他们您找到一个方法可以自动更改 OU 中所有计算机上的 Administrator
密码时,让他或她认为您是个天才好了。实际上只需要几行简单的代码就可以搞定,不过我们当然会保密。(相信我们:我们也不会把这个秘密告诉我们老板的! 42 如何删除某个特定日期之前的所有文件? 如何删除某个特定日期之前的所有文件? 问:
嗨,Scripting Guy!我想得到一个脚本,它可以在计算机上搜索某个特定日期之前的所有文件,然后自动将它们删除。能办到吗? -- GM 答:
嗨,GM。能否编写一个可在计算机上搜索并删除所有旧文件的脚本?当然可以。是否应该编写一个可在计算机上搜索并删除所有旧文件的脚本?这是不一样的问题,我们将在稍后做出解答。
39
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 让我们从代码本身说起。这里有一个代码,可以搜索计算机上所有在 2003 11 2 之前创建的文件,然后回显每个文件的名称: strDate = "000000.000000+000" strComputer = "." Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From CIM_DataFile Where CreationDate < '" & strDate & "'" For Each objFile in colFiles Wscript.Echo objFile.Name Next 我们知道您正在想什么:该脚本怎么知道我们设定的目标日期是 2003 11 2 日?毕竟,2003 11 2
日这个日期并没有显示在此脚本的任何地方。
000000.000000+000——指派给 strDate
变量的值——代表 2003 11 2 日。该日期之所以看起来比较怪异,是因为 WMI 使用了 UTC(通用时间坐标)格式。在 UTC 格式中,前四位数

(2003 代表年份;接下来的两位数 (11 代表月份;而再接下来的两位数 (02 代表日期。换句话说, 相当于 11/02/2003
顺便说一下,之后的六位数代表小时、分钟和秒(采用 24 小时的格式);我们将这些数字保留为 0,因为我们不担心具体的时间(即我们不是查找在 2003 11 2 日下午 2:37 之前创建的文件)小数点后面的六位数代表毫秒;应该总将其保留为零。最后,+000
表示与格林威治时间的对比时差。这一时差使您可以协调位于不同时区的计算机间的日期和时间,如今我们不会再担心这方面的问题了。我们也将该对比时差保留为 +000,以告知计算机按当地时间运行。
那么,我们必须以该 UTC 格式传递日期和时间吗?相同。而且,在 Windows 2000(以及 Windows
的以前版本)中,必须像我们刚才所做的那样键入该数据。但是,在 Windows XP Windows 2003 中,有一个新的 WMI
对象——SWbemDateTime,允许用户键入传统的日期(比如:11/2/2003,然后自动将该日期转化为 UTC 格式。
Scripting Guys 公告。想要了解有关 SWbemDateTime 的详细信息吗?那么请留意将于明年 1 月份推出的 Scripting Week 2
strDate WMI CreationDate(创建日期)早于 11/2/2003
的所有文件。它只要找到一个文件,就会回显一个文件名。
当然,您要求脚本删除这些旧文件。如果这就是您想要得到的,那么只要使用这行代码替换 Wscript.Echo objFile.Name 一行就行了:
objFile.Delete 为何我们没有把这行代码加入脚本?我们想让您在实际运行该脚本之前,思考一下。假设您的计算机上有一个磁盘驱动器 (C。难道您真的想运行脚本来删除在 2003

40
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 11 2 日之前创建的所有文件吗?毕竟,这样会删除大部分操作系统和应用程序文件。般来说,您不会这么做的。
这意味着在搜索文件时,您应该更聪明一点。例如,您的计算机可能有两个驱动器:驱动器 C 上存有操作系统和所有应用程序,而驱动器 D
上存有所有文档。这时,您可以编写 WQL 查询,只搜索驱动器 D 上于 2003 11 2 日之前创建的文件:
strDate = "000000.000000+000" strComputer = "."
Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From CIM_DataFile Where CreationDate < '" & strDate & "'" & _
" AND Drive = 'D:'" For Each objFile in colFiles Wscript.Echo objFile.Name Next 也许,您只关心那些已过时的旧的 Word 文档。这种情况下,只要搜索 2003 11 2 之前创建的带有 doc 文件扩展名的文件就行了: strDate = "000000.000000+000" strComputer = "." Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From CIM_DataFile Where CreationDate < '" & strDate & "'" & _ " AND Extension = 'doc'" For Each objFile in colFiles Wscript.Echo objFile.Name Next 有许多其他的方法可以精确设定搜索;有关详细信息,请参见“Microsoft Windows 2000 本编写指南中的文件和文件夹 一章。
顺便说一下,许多人都问过能否根据文件最后的修改时间进行搜索。当然可以;采用前面所示的脚本之一,删去 CreationDate,并写入 LastModified。换句话说: strDate = "000000.000000+000" strComputer = "." Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2" Set colFiles = objWMIService.ExecQuery _ ("Select * From CIM_DataFile Where LastModified < '" & strDate & "'" For Each objFile in colFiles Wscript.Echo objFile.Name Next

--------------------------------------------------------------------------------
41
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. 43 如何从一个脚本向另一个脚本发送数据? 如何从一个脚本向另一个脚本发送数据? 问:
嗨,Scripting Guy!前不久您向我们介绍了如何使用 InputBox
函数来提示用户输入一个值,然后我们就可以在脚本中使用这个值。我想知道的是,是否可以获取这个值并在另一个脚本中使用这个值? -- JW 答:
嗨,JW。我们猜想,您显然需要一个除了具有其他功能以外、还可以提示用户输入数据的脚本。然后您可能需要启动第二个脚本,并使第二个脚本可以访问用户在第一个脚本中输入的数据。并且,您当然想知道是否可以实现上述目的。 答案就是(这个问题困扰您很久了,对吧?):有几分可能。假设您启动了脚本 A,并且输入了一个值。那么,您现在可以单独启动脚本 B,并通过某种方式让脚本 B
访问脚本 A,然后检索这个值吗?不能。那看来更像是魔术,而不是编写脚本。但是,您可以这么做:启动脚本 A,让用户输入数据。然后使用脚本 A 来启动脚本

B;此时,您就可以将数据传给脚本 B。通过这种方式,脚本 B 就可以访问用户输入的任何信息。
为了更好地解释这点,让我们来看一个简单的示例。我们需要两个脚本:脚本 A 和脚本 B然后我们启动脚本 A,这个脚本会提示用户输入一个数值。然后,脚本 A
启动脚本 B并且在它启动 B 的同时,它会将用户输入的数值传递给脚本 B。这样,脚本 B 就会获取这个数值,并确定出数值的平方根,然后报告结果。
注意:象这种情况,使用一个脚本来获取用户输入和计算平方根不是更简单吗?是的。但这只是一个用来说明如何从一个脚本向另一个脚本发送数据的示例;我们并不是说您在现实中应该这么使用脚本。
以下就是脚本 A。注意,这个脚本首先创建一个 WSH Shell 对象实例;我们会在稍候使用这个对象来启动脚本 B(我们将它命名为 output.vbs;将脚本 A 命名为 input.vbs。然后我们使用 InputBox 函数来请求用户输入一个数值: Set objShell = CreateObject("Wscript.Shell" intValue = InputBox("Please enter a number:" strCommandLine = "output.vbs " & intValue objShell.Run(strCommandLine 请注意我们在用户输入数值后做了什么(假定用户输入的数值为 2。我们使用了以下代码行:
strCommandLine = "output.vbs " & intValue 这行代码构建了一个启动脚本 B 的命令。假设您想要启动脚本 B 并将 2 作为命令行参数传递给它。为此,您需要从命令提示符处输入以下内容:
output.vbs 2 我们所作的就是生成一个包含以下两个项目的字符串:我们所启动的脚本名称 (output.vbs 以及我们所传递的命令行参数

(2。当然,事实上我们并不知道这个参数是 2;我们只是将用户输入的内容传递出去而已。因此我们使用变量 intValue 来代替这个参数。请注意,这个

output.vbs(加上一个空格)是包含在双引号里面的,而 intValue 则位于这些双引号外面。为什么 intValue
不包含在双引号里面呢?很简单;因为接着我们将构建以下命令,这个命令不会传递数值
2
42
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. (或是用户输入的任何数值),而是会传递字符串值 intValue
output.vbs intValue 这并不是我们想要的。
构建这个命令行之后,我们使用 Run 方法来启动脚本 B并将用户输入的值作为命令行参数传递出去。
那么脚本 B 应该是什么样的呢?好吧,它看起来类似如下: intValue =
intSquareRoot = Sqr(intValue Msgbox "The square root of " & intValue & _ " is " & intSquareRoot & "." 如您所见,我们将第一个(在上述示例中,也是唯一的一个)命令行参数分配给变量 intValue然后,我们使用 Sqr
函数来确定这个值的平方根。最后,我们显示答案。上述示例中,我们使用 VBScript Msgbox 函数(对应于

Wscript.Echo)将答案显示在消息框中。如果我们将 Wscript.Echo Cscript
用作您的默认脚本宿主,那么稍候就会有一个命令行窗口打开,并在屏幕上显示答案,然后这个窗口就会很快消失,以至于您甚至看不清答案。当然,这不是我们想要的。但无论脚本宿主是哪个,Msgbox
函数总是会将数据显示在消息框中,因此我们使用 Msgbox 以下还是一个简单的示例,但是您可以轻松对它加以扩展,以便从脚本 A 向脚本 B 发送 2 个、3 个、4
个或是任意数量的命令行参数。这的确是一个很有用的办法,尽管在理论上如果发送太多数据的话,您可能会受到命令字符串长度的限制。在这种情况下,最好的办法就是让脚本 A 将数据保存到文本文件中,然后让脚本 B 从这个文本文件中读取数据。
您还需要注意脚本发送的命令行参数中是否包含空格。例如,如果您希望将名称 Ken Myer 发送给脚本 B。这个命令不会起作用;因为它会发送两个参数(Ken Myer,而不是 Ken Myer 这一个参数:
output.vbs Ken Myer 由于 Ken Myer 之间存在空格(WSH 使用空格来分隔两个参数),因此您需要将 Ken Myer 放到一个双引号中,类似如下:
output.vbs "Ken Myer" 相应地,这意味着您构建的命令字符串也必须包含双引号。以下代码可实现这个目的,有关更多信息,请参阅以下存档嗨,Scripting Guy!专栏:
strCommandLine = "output.vbs " & chr(34 & strValue & chr(34 上述示例中,每个 chr(34 实例都插入了一个双引号。因此,我们必须以 output.vbs + " + Ken Myer + " 结尾,即: output.vbs "Ken Myer"

-------------------------------------------------------------------------------- 44 更改正在运行的进程的优先级 更改正在运行的进程的优先级 描述
将正在运行的 Notepad.exe 的实例的优先级从 Normal 更改为 Above Normal。需要 Windows XP Windows .NET
43
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. Server 脚本代码
Const ABOVE_NORMAL = 32768 strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colProcesses = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name = 'Notepad.exe'" For Each objProcess in colProcesses objProcess.SetPriority(ABOVE_NORMAL Next

-------------------------------------------------------------------------------- 45 确定进程所有权 确定进程所有权 描述
报告可以在其下运行计算机上的每个进程的帐户名。 脚本代码
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process" For Each objProcess in colProcessList colProperties = objProcess.GetOwner(strNameOfUser,strUserDomain Wscript.Echo "Process " & objProcess.Name & " is owned by " _ & strUserDomain & "\" & strNameOfUser & "." Next

-------------------------------------------------------------------------------- 46 终止进程 终止进程 描述
终止正在运行的 Notepad.exe 的任何实例。 脚本代码
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name = 'Notepad.exe'" For Each objProcess in colProcessList objProcess.Terminate( Next

44
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. -------------------------------------------------------------------------------- 47 阻止进程运行 阻止进程运行 描述
Notepad.exe 的任何实例一创建好就立即将其终止的临时性事件消费程序。 脚本代码
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colMonitoredProcesses = objWMIService. _
ExecNotificationQuery("select * from __instancecreationevent " _ & " within 1 where TargetInstance isa 'Win32_Process'" i = 0 Do While i = 0 Set objLatestProcess = colMonitoredProcesses.NextEvent If = "notepad.exe" Then

End If Loop

-------------------------------------------------------------------------------- 48 线程监视 线程监视
更新日期: 20030912 描述信息
针对计算机上运行的所有进程返回线程及线程状态列表。 脚本代码
Set objDictionary = CreateObject("Scripting.Dictionary" strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set colProcesses = objWMIService.ExecQuery _ ("Select * from Win32_Process" For each objProcess in colProcesses
objDictionary.Add objProcess.ProcessID, objProcess.Name
Next Set colThreads = objWMIService.ExecQuery _ ("Select * from Win32_Thread" For each objThread in colThreads
intProcessID = CInt(objThread.ProcessHandle strProcessName = objDictionary.Item(intProcessID
Wscript.Echo strProcessName & VbTab & objThread.ProcessHandle & _ VbTab & objThread.Handle & VbTab & objThread.ThreadState Next
45
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

-------------------------------------------------------------------------------- 49 在隐藏窗口中创建进程 在隐藏窗口中创建进程 描述
在本地计算机中(但是在隐藏窗口中)启动 Notepad.exe 脚本代码
Const HIDDEN_WINDOW = 12 strComputer = "."
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set objStartup = objWMIService.Get("Win32_ProcessStartup" Set objConfig = objStartup.SpawnInstance_ objConfig.ShowWindow = HIDDEN_WINDOW Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process" errReturn = objProcess.Create("Notepad.exe", null, objConfig, intProcessID

-------------------------------------------------------------------------------- 50 在远程计算机上创建进程 在远程计算机上创建进程 描述
在远程计算机上启动 Notepad.exe。在 Windows XP .NET Server 中,Notepad 将运行在隐藏窗口中。 脚本代码
strComputer = "webserver"
Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer &
"\root\cimv2:Win32_Process" Error = objWMIService.Create("notepad.exe", null, null, intProcessID If Error = 0 Then Wscript.Echo "Notepad was started with a process ID of " _ & intProcessID & "." Else Wscript.Echo "Notepad could not be started due to error " & _ Error & "." End If

-------------------------------------------------------------------------------- 51 创建具有更高优先级的进程 创建具有更高优先级的进程 描述
启动具有 Above Normal 优先级的 Notepad.exe 脚本代码
Const ABOVE_NORMAL = 32768
46
文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持. strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" Set objStartup = objWMIService.Get("Win32_ProcessStartup" Set objConfig = objStartup.SpawnInstance_ objConfig.PriorityClass = ABOVE_NORMAL Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process" objProcess.Create "Notepad.exe", Null, objConfig, intProcessID

47

本文来源:https://www.2haoxitong.net/k/doc/30a4035d7ed184254b35eefdc8d376eeafaa1757.html

《VBS经典代码大全.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式