选择离开也是一种深爱:使用脚本程序管理Windows网络

来源:百度文库 编辑:中财网 时间:2024/04/28 00:10:26
使用脚本程序管理Windows网络
━━━━━━━━━━━━━━━━━━━━━━━━━━
文章来源:http://www.pcjx.com/Windows/netg/217380.html

  如何能够使用脚本去自动化日常管理任务,可以简化管理员的日常工作。但为什么学习写脚本呢?不是已经有很多网站,如Microsoft‘s Script Center Script Repository,可以下载大量的满足需求的脚本吗?没错,有一定道理。这些脚本的确是很好用,但通常你需要对它们进行定制以满足自己的要求或自己环境的特殊要求。又有时你希望自己可以对脚本进行某些修改,以完成与脚本作者解决问题的方法不一样的功能,比如将几个脚本整合成一个大的脚本或者将一个脚本的输出作为另一个脚本的输入。或者你想修改其中的一个脚本,这样你就可以用来处理用户的实时输入。或者你想将一个脚本修改后作为启动脚本或登录脚本使用。又或者你想通过修改一个脚本,使它对一个远程计算机上产生作用等等。

  使用脚本程序管理Windows网络 第一部分:基础

  从WindowsNetworking.com学习如何自动化日常管理任务并根据这个来自于的技巧管理你的网络。

一个流行的关于教授人知识的谚语:

“授人以鱼,不如授人以渔。”

的确如此。而在忙碌的IT世界里,这也适用于脚本化管理:

“给人一个有用的脚本,不如教他自己写脚本。”

如何能够使用脚本去自动化日常管理任务,可以简化管理员的日常工作。但为什么学习写脚本呢?不是已经有很多网站,如Microsoft’s Script Center Script Repository,可以下载大量的满足需求的脚本吗?没错,有一定道理。这些脚本的确是很好用,但通常你需要对它们进行定制以满足自己的要求或自己环境的特殊要求。又有时你希望自己可以对脚本进行某些修改,以完成与脚本作者解决问题的方法不一样的功能,比如将几个脚本整合成一个大的脚本或者将一个脚本的输出作为另一个脚本的输入。或者你想修改其中的一个脚本,这样你就可以用来处理用户的实时输入。或者你想将一个脚本修改后作为启动脚本或登录脚本使用。又或者你想通过修改一个脚本,使它对一个远程计算机上产生作用等等。

如果你想完成上面提到的任何一个修改,你必须学会了Windows脚本编写的基础知识。如果你开始进行学习的话,你会惊奇地发现这并不是一件很难的事,而这正是这篇文章所要阐述的问题。你将从Windows脚本编写基础开始,逐渐深化理解如何为Windows网络编写不同方面的脚本。最后,你将能够为你所需要自动化的任务编写脚本,从而简化你的管理工作。而且你将不仅能够从零开始编写脚本,也能够定制你从各种来源下载的公用的脚本。我也将同时告诉你各种可以帮助你学习Windows脚本编写的资源,并向你介绍一些非常有用的脚本编写工具。

编写TCP/IP设置脚本

大多数管理员都使用VBScript来编写Windows管理脚本。VBScript不仅仅是一个强大的编程语言,它的语法非常容易学习。VBScript 也能与Windows Management Instrumentation (WMI)和Active Directory Services Interfaces (ADSI)一起使用,编写关于Windows系统或基于Active Directory的网络的任何方面的脚本。我们将从使用VBScript和WMI去完成一些有用的工作开始学习Windows脚本编写:修改一个网络适配器的IP地址。

为什么会需要修改网络适器IP地址呢?是这样的,我使用许多的Virtual Server和Virtual PC来配置测试环境,然后我常常发现我必须将一个运行Windows Server 2003的虚拟机(VM)从一个虚拟网络移到另一个网络,以便可以进行其他的测试。这就意味着我需要修改服务器的IP地址(可能也要修改默认网关)。我知道我们可以从“控制面板”上打开“网络连接”,右击“本地连接”,然后选择“属性”,在“常规”标签中选择“Internet Protocol (TCP/IP)”,输入IP地址并点击2次“OK”。这么多的动作很费时间——不是吗?哦,没错,我还可以打开命令提示符然后使用Netsh命令完成配置,但Netsh有太多不同的上下文、命令和参数以致我需要一次又次地看Netsh的帮助文档才能顺利完成配置。

但我们这里真正要学的如何编写脚本完成配置,所以让看怎么用VBScript和WMI修改一个机器的IP地址。这包括学习一些特定的概念和方法包括:对象、方法、属性、命名空间等。

首先,我们在本地计算机运行脚本:

strComputer = "."

这里str-前缀表示strComputer是一个字符串型的变量,而句号是一个指向本地计算机的通配符,作为WMI命名空间的开始位置。什么是一个WMI命名空间?它是一个分层次的不同类型的用于管理Windows计算机不同方面的对象集合。比如,其中有一个根命名空间,根下面是一些这样的命名空间,包括SECURITY,perfmon,CIMV2等等。大多有用的WMI类可以在root\cimv2命名空间下找到,在我们操作这些类之前我们需要将其实例化成对象。然后我们可以查看这些对象的属性和通过调用它们的方法来操作它们。

简单的概念介绍

类、对象、属性、方法——这都是什么?这里有个类比的例子可以帮助理解:MicrowaveOven(微波炉)类。换句话说,MicrowaveOven类是所有可能的微波炉(不局限于任意一个微波炉)的抽象集合。这个类可能有以下的属性:Color(颜色)、CubicInches(立方尺寸)、HasTurntable(是否有转盘)等等。属性是一个类的特性。换句话说,微波炉有固定的颜色、一个用立方英寸表示的内部尺寸,他们可以有一个转盘或者没有,等等。

MicrowaveOven类也有方法。方法是类可以作的动作或你可以对类做的动作。对于这个特定的类,可能有这样一些方法:SetCookingTime、SetPowerLevel、Reset等。通常情况下调用一个方法时你需要传入一个参数给方法。比如,调用SetCookingTime方法时我们可能需要定义一个用秒表示的CookingTime变量,然后将这个参数传递给这个类的特定的一个实例的SetCookingTime方法(一个实际的、现实存在的微波炉——不是抽象类)。在WMI VBScript是你可以这样做:

intCookingTime = 120
errSetCookingTime = objMicrowave.SetCookingTime(intCookingTime)

但是Microwave的对象(objMicrowave)又是从哪里来的呢?我们还没创建它,所以我们用Set命令和createObject方法创建它:

Set objMicrowave = createObject("MicrowaveOven")

实际上,有些吹毛求疵地但更准确地说,objMicrowave不是MicrowaveOven的一个对象,而是一个MicrowaveOven类的一个对象的引用。但为了简单起见,我们现在就把它当作MicrowaveOven类的一个对象看待。

我们需要添加一个strColor变量,这样我们可以设置我们的微波炉的颜色为Green(绿色),我的脚本程序变成这样(包括了一些说明性注释):

strColor = "Green" ’specifies color
intCookingTime = 120 ’specifies cooking time in seconds
Set objMicrowave = createObject("MicrowaveOven") ’creates the instance of the object
errSetCookingTime = objMicrowave.SetCookingTime(intCookingTime) ’calls a method to set the cooking time and saves resulting error code
objMicrowave.Color = strColor ’sets the value of the Color property

这越来越有意思了,不是吗?

回到脚本

这是我们使用WMI去访问机器的TCP/IP配置所需要去做的:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

通过定义一个objWMIService对象并将GetObject方法的返回值赋给这个变量,这样就可以连接到本地计算机的root\cimv2命名空间了。一旦连接上了这个命名空间,我们就可以用下面的语句从中收集需要的信息:

Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")")

这些语句到底做了什么?首先,你可以看到一个我们在之前的语句中就已经实例化好的objWMIService对象。这个对象之后是execQuery,它可能是一个属性或方法(只有object.property或object.method这2个格式),这里我们可以根据字面意思猜测它是一个方法,即“执行一个查询”。execQuery是通过传递一个参数而被调用的,这个参数是一个SQL语句(select),这个语句返回一个包含机器上的所有(*号)绑定和激活了TCP/IP的网络配置器配置集合。然后这个方法返回的集合被赋给变量colNetAdapters,它表示了机器上的所有网络配置器的集合。

我们可以对这个集合做什么呢?对于这样一个集合,我们必须使用For Each…Next来循环遍历它:

For Each objNetAdapter in colNetAdapters
’ do something to each network adapter’s configuration
Next

我们必须得用这种方式来循环遍历它,即使集合里只有一个对象。

既然我们是想要做是修改网络适配器的IP地址,就让我们先定义一些变量吧:

arrIPAddress = Array("172.16.11.99")
arrSubnetMask = Array("255.255.255.0")

需要注意的是定义新IP和子网掩码的变量必须是数组变量。我们是怎么确定这一点的?这是因为,首先Windows计算机可能有超过1个的IP地址、默认网关等。所以为何不用数组变量来表示所有的IP设置以保持一致性呢?其次,如果我们在MSDN的WMI参考手册上查看一下Win32_NetworkAdapterConfiguration类,我们会发现它实际上是出也这样使用的。我们将在后面的文章中对它作仔细探究,这里暂不作更详细的介绍。

最后,Win32_NetworkAdapterConfiguration类的EnableStatic方法去将我们机器上的网络适配器的IP地址和默认网关修改成我们在数组变量定义的新值。我们是这样做的:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

这里的err-变量是作为存储方法执行后返回的错误码使用的。

将所有脚本整合在一起

让我们将所有的脚本整合在一些看看:

strComputer = "."
arrIPAddress = Array("172.16.11.99")
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

就是这些了——还没有变量定义、错误处理、使用输入和验证输出。我们将在下一篇文章中介绍如何添加这部分脚本,但先让我看看它是否正常工作。我们先保存脚本(要保证记事本的自动换行是关闭的)为“ChangeIPAddress.vbs”,然后将其拷贝到静态IP为172.16.11.45的服务器的桌面上。然后,以管理员身份登录,打开命令提示符,转变目录到桌面,然后使用命令行宿主Cscript.exe执行脚本。结果是这样的:

C:\Documents and Settings\Administrator\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
IP Address. . . . . . . . . . . . : 172.16.11.45
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 172.16.11.1
C:\Documents and Settings\Administrator.DC-1\Desktop>cscript ChangeIPAddress.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\Documents and Settings\Administrator\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
IP Address. . . . . . . . . . . . : 172.16.11.99
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 172.16.11.1

没错,它能正常工作。我们在执行第二个ipconfig命令可以看到,机器的IP地址已经成功地从.45修改为.49。

关于作者:

Mitch Tulloch是一个作家、培训师和Windows服务器操作系统、IIS管理、网络故障修复和安全方面的专业顾问。他已经写了15本书,其中包括:Microsoft Encyclopedia of Networking (Microsoft Press),Microsoft Encyclopedia of Security (Microsoft Press),Windows Server Hacks (O’Reilly),Windows Server 2003 in a Nutshell (O’Reilly),Windows 2000 Administration in a Nutshell (O’Reilly),and IIS 6 Administration (Osborne/McGraw-Hill)。Mitch居住在加拿大的Winnipeg,你可以他的网站www.mtit.com查到更多关于他的书的信息。

 [2] [3] [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

  使用脚本程序管理Windows网络 第二部分:脚本修订

  在使用脚本程序管理不同方面的Windows网络的系列文章中,作者Mitch Tulloch接下来会介绍“整理”。“整理”是用于修改网络适配器的IP地址的脚本程序的一个简单的步骤。这个技巧之前已经发布在WindowsNetworking.com。

第一篇文章《使用脚本程序管理Windows网络——基础》介绍了一些基本的脚本编写概念,如对象、方法和属性,文章写作的目的是编写一个简单的修改网络适配器IP地址的脚本。这里我们将第一个脚本再列出,也就是ChangeIPAddress.vbs:

strComputer = "."
arrIPAddress = Array("172.16.11.99")
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration")
For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

当我在我的Windows服务器上执行这个脚本时,它成功地把机器的IP地址从.45修改成.99,这已经从我们在脚本执行前后运行ipconfig命令的结果可以看出。到此为止,一切都进展很好。

但不幸的是,虽然上面的脚本已经可以工作了,但是这个脚本还算不上是一个好的脚本程序,它还缺少一些重要的东西,如变量定义、错误处理、使用输入和验证输出等。所以让我们通过添加这些有用的元素来“整理”我们的这个脚本,同时在这个过程中我们将学习更多的Windows脚本编写的基础知识。

变量定义

为了整理我们的脚本,我们将做的第一件事就是定义一些我们正在使用的变量。虽然VBScript可以让我们简单地在一个使用变量的语句中隐式地定义变量,但在脚本的开关显式上声明变量一直都是很好的做法。声明一个变量会告诉VBScript变量的存在,这样VBScript可以为它分配必要的内存。为什么显式地声明变量是好的做法呢?是这样的,在一个很长的脚本程序中,你很可能会出现一两个拼写错误,这样如果你输入了错误的变量名称,你的脚本就可能会与预想的结果不一样。但如果你在脚本的开关就显式地声明了变量,那么之后的脚本中任意隐式声明的变量(拼写错误造成的)都会导致一个运行时错误,这样这些错误就可以帮助你识别出你的拼写错误从而排除脚本的错误。

为了让VBScript意识到你正在显式地声明你的脚本中的所有的变量,可以将以下的语句添加到你的脚本的开头:

Option Explicit

如果你在我们的ChangeIPAddress.vbs脚本的开头添加了这个语句后,从命令提示符运行这个脚本,你可以得到下面的结果:

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\Documents and Settings\Administrator.DC-1\Desktop\ChangeIPAddress.vbs(2, 1) Microsoft VBScript runtime error: Variable is undefined: ’strComputer’

VBScript在这里告诉我们(或者是说用于运行VBScript脚本的Windows Script Host的脚本引擎告诉我们)的是在我们的脚本的第2行有一个错误。第2行是什么呢?它是:

strComputer = "."

为什么这会产生一个运行时错误呢?因为我们正在给一个我们还没有声明的字符串的变量(strComputer)赋值。所以让我们现在为每一个我们在脚本中使用的变量增加声明:

Option Explicit
Dim objWMIService
Dim objNetAdapter
Dim strComputer
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
strComputer = "."
arrIPAddress = Array("172.16.11.93")
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

记住如果你使用了Option Explicit,那么你必须声明脚本程序中所有的变量,包括对象、字符串、数组、集合、错误代码变量等。这看起来似乎会增加许多麻烦,但相信我,一旦你的脚本增加上几页的长度后,它会对你排除越来越多的运行错误很有帮助。同样引起注意的是,声明变量的前后顺序是没有什么关系的,只需要确定声明了所有需要的变量就行。最好的做法是将你的所有变量声明都放在脚本的开头独立的部分,就像我们之前所做的一样。

错误处理

既然我们已经从我们的脚本中清除了拼写错误(希望是这样),如果我们运行修改后的脚本,它会正常地工作。但如果没有呢?比如,如果我们要修改我们的脚本使它能对远程计算机而不是本地计算机产生作用,而远程计算机又不在网络上时又会怎么样呢(我将在后面的文章解释如何做)?同样,一个运行时错误(相对于VBScript在运行之前的编译时就能发现的错误的,在脚本正在执行时发生的错误)将会产生,然后脚本会停下来并显示一个类似于之前我们看到的错误消息,当然我们也是可以进行排错的。但如果我们编写的脚本是要执行许多的动作时又会怎么样呢?在这种情况下,我们也不希望有一个运行时错误使脚本停止——我们也许希望脚本继续执行以便它至少能执行完其它应该完成的没有问题的动作。一个很好的例子是这样一个脚本,它负责监控大量的计算机的配置,但并不对这些配置作修改。在这种情况下,你会希望这个脚本一直保持运行,即使其中的一个或多个计算机已经停止工作响应。

处理运行时错误的最简单的方法是当错误发现时忽略它。你可以通过在脚本的开头附近添加以下的语句告诉VBScript应该忽略运行时错误:

On Error Resume Next

添加这条语句的最好位置是Option Explicit之后,所以我们就这样修改我们的脚本。当然,还有几种情况你可能想做更多关于错误处理的事。比如,你也许想要在你的脚本的一些地方检查一个运行时错误的条件的存在性(如,尝试连接一个远程计算机的WMI服务之后),所以你可以验证脚本本该执行的一个特定的动作是否成功。然后,基于对错误条件的验证结果,你可以决定脚本的下一步应该怎么做。比如,如果一个错误发生后,你会输出一个消息告诉说“计算机X没有找到”,然后继续脚本的后续动作。我们将在后续的文章中详细地研究这样的错误处理,但现在我们就先添加上面的这个语句以忽略所有发生的运行时错误。

用户输入

如果我们想要在运行脚本的时才指定机器的新IP地址而不是将IP地址172.16.11.99硬编码到脚本中去。在这种情况下,我们需要做的是修改脚本以使我们运行脚本时能够提供用户输入。一个实现这个的很好的方法将是我们在命令行执行脚本时可以附加一些参数,比如输入“ChangeIPAddress.vbs 172.16.11.188”应该可以把我们的网络配置器的IP地址修改为172.16.11.188。下面就是我们为了实现这个目标而修改后的脚本:

Option Explicit
On Error Resume Next
Dim objWMIService
Dim objNetAdapter
Dim strComputer
Dim strAddress
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
If WScript.Arguments.count = 0 Then
     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
     WScript.Quit
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

让我们一处处地拆解分析这些代码。首先,我们声明了一个新的变量:

Dim strAddress

这一个将包括参数(IP地址)的字符串变量,这个参数就是我们在运行脚本时所要指定的。下一步,我们在我们声明的部分之后添加以下的代码行:

If WScript.Arguments.count = 0 Then
     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
     WScript.Quit
End If

这些代码是做什么用的呢?WScript对象的Arguments属性返回我们在运行脚本时指定的参数集合。count方法返回我们输入的参数个数。如果参数的个数等于0,它输出(显示)一个消息告诉我们应该如何正确地使用这个脚本,然后脚本退出前停止。

最后,之前脚本中的这一行代码:

arrIPAddress = Array("172.16.11.93")

也就是我们硬编码进去的将要赋给网络适配器的新IP地址现在已经由以下两行代码所替代:

strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)

第一行取出WScript.Arguments集合的第1项(0位置的项)并将它赋给字符串变量strAddress。然后第二行将这个strAddress作为第一个元素赋值给arrIPAddress数组。

让我们看看当运行这个脚本时会产生什么结果,首先不指定参数,然后指定一个参数:

C:\Documents and Settings\Administrator.DC-1\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
   Connection-specific DNS Suffix  . :
   IP Address. . . . . . . . . . . . : 172.16.11.31
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 172.16.11.1
C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Usage: ChangeIPAddress.vbs new_IP_address
C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.188
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\Documents and Settings\Administrator.DC-1\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
   Connection-specific DNS Suffix  . :
   IP Address. . . . . . . . . . . . : 172.16.11.188
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 172.16.11.1

这样,就对了。

验证输出

下一步,我们不想再在每次执行完脚本后都使用ipconfig去查看IP是否被修改成我想要的结果。是否有其他的方法可以检查脚本运行结果呢?是有的。注意我们脚本的下面几行:

For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

这些代码的目的是使用objNetAdapter.EnableStatic方法修改网络适配器的IP地址,而我在我的前一篇文章已经提到,我们需要使用一个err-参数(这里是errEnableStatic)作为存储方法运行时返回的错误代码。Win32_NetworkAdapterConfiguration 类的EnableStatic方法可能返回的一组可能的错误代码可以在MSDN上找到,而且我们可以从中知道如果返回0的错误代码表示操作已经成功完成(如这里是IP地址已经成功修改)。检查这个错误代码的最简单方法是通过在脚本的最后添加下面这行代码来输出这个错误代码:

Wscript.Echo errEnableStatic
Let’s run our script again and see this:
C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.237
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
0
C:\Documents and Settings\Administrator.DC-1\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
   Connection-specific DNS Suffix  . :
   IP Address. . . . . . . . . . . . : 172.16.11.237
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 172.16.11.1

可以确信,错误代码0表明IP地址被成功的更改。更好的一种办法是展示一个信息而不是用下面的编码来代替回应指令陈述:

If errEnableStatic=0 Then
     Wscript.Echo "Adapter’s IP address has been successfully changed to " & strAddress
Else
     Wscript.Echo "Changing the adapter’s address was not successful. Error code " & errEnableStatic
End If

让我们将这些添加到我们的脚本最后,然后尝试运行脚本2次,第一次用一个正确的IP,一次使用乱写的IP:

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.173
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Adapter’s IP address has been successfully changed to 172.16.11.173
C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.1492567
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Changing the adapter’s address was not successful. Error code 70
C:\Documents and Settings\Administrator.DC-1\Desktop>

结论

为了整理我们的脚本,我们将要做的最后一件事是增加一些注释来说明我们的脚本。这是一个很好做法,这可以使你在一年以后再使用或修改脚本时,你可以快速地明白它是做什么用的。下面是我们的用于修改我们机器上的网络适配器IP地址的最终整理版脚本:

’=========================
’ NAME: ChangeIPAddress.vbs

’AUTHOR: Mitch Tulloch
’DATE: October 2006

ARGUMENTS:
’1. new_IP_address
’=========================-
Option Explicit
On Error Resume Next
Dim objWMIService
Dim objNetAdapter
Dim strComputer     ’ Can specify IP address or hostname or FQDN
Dim strAddress     ’Contains the new IP address
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
’Check for missing arguments
If WScript.Arguments.count = 0 Then
     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
     WScript.Quit
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next
’Display result or error code
If errEnableStatic=0 Then
     Wscript.Echo "Adapter’s IP address has been successfully changed to " & strAddress
Else
     Wscript.Echo "Changing the adapter’s address was not successful. Error code " & errEnableStatic
End If

上一页  [1]  [3] [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第三部分:理解WMI

了解Windows Management Instrumentation(WMI)是如何工作,以及如何使用VBScript脚本,本文最初发表于windowsnetworking.com。

在本系列专题的前两篇文章中,我们了解到如何使用VBScript修改一个Windows计算机的一个网络适配器的IP地址。其中,我们还学到了很多关于Windows脚本编写的基本概念,如类、对象、属性、方法和不同类型的变量,包括字符串变量、整数变量、数组和集合。我们还了解到一些关于写好脚本的基本方法,如定义变量、实现错误处理、接受用户设置、显示验证输出,以及通过注释来文档化脚本。

我们的最终脚本已经按要求工作了,但可能仍有一些方面你觉得难以理解。比如,让我们看一下下面这一行:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

在我的第一篇文章,对于这一行我作了以下评论:“通过定义一个objWMIService对象并将它赋值为GetObject方法返回的句柄,就可以连接到本地计算机的root\cimv2命名空间了”。

这究竟意味着什么呢?到底什么是WMI,它究竟是如何工作的呢?而且为什么它对于想要了解如何编写脚本来管理Windows电脑的你来说是如此重要的呢?

理解WMI

大约在Window98出现或是更早以前,WMI就已经出现,只是这那之前它有一个不大相同的名称:基于Web的企业管理(WBEM) 。 WBEM是由Microsoft,Cisco,Intel,Compaq和BMC Software共同开发的技术,目的是为是更容易管理企业环境中的桌面系统和服务器系统。WMI提供了一个模型以表示、存储和查询Windows计算机的配置和状态信息以及其他运行状况。开发人员可以使用WMI写脚本或托管的代码去查看和修改设置在Windows电脑上的配置,以此查看Windows的应用和服务的状态,同时还做了很多其他有助于管理员进行Windows网络部署、维护和故障排除的其他的功能。

换句话说, WMI表示:

●Windows——只工作在安装了Microsoft Windows的计算机上工作;

●管理——可以用来管理这些电脑;

●检测工具——提供查看和修改这些计算机上配置的工具。

有一个很好的比喻是把Windows电脑比一个汽车,而WMI则作为你车上的控制台的电子(仪表),以显示上你车子的速度、引擎温度、RPMS 等等。这些仪表板的控制并不是它们自身完成的——你仍然要想出办法通过获取这些电子信息并且以一个可读的形式显示出来。使用WMI写VBScripts就是如同创造仪表板显示元件一样,整合到汽车的仪表盘中,以告诉你所想知道的信息并控制你的引擎。换句话说,Windows安装了通过WMI构建的所有这些工具——你只需要弄清楚如何使用它就可以通过它做一些有用的事情,比如改变你机器的IP地址、查看当前的时区、重启远程机器、显示已安装的修复程序列表等等。

WMI命名空间

我们要了解关于MWI的所有事,现在还不够。实际上,要找出WMI是否可以做一些特别的事情是需要一点耐心和领会能力的。让我们首先考虑WMI命名空间。在WMI术语,一个名字空间是类和类的实例的一种逻辑数据库。下面是一个简单的shownamespaces.vbs脚本,它列举了在根命名空间下的所有WMI命名空间:

Set objWMIService = GetObject("winmgmts:\\.\root")
Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")
For Each objNamespace In colNamespaces
     WScript.Echo objNamespace.Name
Next

下面是在WindowsXP 机器上运行这个脚本的结果:

C:\scripts>cscript ShowNamespaces.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
SECURITY
RSOP
Cli
SecurityCenter
WMI
CIMV2
Policy
Microsoft
DEFAULT
directory
subscription

每个这样的命名空间都是一个可能的来源,你可以查询关于Window计算机某个状态或配置的资料(而且也可以经常修改配置)。这些命名空间是像硬盘驱动器上的文件夹分层次地组织的。例如,我们可以通过下面的方式修改我们脚本的第一行来显示在root\CIMN2命名空间下的所有的命名空间:

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")

当你运行修改后脚本时,输出结果是这样的:

C:\scripts>cscript ShowNamespaces.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
ms_409
Applications

事实上,root\ CIMV2是Windows机器上默认的WMI命名空间。这意味着,如果你在脚本的第一行里不指定连接的命名空间,那么WMI默认就会自动连接到root\ CIMV2命名空间。因此,如果我们将第一行改为:Set objWMIService = GetObject("winmgmts:\\") ... 我们会得到与上面相同的结果。请注意,我们去掉了winmgmts:\\.\\root\CIMV2句号后面的内容。如果你还记得在我们的第一篇文章,这个句号表示本地计算机,同时默认地WMI假设你想要在本地计算机上工作,这意味着你可以去掉句号后面的部分。而编写脚本最好的做法是在脚本中使用变量(来定义它们),以下是一个更广泛使用的可以用来显示WMI命名空间脚本:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colNamespaces
Dim objNamespace
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")
For Each objNamespace In colNamespaces
     WScript.Echo objNamespace.Name
Next

为什么要把它变得这么复杂呢?主要的原因是增加灵活性!举例来说,如果我们需要运行在远程计算机上运行这个脚本,我们可以改变strComputer为远程计算机的IP地址值。或者如果我们需要显示命名空间的不同部分,我们可以添加几行到我们的脚本中以接受用户对strWMINamespace变量的输入。

WMI提供者

找到合适的命名空间只是第一个挑战(虽然大部分的情况下连接到默认的命名空间就已经足够了)。你还必须访问正确的提供者,以便取回或更新你的目标系统的数据。下面是一个ShowProviders.vbs脚本,可以显示root\CIMV2命名空间的所有WMI提供者:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colWin32Providers
Dim objWin32Provider
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colWin32Providers = objWMIService.InstancesOf("__Win32Provider")
For Each objWin32Provider In colWin32Providers
     WScript.Echo objWin32Provider.Name
Next

以下就是在Windows XP机器上运行这个脚本的输出结果:

C:\scripts>cscript ShowProviders.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Win32_WIN32_TSLOGONSETTING_Prov
MS_NT_EVENTLOG_PROVIDER
Win32_WIN32_TSENVIRONMENTSETTING_Prov
SCM Event Provider
ProviderSubSystem
VolumeChangeEvents
NamedJobObjectLimitSettingProv
HiPerfCooker_v1
WMIPingProvider
Microsoft WMI Forwarding Event Provider
Win32_WIN32_TSNETWORKADAPTERSETTING_Prov
SystemConfigurationChangeEvents
Win32_WIN32_TERMINALSERVICE_Prov
Win32_WIN32_TSREMOTECONTROLSETTING_Prov
Win32_WIN32_TSNETWORKADAPTERLISTSETTING_Prov
Win32_WIN32_COMPUTERSYSTEMWINDOWSPRODUCTACTIVATIONSETTING_Prov
Win32_WIN32_TSSESSIONDIRECTORY_Prov
CmdTriggerConsumer
Standard Non-COM Event Provider
SessionProvider
WBEMCORE
RouteEventProvider
WhqlProvider
Win32_WIN32_TSSESSIONSETTING_Prov
Win32_WIN32_TERMINalterMINALSETTING_Prov
Win32_WIN32_TSCLIENTSETTING_Prov
Win32_WIN32_TERMINALSERVICESETTING_Prov
WMI Kernel Trace Event Provider
Win32_WIN32_PROXY_Prov
NamedJobObjectProv
MS_Shutdown_Event_Provider
SECRCW32
Win32ClockProvider
MS_Power_Management_Event_Provider
Win32_WIN32_WINDOWSPRODUCTACTIVATION_Prov
RouteProvider
Cimwin32A
Msft_ProviderSubSystem
Win32_WIN32_TERMINALSERVICETOSETTING_Prov
NamedJobObjectSecLimitSettingProv
Win32_WIN32_TSSESSIONDIRECTORYSETTING_Prov
Win32_WIN32_TSPERMISSIONSSETTING_Prov
Win32_WIN32_TSACcount_Prov
Win32_WIN32_TERMINAL_Prov
MSIProv
DskQuotaProvider
NetDiagProv
Win32_WIN32_TSGENERALSETTING_Prov
CIMWin32
NamedJobObjectActgInfoProv
NT5_GenericPerfProvider_V1
WMI Self-Instrumentation Event Provider
MS_NT_EVENTLOG_EVENT_PROVIDER

看起来很复杂,不是吗?但是,使用这一系列的提供者,你可以轻松地搜索MSDN上有关某一特定提供者的更多的信息,并找到它所支持的方法。这就是你可以使用WMI对供应商所做的操作。

WMI类

除了命名空间和提供者,如果你想要利用WMI来脚本化Windows管理任务,你还需要理解WMI类。一个类是你可以用WMI管理的一种类型对象的一种模板。比如,Win32_LogicalDisk类是一个Windows机器上的逻辑磁盘摸板,而WMI则使用这个类为每一个安装的硬盘产生一个实例。

下面的ShowClasses.vbs脚本显示root\CIMV2命名空间的所有类(潜在的管理对象):

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colClasses
Dim objClass
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colClasses = objWMIService.SubclassesOf()
For Each objClass In colClasses
    WScript.Echo objClass.Path_.Path
Next

下面是在Windows XP上运行这个脚本时输出的内容:

C:\scripts>cscript ShowClasses.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
\\XP\ROOT\CIMV2:__SystemClass
\\XP\ROOT\CIMV2:__thisNAMESPACE
\\XP\ROOT\CIMV2:__Provider
\\XP\ROOT\CIMV2:__Win32Provider
\\XP\ROOT\CIMV2:__IndicationRelated
\\XP\ROOT\CIMV2:__EventGenerator
\\XP\ROOT\CIMV2:__TimerInstruction
\\XP\ROOT\CIMV2:__IntervalTimerInstruction
...
\\XP\ROOT\CIMV2:MSFT_WMI_GenericNonCOMEvent
\\XP\ROOT\CIMV2:MSFT_WmiSelfEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_OperationEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_ComServerLoadOperationEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_InitializationOperationFailureEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_LoadOperationEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_OperationEvent_Pre
\\XP\ROOT\CIMV2:Msft_WmiProvider_deleteClassAsyncEvent_Pre
\\XP\ROOT\CIMV2:Msft_WmiProvider_GetObjectAsyncEvent_Pre
...
\\XP\ROOT\CIMV2:Win32_ComputerSystemEvent
\\XP\ROOT\CIMV2:Win32_ComputerShutdownEvent
\\XP\ROOT\CIMV2:Win32_SystemTrace
\\XP\ROOT\CIMV2:Win32_ModuleTrace
\\XP\ROOT\CIMV2:Win32_ModuleLoadTrace
\\XP\ROOT\CIMV2:Win32_ThreadTrace
\\XP\ROOT\CIMV2:Win32_ThreadStartTrace
\\XP\ROOT\CIMV2:Win32_ThreadStopTrace
\\XP\ROOT\CIMV2:Win32_ProcessTrace
\\XP\ROOT\CIMV2:Win32_ProcessStartTrace
\\XP\ROOT\CIMV2:Win32_ProcessStopTrace

同样,这一切看起来有点还是挺复杂的,但你可以使用这些类在MSDN上搜索更多关于某一特定的WMI类信息,以此找到这个类相关的属性和方法。

使用WMI

下面让我们学以致用。上面脚本中显示的其中一个类是Win32_TimeZone,让我们用这个类显示电脑上所配置的时区。首先,我们需要知道关于这个类的更多信息,在MSDN上搜索“Win32_TimeZone类”会找到关于它的信息网页。在这个页面中我们可以找到这个类所支持的属性和方法(虽然实际上这个特定的级别只有属性而没有方法),这样使用这些信息,我们就应该可以写出我们所要的脚本。

这个小实验证明Caption属性是我们所要显示的,因为这是存储在机器上对最可读的(human-readable)形式的时区信息。以下这个命名为DisplayTimeZone.vbs的脚本,我们将用其查询WMI ,搜索这方面的资料并进行显示:

Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim strWMIQuery
Dim objWMIService
Dim colItems
Dim objItem
strComputer = "."
strWMINamespace = "\root\CIMV2"
strWMIQuery = "select   FROM Win32_TimeZone"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colItems = objWMIService.execQuery(strWMIQuery)
For Each objItem In colItems
    WScript.Echo objItem.Caption
Next

这就是运行脚本所显示的结果:

C:\scripts>cscript DisplayTimeZone.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
(GMT-06:00) Central Time (US & Canada)

让我们看看这个脚本是如何工作的。首先,你可以看到它很多基于我们先前的脚本。换句话说,我们是从使用以下语句连接WMI开始的:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)

而下面一句是新的:

Set colItems = objWMIService.execQuery(strWMIQuery)

我们在这里要做的是执行对WMI一个查询以从中收集一些信息。这个查询已经在之前使用以下的语句定义了:

strWMIQuery = "select  FROM Win32_TimeZone"

这个SQL的select语句本质上返回Win32_TimeZone提供者所能提供给我的所有记录(*号),然后将这些结果保存在colItems集合中。然后,我们循环遍历集合中的每一项(其实查询结果中只有一项记录)和显示这一项的Caption属性,就是下列字符串:

(GMT-06:00) Central Time (US & Canada)

练习

我们将在这一系列接下来的文章中深入研究WMI脚本编写,但现在让我们尝试做一个练习。将上面displaytimezone.vbs脚本中的内容到记事本(保证自动换行是关闭的),并将其另存为PageFile.vbs。现在修改脚本上的一行(实际上只是一行的一小部分),这样当脚本运行时显示路径和系统的PageFile(也就是虚拟内存)而不是时区。提示:在MSDN上搜索有关Win32_PageFile类的信息。我将在接下来的系列文章中解释这个练习的答案。

上一页  [1] [2]  [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第四部分Win32-NetworkAdapterConfiguration

这一章中将学习Win32-NetworkAdapterConfiguration类,此章来源于WindowsNetworking.com。

在这一系列的前面两篇文章中,我们阐述了使用Windows脚本来管理TCP/IP网络设置的基础知识。特别是,我们写了以下简单的脚本来改变IP地址的网络适配器:

Option Explicit
On Error Resume Next
Dim objWMIService
Dim objNetAdapter
Dim strComputer ’ Can specify IP address or hostname or FQDN 
Dim strAddress ’Contains the new IP address
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
’Check for missing arguments
If WScript.Arguments.count = 0 Then
    Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
    WScript.Quit
End If
strComputer = "." 
strAddress = Wscript.Arguments.Item(0) 
arrIPAddress = Array(strAddress) 
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from 
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
    errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next
’Display result or error code
If errEnableStatic=0 Then
   Wscript.Echo "Adapter’s IP address has been successfully changed to " & strAddress
Else
   Wscript.Echo "Changing the adapter’s address was not successful. Error code " & errEnableStatic
End If

上面的脚本是通过使用Win32_NetworkAdapterConfiguration修改网络配适器的IP地址,这也是管理基于Windows系统的TCP / IP网络配置一个最有用的WMI类。在第三篇文章中,我们简短探讨了“WMI Land”并了解了WMI的命名空间、提供者和类,以便我们能够更好地理解下面这个处于脚本核心中的一行:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

如果你还记得,通过确定一个objWMIService对象并用GetObject方法返回的句柄赋值给它,这一行脚本所起的作用就是你能在本地计算机上连接到root\ cimv2命名空间。当然,一旦你连接到这个命名空间,你就可以从中收集需要的信息。

而在今天的文章中,我们要把重点放在后面的一行脚本上,这一行脚本使用了Win32_NetworkAdapterConfiguration类:

Set colNetAdapters = objWMIService.execQuery("select * from 
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")

如果你再次回顾,你会发现这第二行所做的是调用了objWMIService对象的execQuery方法,这个对象就是我们在第一行实例化的。一个select语句被作为一个参数传递给此方法,这个方法会返回绑定和激活了TCP/IP的网络适配器的系统上所有的网络适配器配置的集合,这个集合被分配给变量colNetAdapters。一旦我们有了这个集合,我们使用Each...Next来对它进行循环遍历。记住你总是必须循环遍历集合去取数据项,即使只有一个数据项在集合中。

一个select语句被作为一个参数传递给此方法,同时,系统上所有被绑定和激活了TCP/IP的适配器的所有网络适配器配置集合将被返回和分配给变量colNetAdapters。

这就是我们今天要面对的问题:对于Win32_NetworkAdapterConfiguration类我们还可以做什么?

使用Win32_NetworkAdapterConfiguration的属性和方法

我们知道属性表示的是你可以使用WMI从一个系统中取回的信息。一个WMI类的属性越多,你能从中得到的信息就越多。实际上Win32_NetworkAdapterConfiguration类有61种不同的特属性,其中一些是特有的和其他的是从别的类上继承过来的。你可以在MSDN上找到一个完整的Win32_NetworkAdapterConfiguration类属性列表。如果你认真学习如何编写WMI脚本以使自己能够使用脚本管理Windows网络,熟悉像在MSDN上的WMI信息是很重要的,图1显示这个类的一些属性:

Win32_NetworkAdapterConfiguration类的属性

图1:Win32_NetworkAdapterConfiguration类的属性

在上图中,我点击了布尔型属性IPEnable的链接,这个属性是我们在脚本中用以识别我们的绑定了TCP/IP并已激活了的系统中的所有网络适配器。在通过下面的作为objWMIService.execQuerySQL参数的查询方法的情况下,我们使用这个链接:

select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE

马上我们就可以看到我们可以怎么通过查询类的其它属性来扩展我们的脚本的功能。比如,如果我们想要选择我们的系统中激活了DHCP的所有网络适配器,我们只需要简单地修改我们的select语句:

select * from Win32_NetworkAdapterConfiguration where DHCPEnabled=TRUE

我们怎么知道这些呢?因为这些信息可以在相同的MSDN页面找到,如图2:

Win32_NetworkAdapterConfiguration的DHCPEnabled属性

图2:Win32_NetworkAdapterConfiguration的DHCPEnabled属性

这个类的方法有哪些呢?我们知道方法是你可以使用WMI执行不同行为的东西。结果显示,Win32_NetworkAdapterConfiguraiton也有很多个方法,实际运用的总共有41个。你可以在同一页的属性下面找到这个类的方法,如图3所示: 

图3:Win32_NetworkAdapterConfiguration类的方法

图3:Win32_NetworkAdapterConfiguration类的方法

下面,让我们回顾一下我们脚本中的关键部分:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from 
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
    errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

首先,我们使用Win32_NetworkAdapterConfiguration类的IPEnable属性去返回绑定并激活TCP / IP的网络适配器的集合。然后,我们会使用先前在脚本中定义的数组变量arrIPAddress和arrSubnetMask来调用这个同样的类的EnableStatic方法去修改这些网络适配器的IP地址和子网掩码。我们是怎么知道我们必须将两个变量作为参数传递给这个方法的呢?是这样的,通过点击上面图3的EnableStatic的链接,MSDN的网页已经在图4显示,告诉我们关于如何使用这个类的信息: 

Win32_NetworkAdapterConfiguration类的EnableStatic方法的详细信息

图4:Win32_NetworkAdapterConfiguration类的EnableStatic方法的详细信息

需要注意的是这个MSDN网页不仅给我们提供了如何调用这个类的语法,而且还给我们提供了返回值以及如何解释可能出现的不同的错误条件。这就是为什么我们在以下几行的脚本中使用了错误的变量的原因:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

这就是为什么我们在脚本中包括了下面的几行来报告错误代码,当脚本运行时可能会报错:

If errEnableStatic=0 Then
    Wscript.Echo "Adapter’s IP address has been successfully changed to " & strAddress
Else
    Wscript.Echo "Changing the adapter’s address was not successful. Error code " & errEnableStatic
End If

再次,我们可以看到我们可以如何扩展脚本的功能,这一次我们是通过调用这个类的其他方法实现的。例如,如果我们想在我们的所有绑定和激活TCP/TP的网络适配器上禁用NetBIOS。通过略读MSDN上的Win32_NetworkAdapterClass网页,我们发现了一种似乎符合这一要求的SetTcpNetbios的方法 (见图5 ): 

Win32_NetworkAdapterConfiguration类的SetTcpipNetbios方法

图5:Win32_NetworkAdapterConfiguration类的SetTcpipNetbios方法

点击这个方法链接,打开一个如何使用它的网页(图6 ) : 

图6:SetTcpipNetbios方法的详细信息

图6:SetTcpipNetbios方法的详细信息

我们可以看到如果我们要在适配器上禁用NetBT,我们所需要做的就是在脚本上修改下面的这一行:

  
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

为:

errEnableStatic = objNetAdapter.SetTcpipNetbios(2)

修改脚本,并整理好我们的脚本:去除不再需要的变量并重命名其他变量,然后我们就有了以下的脚本,它可以在绑定和激活了TCP/IP的所有网络适配器上禁用NetBT:

’=========================
’ NAME: DisableNetbios.vbs

’AUTHOR: Mitch Tulloch
’DATE: December 2006

’ARGUMENTS: 
’1. None
’=========================-
Option Explicit
On Error Resume Next
Dim objWMIService
Dim objNetAdapter
Dim strComputer ’ Can specify IP address or hostname or FQDN
Dim colNetAdapters
Dim errDisableNetbios
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from 
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
    errEnableStatic = objNetAdapter.SetTcpipNetbios(2) 
Next
’Display result or error code
If errDisableNetbios=0 Then
    Wscript.Echo "NetBIOS has been successfully disabled on the adapters"
Else
    Wscript.Echo "Disabling NetBIOS was not successful. Error code " & errDisableNetbios
End If

让我们看看它是否正常工作。图7显示在一个Windows Server 2003机器上的“本地连接”-“高级TCP/IP属性”的“WINS”标签:

图7:一个Windows Server 2003机器上的TCP/IP的NetBIOS设置

图7:一个Windows Server 2003机器上的TCP/IP的NetBIOS设置

注意这台机器的当前的NetBT设定是“Default”,它对于SetTcpipNetbios方法(见图6)的值为0的。让我们拷贝的新脚本到记事本(确保自动换行是关闭的)并另存为DisableNetbios.vbs。然后,我们会在我们的服务器的命令提示符窗口使用cscript来运行这个脚本(图8):

图8:使用一个脚本来禁用TCP/IP的NetBIOS

图8:使用一个脚本来禁用TCP/IP的NetBIOS

现在让我们看看它是否正常工作。我们需要关闭我们的TCP/IP属性页面并重新打开以便在GUI上刷新设置的NetBT,现在我们可以看到它的状态(图9):

图9:NetBT已经被成功地禁用

图9:NetBT已经被成功地禁用

结论

最好的学习Window 脚本编写的方法就是实际操作,所以这里有一组练习,你可以自己尝试一下以便巩固你在这篇文章中学到的知识:

1. 修改脚本,使其能够接收参数。例如,输入DisableNetbios.vbs 1激活NetBT, 而DisableNetbios.vbs 2则禁用它,以及DisableNetbios.vbs 0让它使用默认值,使用DHCP来确定NetBT在适配器上是激活还是禁用。

2. 修改脚本中的select语句,使之能够基于Win32_NetworkAdapterConfiguration的一些其他的属性选择网络适配器;然后进一步修改脚本去调用这个类的一些不同的方法以在网络适配器上执行一些其他关于TCP / IP配置的行为。

3. 浏览MSDN去学习其他的一些对你脚本化不同的Windows管理任务有帮助的WMI类。

上一页  [1] [2] [3]  [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第五部分:跨过一道坎

当学习用脚本来管理Windows 网络时,你必须注意在此过程中出现的、被Mitch Tulloch称为“坎”的难关。以下是就如何攻克难关的技巧学习,原文发表在WindowsNetworking.com.

在这一系列的前几章中,我们开始探索“我们可以用Win32_NetworkAdapterConfiguration 做什么”。这个强大的WMI级别有61个属性和41种方法,可用于获取和修改Windows计算机的TCP/IP网络设置。

为了说明这个类的功能,我们采取了我们在第一和第二章中开发的示例脚本,并利用MSDN上关于这个类的信息,我们定制我们原来的脚本使它做了一些不同的事。具体来说,我们利用之前修改网络适配器IP地址的脚本,并将它定制成一个新的脚本,它将禁用在所有绑定和激活了TCP/IP的网络适配器上TCP/IP的NetBIOS(NetBT)。

我们需要继续更深入地探索这个强大的WMI类,而且我们在接下来的几篇文章中将对它继续进行分析。但在做这个之前,让我们先来谈谈这个“坎”。

所谓的坎

在我开始写这个关于使用脚本管理Window网络的系列文章时,我收到了读者们给我的邮件。在所有这写读者的邮件中都问到一个简单的问题:“我应该如何学习脚本呢?”我的第一个反应总是给提问者们指出若干的资源,包括TechNet上的文章、不同的书、脚本新闻群组等等。当然,当我考虑到这个问题的时候,就好像是要回答某人关于如何成为一个法国烹饪专家一样。“这是一些关于不同的烹饪学校、烹饪书目和网站。开始学习吧。”这样的回答可能对于那些有主动性和自律性学习技巧的人有所帮助,但是它也涉及到另外一个更有趣的问题:为什么有些人在开始学习这个技巧时遇到那么多问题呢?

●我也曾经尝试过成为一名美食厨师,下面这些就是我所做的一些事情:

   ● 我在当地的一个二手书店里买了一堆旧的Gourmet Magazine 的期刊


   ● 我开始买各种异国风味的作料,如香料、五香料和不同的油等等


    ●我选择了一个听起来很好吃的Carrot Ginger Soup Frog食谱,然后买了所有需要的作料。(Frog是以饭店的主厨创造的汤名命名的招牌;i.e.汤里面并没有青蛙)。


    ●我邀请了几位女性劝导一起吃晚饭,并且我准备在晚餐上给与她们这个烹饪奇观般的美食惊喜。(请注意我是请了几位朋友而不是一位。如果你很幸运的话,有时候你应该使用撒网而不是下钩。)


    ●一起吃晚饭的那天到了,我开始第一次烹饪这道著名的汤。之前我从没有练习过的。
    ●结果是怎么样的呢?汤散得到处都是,炉灶上、墙上和天花板上。而且弄脏的餐具锅盘堆得老高。我也同样不走运——对于我和我的朋友而言,它尝起来一点都不美味。到底是怎么了呢?有很多的原因。特别是:

   ● 我是从一个过高的水平要求上开始的,尝试准备一件需要很大基本技能的工作,但都还没有掌握好这些技能。


   ● 在投入到“生产环境”之前,我也没有很好地测试我的创作。


    ●我还没有理解学习一个概念和学习一种技能的区别。


    ●我都也没有很认真地将学习一些概念,更别提技能了
    到底应该选择哪种途径来替代我原先所用的那种呢?

   ● 先在本地的社区俱乐部上一个法式餐的基本课程。


    ●在尝试做其他更难的之前先学习做一个简单的白调味汁。


    ●在读像Gourmet 般的高水平刊物之前先循序渐进地学习新的烹饪术语。


    ●在我进行实验和原创之前要进行反复的练习。


   ● 寻找其他的方法来吸引约会,比如学习自我推荐。

那么这跟学习脚本有什么关系呢?首先,这样一个有点幽默的例子能让你有个好心情来听讲,比如现在我就能让你开始关注于我所要讲的了。几乎所有想了解如何写脚本的Windows管理员都会在学习的路上遇上这个我称之为“坎”的问题。因为有太多可以很容易学懂的概念,所以大脑就开始停歇下来时这个坎就出现了。这是因为概念不是在一个单独的位置存在的,而是相互关联的。例如,除非你明白了什么是方法,否则你不能真正理解什么是属性。属性和方法都是在类的上下文中才能被理解的。类必须先被实例化成对象,然后才可以有属性和你可以读和操作的方法。听起来有点像是说教科书内容,对吧?其实,那是因为它就是教科书中的内容。

 “为什么我不能只是学习脚本?为什么一定要学习所有这些概念和术语?”那么,为什么你必须学会区别白色和棕色的调味汁呢?或者为什么要知道酱汁有四种基本类型:果泥状 ,稀少状,淀粉状和乳液状?又或者是要知道掺油面粉糊是调味酱、浓汤、etouffe和白色和棕色这两种调味汁的基本组成?同时,为什么我需要了解调味酱的历史?因为从长远来看,除非你了解这些基本概念,否则你将不会取得任何进展,因为它们是大多数法国烹饪的基本组成。

另一方面,在现实世界中我们的大多数人(比如,我们这些不想成为专业厨师的)没有时间,金钱或耐心全日制地参加一个法国烹饪学校,在学习如何煎猪肉排之前花费开始的6几个月的时间一次又一次地做基本的调味汁。我知道,在过几个星期后我将感到厌倦无聊,并决定寻找一个不同的职业。这个跟学习脚本是一样的道理的:作为一个繁忙的网络管理员,我不能花三年的时间学习每一个与任何Windows网络的WMI类相关联的属性和方法。或者是完全精通地学习VBScript语言的语法的每一个方面。我在大学一年级时就已经花了足够多的时间学习Fortran 语言了,一遍又一遍地编程序来列印出前十平方、前100质数、前1000个 Fibonacci数字等等。因此,考虑到我们有限的时间、金钱和耐心,再加上学习大量的关于Windows的脚本编写的相互关联的概念确实存在不少的困难,像我们这样的一般的管理员要怎么样才能攻克难关从而继续学习脚本编写呢——它真的有用吗?

攻克难关

很显然,对于这个问题并没有很好的答案,但下面是我所找到的有用的东西。这些也是曾经在我的学习过程中起到有所帮助的:

1. 从小处着手。一步到位并不是一个很好的开端,不管是对于学习法国烹饪还是编写脚本都是这样。所以,如果你已经定下目标要学会如何写一个脚本去为一个域中的OU结构查询Active Directory并在一个HTML页面上显示这个结构,而且要在一个星期内学完编写这个脚本所需要的知识,那么你这个目标可能真的高了,或者至少你比我聪明很多。而你最可能会做的是用Google在网上搜索一个功能类似的脚本,然后尝试定制这些脚本以满足你的要求(这就是你做的全部),但这只是学习的一个方面。另外,你最终可能会以一个复杂到你根本不能完全理解的脚本而告终。

2. 专注于编写脚本的特定领域。我自己最大的一个弱点是,我想要了解一切的一切,并且是马上学会。所以,当我第一次想了解如何写脚本时,我一开始就尝试从头到尾地阅读整本的 VBScript语言参考。不用说,这是枯燥无味的阅读,所以在读到大约四分之一的的时候我放弃了。更好的做法是关注于脚本编写的一个特定领域,如脚本化TCP/IP网络的任务,这也是这一系列文章的重点。一旦你掌握了这个(一个不小的)领域的脚本,然后你可以转到另一个重点领域,并尝试掌握它等等。

3. 花一些时间去学习基础知识。集中在一个主题方面是一个很好的做法,同时也很重要的是学习基础知识。要学习如何使用运行参数输入信息到一个脚本。要学习如何处理简单的错误。要学习如何以可读的方式显示结果。要学习一些简单的select语句的语法。要学习不同的变量类型。学习一些关键的WMI类,并学习每个类的几个有用的属性和方法。等等。你不必成为所有这些领域的专家,但是为了编写一个适当的脚本,你必须足够的了解各个方面的知识,而不仅仅是脚本的片段。

4. 用笔记记下所学的东西。在很长一段时间(令人尴尬的长),因为所涉及到的一些概念,我对学习脚本编写的遇到很大的难题。正如你可能已经从我之前说的大学里学习Fortran的例子中猜到我在过程语言编程的日子里学习计算机编程的。这带来的后果是,由于根深蒂固的过程编程思想导致我很难转变到面向对象的编程,而我们知道当VBScript从 Visual Basic剥离时,面向对象编程(对于Windows管理员)就开始流行了。因此在很长一段时间里,我被面向对象术语所困扰,如对象、属性、方法和类等等,这成为了我学习脚本编写的一个大障碍(坎)。当然,我可以拿一个别人写的脚本,而且(如果它足够简单)我就可以或多或少地弄清楚它如何运行的,并能够对它进行一些定制。但是MSDN于我就像希腊语一样(这里没有攻击希腊的意思)而WMI对我来说是完全的谜。这种状况直到我开始记笔记才有所改变。有一天,我写下了一个简单的句子:“属性是你可以读取的东西,而方法是你是可以做的”,突然间难关一跨而过,我攻克了这个问题。其他的概念开始迅速触类旁通,因为它们都是相互关联的;一旦你将其中几个给解决了,其余的开始迅速很快得到了解决。

5. 收集有用的学习资源,并利用它们。如果你找到一本关于脚本的好书,购买下来然后从头到尾地阅读,做完其中的练习。在TechNet Script Center上也有大量的关于脚本的资源,在以后的这个系列的几章中我将重点指出一些这方面的资源。还有其他资源包括课程(包括教师主导和自定进度的)、讨论组等等。那里有几乎所有方面的关于脚本学习的资源,但关键是要很好的利用其中的一些并且你就会有所收获。包括现在这些文章也是。

6. 练习、练习、反复地练习。学习任何技能都需要极大的耐心。事实上,我仍然不能做出象样的没有稠状的白色调味汁!同样的,学习脚本也一样:熟能生巧。在前进的道路上总有各种各样的难关,我们需要采取决心和毅力来克服它们。而且一般来言,比起编写少量又长又复杂的脚本,通过编写几百个短脚本会让你将会学到更多。因此,让自己以做一系列短期的练习为目标,并且尽自己最好的方式来学习。

7. 学习会变得很有趣的。最后,我不知道你是否一样,但是我在乐趣中学习是最好的。如果你有一些网络的管理任务,而且你认为使用脚本可能会让管理容易些,那么这就可能是你的一个学习的动机。另一方面,如果你真的忙(同时不是网络管理员),那么如果你请别人给你写脚本的话可能是最容易的。但是,如果你把接触脚本编写作为一种新的爱好享受,类似高尔夫球,比起你将它作为一个额外的工作清单看待,你可能会学习更快,并且能够做比你学到的东西更多的事。就像打高尔夫球一样,能与别人一起完成是最愉快的,因此,看看你的一些IT职业的朋友或同事是否也有兴趣玩一下脚本游戏。向他人分享你正在学习的东西会能让学习变得更加有趣。

结论

我写这篇文章的原因是我意识到一些读者仅仅读了前面四篇文章后就可能遇到了一些难关。希望我在这里所说的能够帮助你克服阻碍你继续学习的问题。在下一章中,我们将重新回去探索Win32_NetworkAdapter Configuration类,同时看看我们该如何对它进行操作,当然我们将要学习一些新的概念同时巩固前面所学习的内容。此外我们还要学习更多的VBScript语法并探讨一下我们怎么让我们的脚本变得更简练和实用。然后我们还要探索一下其他的一些WMI类,最后是一些高级脚本的主题,比如替代证书(alternate Credentials)、远程脚本、COM对象和WSF脚本等等。我们最后还介绍几个很好的脚本编写的工具,但是重要的是在学习一些捷径之前你要先学好基础的东西,因为它能让你更深刻的理解这个问题,从而使你对自己的技术更有信心。我还会试着给你提供一些练习让你独立完成,如果你真的想学好脚本编写,你就必须真的动手去做,而不是只是看上一眼然后就说: “我懂了。”毕竟,实践出真知。

上一页  [1] [2] [3] [4]  [6] [7] [8] [9] [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第六部分:远程脚本

本文主要学习如何在一个远程Windows XP计算上远程地运行你的脚本,原文发布于WindowsNetworking.com。

在上一篇文章中,我们探讨了“Win32_NetworkAdapterConfiguration类的使用”和“跨过一道学习的坎”这两个个许多Windows管理员在学习脚本编写都会遇到的问题。

现在让我们回顾一下我们的修改网络适配器IP地址的ChangeIPAddress.vbs脚本:

Option Explicit 
Dim objWMIService
Dim objNetAdapter
Dim strComputer 
Dim strAddress 
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
If WScript.Arguments.count = 0 Then
    Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
    WScript.Quit
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0) 
arrIPAddress = Array(strAddress) 
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.execQuery("select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
    errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask) 
Next

注意,我已经删除了注释以及最后显示结果的代码。

现在记住脚本的以下行为:

  ●它连接到本地计算机的root\cimv2命名空间;


    ●它使用一个select语句返回绑定和激活了TCP/IP的网络适配器集合;


    ●它将适配器的IP地址修改成命令行参数所指定的值。

假定我们将这个脚本保存在一个静态IP地址为172.16.11.43的Windows XP机器的目录:C:\localtest上。然后我们用管理员权限的用户打开命令提示符,再用这个脚本将机器的IP地址修改成172.16.11.54:

C:\locatest>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 172.16.11.43
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 172.16.11.1
C:\locatest>ChangeIPAddress.vbs 172.16.11.54
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\locatest>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 172.16.11.54
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 172.16.11.1
C:\locatest>

提示1:记住修改Windows XP机器的IP地址要求本地的管理员权限。所以如果你当前以一个域用户登录到机器上,你需要打开一个命令提示符,然后输入:runas /user:administrator cmd.exe来打开第2个命令提示符,它就是运行在本地管理员权限上下文的,然后在第2个命令行提示符上运行这个脚本。

但如果我们想在一台机器上(如xp2.contoso.com)运行这个脚本去修改另一台机器(xp.contoso.com)的IP地址又应该怎么做呢?换句话说,我们想要运行脚本去完成远程Windows XP计算机的任务。我们要怎么实现?

第一次尝试

首先我们用我们Mary Jones的域管理员帐号登录到我们管理员工作站xp.contoso.com。因为域管理员拥有所有域内机器的本地管理员权限,所以当我们从我们管理员工作站运行我们的脚本作用于远程机器,它应该是能工作的,对吗?

假定我们的脚本ChangeIPAddress.vbs是我们管理员工作站的目录:C:\tools,我们打开一个命令提示符然后输入下面的命令:

C:\Documents and Settings\mjones>cd \tools
C:\tools>notepad ChangeIPAddress.vbs
Our script opens in Notepad, and we change this line:
strComputer = "."
to read the following:
strComputer = "xp2 "
We then select File | Save to save changes, and close Notepad. Now let’s run the script:
C:\tools>ChangeIPAddress.vbs 172.16.11.65 
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\tools\ChangeIPAddress.vbs(20, 1) Microsoft VBScript runtime error: The remote server machine does not exist or is unavailable: ’GetObject’
C:\tools>

注意这需要运行一段时间后上面的错误消息才最终返回。但操作成功了吗?这样,如果我登录到远程机器xp2,contoso,com上,打开命令提示符然后输入ipconfig,我会得到:

C:\locatest>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 172.16.11.43
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 172.16.11.1
C:\locatest>

这样看来这个机器的地址仍然是17216.11.43,脚本并没有产生作用。怎么可能?是哪里出问题了呢?我们从错误信息上看到在脚本的第20行的地方出现了一个运行错误,让我们看看第20行是什么:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

所以看起来我们的脚本不能连接到远程机器的WMI服务。那又是什么导致这个错误呢?

第二次尝试

也许这跟远程机器的Windows防火墙设置有关系。

记住,Windows XP SP2带有一个防火墙,它会阻挡除配置的例外程序之外的所有到达的网络流量。测试是否由于防火墙引起的最简单的办法是先暂时禁用目标机器的Windows防火墙。可以这样做,我们先以管理员身份登录xp2.contoso.com,从“控制面板”打开“Widnows防火墙”工具,在“常规”标签中选择“关闭”选项。

现在让我们在管理员工作站上再一次运行脚本:

C:\tools>ChangeIPAddress.vbs 172.16.11.65Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.
C:\tools>

没错,又一个错误,同样它需要运行一段时间后才出现这个错误的。但至少这是一个不同的错误了,它显示在第23行出了问题:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

然而,当我在远程机器上的命令提示符输入ipconfig时,我得以这样的结果:

C:\locatest>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 172.16.11.65
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 172.16.11.1
C:\locatest>

所以看起来我们的脚本已经生效了!我们已经达到目的了!但这里仍有两个疑问:

●我们不想通过禁用远程机器的Windows防火墙来允许脚本对它操作。所以在这些机器上是否应该有一个防火墙例外设置使得在防火墙打开时允许远程脚本来操作它?


   ●上面的RPC错误是怎么回事?脚本已经生效了但为什么还有错误?

远程脚本异常

首先我们在远程机器上重新启用Windows防火墙。这样它将再次阻挡我们的脚本对它进行远程操作。然后在远程机器的管理员级的命令提示符上,输入gpedit.msc打开“本地计算机策略”,找到下面的策略设置(如图1):

图1:激活远程管理的Windows防火墙策略设置

图1:激活远程管理的Windows防火墙策略设置

双击这个策略设置并在本地子网(如图)中激活它。我们这样做是因为我们知道我们的管理工作站与目标计算机是在同一个子网的。

图2:激活远程管理例外

图2:激活远程管理例外

提示2:当然,你也许想要用不同的方法实现这个设置,如在一个域的Group Policy Object (GPO)而不是在本地配置这个策略的设置。依据这种方式,你就不需要通过远程机器来激活这个防火墙例外设置。

现在让我们在管理工作站再次运行脚本,试着把远程机器的IP地址从172.16.11.65修改成172.16.11.66:

C:\tools>ChangeIPAddress.vbs 172.16.11.66
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.
C:\tools>

和之前一样的错误,但当我在远程机器上的命令提示符输入ipconfig 后我得到这样的结果:

C:\locatest>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 172.16.11.66
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 172.16.11.1
C:\locatest>

成功了!所以保持激活远程机器上的Windows防火墙,但使用Group Policy在防火墙上对远程管理打开一个例开设置,我们就可以在一个管理工作站运行脚本来远程地修改机器的IP地址了。

这样我们就解决了第一个疑问了,但第二个呢?

我喜欢神秘些,所以让我们留到下一篇文章再解决。

上一页  [1] [2] [3] [4] [5]  [7] [8] [9] [10]  ... 下一页  >> 

使用脚本管理Windows网络 第七部分:修复神秘的错误

本章关于使用脚本管理Windows网络,阐述了当使用我们之前开发的ChangeIPAddress.vbs脚本去修改远程计算机IP地址时,如何修复其产生的“远程程序调用失败”的错误。原文发表于WindowsNetworking.com。

在前面的文章“远程脚本初探”,我们使用之前开发的ChangeIPAddress.vbs脚本,将它修改了后用以修改远程计算机的IP地址。下面就就是我们修改的脚本:

Option Explicit
Dim objWMIService
Dim objNetAdapter
Dim strComputer     
Dim strAddress     
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
If WScript.Arguments.Count = 0 Then
     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
     WScript.Quit
End If
strComputer = "xp2"
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Next

这一行:

strComputer = "xp2"

告诉我们,脚本的目标计算机名是XP2。远程计算机XP2原先的IP地址是172.16.11.43。

现在,当我们从管理工作站XP上输入ChangeIPAddress.vbs 172.16.11.65运行脚本时,出现了下列情况:

1. 脚本起作用了,如XP2的地址将从172.16.11.43 改为172.16.11.65;

2. 脚本需要花费很长的时间才执行完;

3. 脚本返回以下错误:

C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.

我们怎样处理这些结果呢?

简单的解决方法

其实我们可以对自己说,“好了,既然它已经起作用了,那么就让我们忽略这个错误吧。”对于这种说法是可以理解的。毕竟,任何现实的管理员都知道IT不是一个精确的科学工作,当我们无法设计妥善的解决方法时,我们往往最终采用“应急方案”来解决问题。

因此,我们该如何忽略这个错误呢?只需在标头节添加以下这一行:

On Error Resume Next

换句话说,我们脚本的头部将是这样的:

Option Explicit
On Error Resume Next
Dim objWMIService
etc.

现在,我们就不会看到错误,而且我们的脚本也可以正常工作了。但是,它仍然需要一段较长的时间来执行,事实上,足足超过一分钟。这又该怎么办呢?

解决错误讯息

错误消息有时是很隐秘的,这是其中的一个。这里是又一个错误消息:

SWbemObjectEx: The remote procedure call failed.

这是产生错误的那一行代码:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

现在这行代码工作了(如,目标计算机IP地址修改了)但它抛出了一个错误,为什么呢?

让我们先设法理解SWebObjectEx的作用。从MSDN上快速搜索到这个网页,上面有这样的说明:

Extends the functionality of SWbemObject. This object adds the Refresh method for SWbemRefresher objects. 

很好。这样看来SWbemObjectEx只是给SWbemObject增加了更多的功能。那么,SWbemObject又是什么呢?

Contains and manipulates a single WMI object class or instance.

那么,这是又意味着什么呢?网页上告诉了我们很多,但是却又相当怪异。但是,简而言之,SWbemObject(以及SWbemObjectEx )是你用于在WMI中管理或查询的。在我们的脚本上,我们正在查询Win32_NetworkAdapterConfiguration类和返回代表计算机网络适配器的colNetAdapters对象集合。因此,这个错误消息所指的SWbemObjectEx(或SWbemObject)仅仅是该对象代表网络适配器本身,即objNetAdapter 。

那么,是SWbemObject导致了错误。为什么呢?

于是,我必须得跟我一些脚本“高手”朋友交谈一下来尝试和解决这个问题。但是,直到现在我所得到的答复都不能完全令人满意。但是,不管怎么说,什么时候曾有过用 “满意”来描述IT管理员工作的吗?

总之,这里的似乎是存在问题的。根据其中的一位高手所言,似乎Windows XP上的更新补丁的“某个东西”可能已经改变了当导致错误的语句执行时返回调用的创建和提交方式。通常情况下,如果Win32_NetworkAdapterConfiguration类的实例对象的EnableStatic方法调用成功完成,它将返回 0,这意味着没有错误,而如果调用返回1,那么这意味着需要重新启动(见本页下的“Return Value”的更多信息)。当然,在Windows XP上,当你更改需网络适配器的IP地址时是不需要重新启动的。如果由于某种原因,更新补丁可能已经改变了一些WMI提供者或其他一些内部元素,因此,Windows认为在目标机器采用新的地址之前系统需要重新启动,而这正是导致错误的原因,因为网络适配器配置的机器一直保持不定型的状态,直到机器被重新启动。但是,当目标计算机的网络适配器配置进入这个不确定状态时,由于脚本仍在管理工作站运行,两台主机的RPC连接在脚本完成运行之前便开始了工作。因此,这就产生了错误。

至少目前来说,这是我能够给出的最佳答案,我将继续进行调研。但是,同时让我们看看我们是否能够设法将这个问题隔离开来,即这个错误只有在Win32_NetworkAdapterConfiguration上的 EnableStatic方法才出现,而不是普遍存在的。如果我们尝试写一个脚本对目标机器的网络适配器进行不一样的操作,而不是改变其IP地址呢?例如,改变目标机器的默认网关而不是IP地址?如果这一方法可行,那么至少我们知道,我们可以成功地从管理员工作站上连接远程计算机,并调用WMI方法来改变网络设置。

改变默认网关

在此,我建议你先停止阅读这篇文章,然后重新回到第四部分。在第四部分中,我指出了“如何使用MSDN去学习运用Win32_NetworkAdapterConfiguration类的属性和方法”。我敢打赌,如果你这样做了,你可以自己写出这样的脚本。大胆尝试一下!

中止

很好,现在你已经开始尝试写自己的脚本了。有可能你的脚本能能正常工作,也有可能不行。如果它不行,尝试下面的步骤:

1. 第一步是回到MSDN中关于Win32_NetworkAdapterConfiguration class 类的页面。

2. 在这一页中,寻找与修改网络适配器的网关有联系的方法。快速地查阅这一页你将看到:

SetGateways: Specifies a list of gateways for routing packets destined for a different subnet than the one this adapter is connected to.

这就是我们想要的,所以,点击SetGateways,打开Win32_NetworkAdapterConfiguration class 类页面的SetGateways方法。

3. 在SetGateways方法的这一页上,你将找到问题的解释:
The SetGateways WMI class method specifies a list of gateways for routing packets to a subnet that is different from the subnet that the network adapter is connected to. This method only works when the Network Interface Card (NIC) is in the static IP mode.

你已经知道了在你调用这个方法之前,目标计算机上必须有一个静态的地址。接着往下读,你会发现调用这个方法的句法是这样的:

SetGateways(A,B)

这里A是一个包含网关IP地址的字符串变量,而B是一个从1到9999间指定数据的整数价值。

现在你应该有了足够的信息来编写你的脚本了。最简单的方法就是从你在这一系列的第二部分所开发的原始ChangeIPAddress.vbs脚本上开始,然后对它进行一点修改,直到我们获得以下这样的一个新的脚本(我们称之为ChangeIPAddress.vbs)

'=========================
' NAME: ChangeGateway.vbs
'
'AUTHOR: Mitch Tulloch
'DATE: February 2007
'
'ARGUMENTS:
'1. gateway_address
'2. metric
'=========================-
Option Explicit
Dim objWMIService
Dim objNetAdapter
Dim strComputer 
Dim strGateway 
Dim arrGateway
Dim intMetric
Dim arrMetric
Dim colNetAdapters
Dim errGateway
'Check for missing arguments
If WScript.Arguments.Count = 0 Then
     Wscript.Echo "Usage: ChangeGateway.vbs gateway_address metric"
     WScript.Quit
End If
strComputer = "xp2"
strGateway = Wscript.Arguments.Item(0)
arrGateway = Array(strGateway)
intMetric = Wscript.Arguments.Item(1)
arrMetric = Array(intMetric)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
     errGateway = objNetAdapter.SetGateways(arrGateway, arrMetric)
Next
'Display result or error code
If errGateway=0 Then
     Wscript.Echo "Adapter's gateway has been successfully changed to " & strGateway
Else
     Wscript.Echo "Changing the adapter's gateway was not successful. Error code " & errGateway
End If

拷贝这个脚本到记事本(关闭自动换行)并另存为ChangeGateway.vbs。现在我们来测试它。让我们登录到远程主机XP2上,打开命令提示符并输入“ipconfig /all”,得到结果如下:

C:\>ipconfig /all
Windows IP Configuration
        Host Name . . . . . . . . . . . . : XP2
        Primary Dns Suffix  . . . . . . . : contoso.com
        Node Type . . . . . . . . . . . . : Unknown
        IP Routing Enabled. . . . . . . . : No
        WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Local Area Connection:
        Connection-specific DNS Suffix  . :
        Description . . . . . . . . . . . : Intel 21140-Based PCI Fast Ethernet
Adapter (Generic)
        Physical Address. . . . . . . . . : 00-03-FF-21-88-8C
        Dhcp Enabled. . . . . . . . . . . : No
        IP Address. . . . . . . . . . . . : 172.16.11.80
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 172.16.11.1
C:\>

现在在管理工作站XP上,打开命令提示符,运行新的脚本:

C:\tools>ChangeGateway.vbs 172.16.11.2 5
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Adapter's gateway has been successfully changed to 172.16.11.2
C:\tools>

脚本大概需要运行5秒钟便结果,而且没有任何错误抛出。(注意我已经在脚本的开头添加了“On Error Resume Next”,所以我看不到任何错误发生。)

现在让我们回到远程机器XP2,再次运行ipconfig /all:

C:\>ipconfig /all
Windows IP Configuration
        Host Name . . . . . . . . . . . . : XP2
        Primary Dns Suffix  . . . . . . . : contoso.com
        Node Type . . . . . . . . . . . . : Unknown
        IP Routing Enabled. . . . . . . . : No
        WINS Proxy Enabled. . . . . . . . : No
Ethernet adapter Local Area Connection:
        Connection-specific DNS Suffix  . :
        Description . . . . . . . . . . . : Intel 21140-Based PCI Fast Ethernet
Adapter (Generic)
        Physical Address. . . . . . . . . : 00-03-FF-21-88-8C
        Dhcp Enabled. . . . . . . . . . . : No
        IP Address. . . . . . . . . . . . : 172.16.11.80
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 172.16.11.2
C:\>

它起成功了。没有错误,没有问题——我们已经运行一个脚本远程地操作另一个计算机,它修改了目标主机的默认网关。

还有,我们还没有检查跳数是否已经修改了,对吧?这个ipconfig命令并不显示这些信息,但我们可以用netsh命令去得到这些信息:

C:\>netsh interface ip show address
Configuration for interface "Local Area Connection"
    DHCP enabled:                         No
    IP Address:                           172.16.11.80
    SubnetMask:                           255.255.255.0
    Default Gateway:                      172.16.11.2
    GatewayMetric:                        5
    InterfaceMetric:                      0
C:\>

没错,它也成功了!

上一页  [1] [2] [3] [4] [5] [6]  [8] [9] [10]  ... 下一页  >> 

第八部分:使用Network Monitor 3.0进行远程脚本故障修复

本文介绍如何使用Network Monitor 3.0修改一个远程脚本的错误,原文发布于WindowsNetworking.com。

在上一篇文章《修复神秘的错误——使用脚本管理Windows网络》中,我们开始修复一个神秘的错误,这个错误发生在我们尝试使用我们开发的脚本ChangeIPAddress.vbs远程地修改一个XP主机的IP地址。这个神秘错误是这样的:

SWbemObjectEx: The remote procedure call failed

在前一篇文章中,我提到我已经联系了一些脚本高手一起解决这个错误,其中我收到最好的答案是可能有一个热补丁(Hotfix)破坏了WMI的功能,结果这个脚本虽然在远程工作了但却产生一个错误。

但是,后来有一个聪明的读者联系我并给了我这样的评论:

“在我看来这不是任何一个热补丁上发生的错误。记住你正在修改XP2的IP地址。远程过程调用失败了是因为它失去了XP2在原来IP地址(172.16.11.43)的连接。然后它花了一段时间(大约1分钟)在新的IP地址上(172.16.11.65)寻找XP2,直到最后放弃了。”

“想象你作为管理员Telnet到一个服务器,然后修改服务器的IP地址。你会失去与服务器连接吗?它会僵死一段时间,这与我们脚本的现象是一样的。但是修改服务器的默认网关将不会打断已存在的(Telnet)连接(假定你在同一个子网内)。如果你尝试从远程位置修改默认网关,你应该也会经历相同的延迟。”

非常对!我们要怎么测试这个解释呢?

使用Network Monitor 3.0

Microsoft最近发布了一个新版本的Network Monitor,一个作为Microsoft Systems Management Server一部分的包探测工具。Network Monitor 3.0比起之前的版本已经有了好几处的改进,诸如以下几项:

●新的功能是,改进了用户界面,当他们正在实时捕捉时能够显示帧;

●多种并发的会话捕捉和多个网络适配器并发捕捉;

●显示网络“会话”的能力,比如,特殊协议的会话;

●支持Vista,Windows XP和Windows Server 2003,包括32位和64位平台;

●新的过滤面板支持手动指定过滤规则。

更多关于Network Monitor 3.0的信息,见Paul Long在TechNet的博客。

然后这是我的计划。我将在运行ChangeIPAddress.vbs脚本的主机上,通过使用NM3捕捉一个网络轨迹。我的测试步骤如下:

Administrator workstation
Name: test124.test.com
IP address: 172.16.11.124 (static)
Target machine
Name: test125.test.com
IP address: 172.16.11.125 (static)
Domain controller
Name: dc181.test.com
IP address: 172.16.11.181

但在我尝试在Test124上运行ChangeIPAddress.vbs来修改test125的IP地址之前,让我们快速地浏览一下NM3。

当你启动NM3时,它的界面是这样的(图1):

 Network Monitor 3.0启动页面

图1:Network Monitor 3.0启动页面

在我继续阐述之前,让我们选择“Enable Conversations”复选框,这样我们就可以浏览每一种在我们跟踪过程中出现的协议的会话。

现在点击“Create A New Capture Tab”。将会打开一个名称为“Capture1”的新标签,我们可以用这个来创建我们的网络跟踪(图2):

打开一个新的捕捉标签 

图2:打开一个新的捕捉标签

现在让我测试NM3的一些简单功能。我们将点击“Play”按钮开始一个捕捉,然后我们将在主机test124上打开命令提示符并输入“ping 172.16.11.125”——我们从主机test124上ping主机test125。结果是这样的(图3):

跟踪对172.16.11.125的ping操作

图3:跟踪对172.16.11.125的ping操作

这就是我们所期待的:2个ARP数据包(一个ARP请求和一个ARP响应),然后是一系列的ICMP数据包(Echo请求消息和Echo回复消息)。如果你知道基本的TCP/IP网络,这会更容易理解。

让我们看看发生的“会话”。展开“My Traffic”节点就可以显示这些会话,如图4所示:

 显示会话

图4:显示会话

注意有两个会话发生:ARP和IPv4(ICMP)。同样,如果你知道基本的TCP/IP网络,很明显,你会相当容易地理解这个。

现在让我们选择ARP请求数据包并查看其内部信息(图5):

 检查一个数据包

图5:检查一个数据包

现在我们已经简单地介绍了NM3(还有更复杂的)。让我们尝试用它来修改我们神秘的错误吧。

捕捉跟踪

我将从重启两个工作站以清除所有缓存(ARP,DNS等)开始,然后我将在test124 打开一个命令提示符,并输入“ChangeIPAddress.vbs 172.16.11.144”,以便将test125的IP地址从172.16.11.125修改成172.16.11.144。(我已经将目标计算机test125写到这个脚本中。)下面就是运行的结果(图6):

 运行ChangeIPAddress.vbs 172.16.11.144的结果

图6:运行ChangeIPAddress.vbs 172.16.11.144的结果

这是所发生的概述:捕捉持续了总共90秒,捕捉到274个帧。错误消息发生在第241个帧,命令提示符在第274帧返回。(我之所以知道这些是因为在跟踪正在捕捉时,我在观察命令行输出。)这里有许多的流量要分析!看一下上面的图6,我们至少可以开始分析它了:

●帧3-4显示主机名TEST125正被DNS转换成IP地址172.16.11.125。

●帧5-6显示IP地址172.16.11.125正被ARP转换成一个MAC地址。

●帧7-9显示一个三向TCP握手(SYN,SYN/ACK,ACK)在test124和test125之间发生。

●帧10-11显示一个ROC绑定正在2个主机间建立。

●帧12-13显示DCOM正在RCP(WMI使用DCOM处理远程调用)间使用。

……等等。

显然我们不能在图中显示所有的274个帧,所以我将Frame Summary信息拷贝到一个文本文件。(我也将捕捉另存为一个.cap文件。)你可以点击这个链接(Frame Summary)查看我们运行ChangeIPAddress.vbs的结果。

这是非常难懂的,不是吗?我们要怎么才能理解这个捕捉正在说什么呢?

当你在修复故障时,最好是从你了解的地方入手,而不是从不懂的地方开始。而我们知道我们在前一篇文章中开发的其他脚本(ChangeGateway.vbs)都是正常工作并不会产生任何错误消息的。所以在我们继续探究ChangeIPAddress.txt之前,让我们重启我们的工作站并执行另一个捕捉,这次显示在test124上运行命令 “ChangeGateway.vbs 172.16.11.2 1”的结果,它将test125的默认网关从172.16.11.1修改成172.16.11.2(并指定跳数为1)。这是第二次捕捉的结果(图7):

 运行“ChangeGateway.vbs 172.16.11.2 1”的结果
图7:运行“ChangeGateway.vbs 172.16.11.2 1”的结果

你可以从Frame Summary看到这次只有217帧需要分析。

分析ChangeGateway.vbs的捕捉

让我们尝试通过将帧概要(Frame Summary)分成一块块地分析第二个捕捉(运行后不产生任何错误的)。如下所示:

1          0.000000                                             NetmonFilter   NetmonFilter: Updated Capture Filter: None
2          0.000000                                             NetworkInfo    NetworkInfo: Network info for TEST124, Network Adapter Count = 1

这只是NM3的头信息——可以忽略它。

3          0.000000         {DNS:3, UDP:2, IPv4:1}        172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0x4275, QUERY (Standard query), Query  for  124.11.16.172.in- addr.arpa of type SOA on class Internet
4          1.281250         {ARP:4}          172.16.11.181 172.16.11.1     ARP     ARP: Request, 172.16.11.181 asks for 172.16.11.1
5          1.890625         {DNS:6, UDP:5, IPv4:1}        172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0xEB6E, QUERY (Standard query), Query  for  test125.test.local of type Host Addr on class Internet
6          1.890625         {DNS:6, UDP:5, IPv4:1}        dc181.test.local           172.16.11.124 DNS    DNS: QueryId = 0xEB6E, QUERY (Standard query), Response - Success 
7          1.906250         {ARP:7}          172.16.11.124 172.16.11.125 ARP     ARP: Request, 172.16.11.124 asks for 172.16.11.125
8          1.906250         {ARP:7}          172.16.11.125 172.16.11.124 ARP     ARP: Response, 172.16.11.125 at 00-11- D8-E3-EC-84

这是名称和地址解析信息(DNS和ARP)

9          1.906250         {TCP:9, IPv4:8}          172.16.11.124 test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441244938, Ack=0, Win=65535 (scale factor 0) = 65535
10        1.906250         {TCP:9, IPv4:8}          test125.test.local          172.16.11.124 TCP     TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1069, Len=0, Seq=871910569, Ack=1441244939, Win=65535 (scale factor 0) = 65535
11        1.906250         {TCP:9, IPv4:8}          172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441244939, Ack=871910570, Win=65535 (scale factor 0) = 65535

Test124刚刚与Test125建立一个TCP连接。

12        1.906250         {MSRPC:10, TCP:9, IPv4:8} 172.16.11.124 test125.test.local          MSRPC           MSRPC: c/o Bind:  UUID{99FCFEC4-5260-101B- BBCB-00AA0021347A} DCOM-IObjectExporter  Call=0x1  Assoc Grp=0x0  Xmit=0x16D0  Recv=0x16D0 
13        1.906250         {MSRPC:10, TCP:9, IPv4:8} test125.test.local          172.16.11.124 MSRPC           MSRPC: c/o Bind Ack:  Call=0x1  Assoc Grp=0x32E9  Xmit=0x16D0  Recv=0x16D0 
14        1.906250         {MSRPC:10, TCP:9, IPv4:8} 172.16.11.124 test125.test.local          DCOM            DCOM
15        1.906250         {MSRPC:10, TCP:9, IPv4:8} test125.test.local          172.16.11.124 DCOM            DCOM

Test124建立一个与Test125绑定的RCP并调用DCOM。

提示:如果你对理解这个跟踪的RPC部分存在困难的话,可以链接see KB 159258 for help。

16        1.921875         {TCP:11, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0, Seq=3003512395, Ack=0, Win=65535 (scale factor 0) = 65535
17        1.921875         {TCP:11, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1070, Len=0, Seq=4088700167, Ack=3003512396, Win=65535 (scale factor 0) = 65535
18        1.921875         {TCP:11, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0, Seq=3003512396, Ack=4088700168, Win=65535 (scale factor 0) = 65535

这个是主机间的另一个TCP三向的握手。

19        1.921875         {UDP:12, IPv4:1}       172.16.11.124 dc181.test.local           KerberosV5     KerberosV5: TGS Request Realm: TEST.LOCAL Sname: RPCSS/test125.test.local 
20        1.921875         {UDP:12, IPv4:1}       dc181.test.local           172.16.11.124 KerberosV5     KerberosV5: TGS Response Cname: Administrator 

Kerberos身份验证(2个主机都是域联结的)。

21        1.921875         {MSRPC:13, TCP:11, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Bind:  UUID{000001A0-0000-0000- C000-000000000046} DCOM-IRemoteSCMActivator  Call=0x2  Assoc Grp=0x32E9  Xmit=0x16D0  Recv=0x16D0 
22        1.921875         {ARP:14}        172.16.11.181 172.16.11.125 ARP     ARP: Request, 172.16.11.181 asks for 172.16.11.125
23        1.921875         {MSRPC:13, TCP:11, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Bind Ack:  Call=0x2  Assoc Grp=0x32E9  Xmit=0x16D0  Recv=0x16D0 
24        1.921875         {MSRPC:13, TCP:11, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{000001A0-0000-0000- C000-000000000046} DCOM-IRemoteSCMActivator  Call=0x2 
25        1.921875         {MSRPC:13, TCP:11, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x2  Assoc Grp=0x32E9  Xmit=0x16D0  Recv=0x16D0 
26        1.921875         {MSRPC:13, TCP:11, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
27        1.937500         {MSRPC:13, TCP:11, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM

这是更多的RPC和DCOM。我认为“Alter Cont”表示正在使用替代的上下文,但我不能保证是这样的。同样的,既然脚本已经正常工作并不产生任何错误,那么一切运行就必然是OK的。

28        1.937500         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1072, DstPort=1117, Len=0, Seq=3011418470, Ack=0, Win=65535 (scale factor 0) = 65535
29        1.937500         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: Flags=.S..A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554832695, Ack=3011418471, Win=65535 (scale factor 0) = 65535
30        1.937500         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011418471, Ack=554832696, Win=65535 (scale factor 0) = 65535

这里是另外一个TCP握手。

31        1.937500         {UDP:16, IPv4:1}       172.16.11.124 dc181.test.local           KerberosV5     KerberosV5: TGS Request Realm: TEST.LOCAL Sname: TEST125$ 
32        1.937500         {UDP:16, IPv4:1}       dc181.test.local           172.16.11.124 KerberosV5     KerberosV5: TGS Response Cname: Administrator 

这是更多的Kerberos信息。

33        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Bind:  UUID{00000143-0000-0000- C000-000000000046} DCOM-IRemUnknown2  Call=0x1  Assoc Grp=0x0  Xmit=0x16D0  Recv=0x16D0 
34        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Bind Ack:  Call=0x1  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
35        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{00000143-0000-0000- C000-000000000046} DCOM-IRemUnknown2  Call=0x1 
36        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x1  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
37        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
38        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
39        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{D4781CD6- E5D3-44DF-AD94-930EFE48A887} WMI-IWbemLoginClientID  Call=0x2 
40        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x2  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
41        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
42        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
43        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{F309AD18- D86A-11D0-A075-00C04FB68820} WMI-IWbemLevel1Login  Call=0x3 
44        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x3  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
45        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
46        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
47        1.937500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
48        1.937500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
49        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{9556DC99-828C- 11CF-A37E-00AA003240C7} WMI-IWbemServices  Call=0x5 
50        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x5  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
51        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
52        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
53        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
54        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
55        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{1C1C45EE- 4395-11D2-B60B-00104B703EFD} WMI-IWbemFetchSmartEnum  Call=0x7 
56        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x7  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
57        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
58        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
59        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{423EC01E- 2E35-11D2-B604-00104B703EFD} WMI-IWbemWCOSmartEnum  Call=0x8 
60        1.953125         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x8  Assoc Grp=0x333D  Xmit=0x16D0  Recv=0x16D0 
61        1.953125         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
62        2.015625         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM

这里还有许多的RPC/DCOM信息。看起来很奇怪,对吗?如何你仔细观察你会看到有一些WMI信息出现,如WMI-IWbemLoginClientID,WMI-IWbemLevel1Login, WMI-IWbemServices,WMI-IWbemFetchSmartEnum等等。搜索MSDN我们会知道更多关于这里的具体细节。比如,Microsoft Developer Network库告诉我们“IWbemServices接口是客户和提供者用于访问WMI服务的”,所以看起来似乎所有这些I-thingies都是 WMI接口(API),而这些接口是在我们运行脚本的工作站上的远程主机(使用DCOM)正在调用的。并且事实上这些接口中有一些似乎没有文档化,所以我们将不用太着急去理解它们。

从这里开始东西变得越来越多。首先会有更多的TCP信息和ROC“Continued Response”数据包,这些数据包似乎暗示之前建立的连接正在被用于某些用途。我准备从跟踪的下一部分开始忽略一些帧:

63        2.015625         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: [Continuation to O2]Flags=....A..., SrcPort=1117, DstPort=1072, Len=1460, Seq=554835972 - 554837432, Ack=3011421991, Win=65061 (scale factor 0) = 65061
64        2.015625         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011421991, Ack=554837432, Win=65535 (scale factor 0) = 65535
65        2.015625         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: [Continuation to O2]Flags=....A..., SrcPort=1117, DstPort=1072, Len=1460, Seq=554837432 - 554838892, Ack=3011421991, Win=65061 (scale factor 0) = 65061
66        2.015625         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011421991, Ack=554838892, Win=65535 (scale factor 0) = 65535
67        2.015625         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: [Continuation to O2]Flags=...PA..., SrcPort=1117, DstPort=1072, Len=1449, Seq=554838892 - 554840341, Ack=3011421991, Win=65061 (scale factor 0) = 65061
68        2.015625         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Continued Response: WMI- IWbemWCOSmartEnum  Call=0x8  Context=0x5  Hint=0x198C  Cancels=0x0 
.
.
.
155      2.031250         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 MSRPC            MSRPC: c/o Continued Response: WMI- IWbemServices  Call=0x9  Context=0x3  Hint=0x904  Cancels=0x0 
156      2.031250         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: [Continuation to <>
157      2.031250         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011422236, Ack=554925189, Win=65535 (scale factor 0) = 65535
158      2.031250         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
159      2.031250         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: [Continuation to <>
160      2.031250         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: Flags=....A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554925189, Ack=3011423697, Win=65535 (scale factor 0) = 65535

现在仅仅过去两秒钟而已。现在有一组DCOM信息,随后是使用FIN/ACK来中断TCP连接,所以我猜想这个脚本很可能已经完成它的工作并,并且现在正在清理中:

161      2.062500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
162      2.062500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
163      2.062500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
164      2.062500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
165      2.062500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
166      2.062500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
167      2.062500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
168      2.062500         {MSRPC:17, TCP:15, IPv4:8}           172.16.11.124 test125.test.local          DCOM            DCOM
169      2.062500         {MSRPC:17, TCP:15, IPv4:8}           test125.test.local          172.16.11.124 DCOM            DCOM
170      2.078125         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=F...A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011424421, Ack=554926046, Win=64678 (scale factor 0) = 64678
171      2.078125         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: Flags=....A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554926046, Ack=3011424422, Win=64811 (scale factor 0) = 64811
172      2.078125         {TCP:15, IPv4:8}        test125.test.local          172.16.11.124 TCP     TCP: Flags=F...A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554926046, Ack=3011424422, Win=64811 (scale factor 0) = 64811
173      2.078125         {TCP:15, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011424422, Ack=554926047, Win=64678 (scale factor 0) = 64678
174      2.093750         {TCP:9, IPv4:8}          172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441245035, Ack=871910766, Win=65339 (scale factor 0) = 65339
175      2.093750         {TCP:11, IPv4:8}        172.16.11.124 test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0, Seq=3003514721, Ack=4088701653, Win=65535 (scale factor 0) = 65535
176      2.546875         {TCP:18, IPv4:1}        172.16.11.124 dc181.test.local           TCP     TCP: Flags=.S......, SrcPort=1074, DstPort=DCE endpoint resolution(135), Len=0, Seq=4283854964, Ack=0, Win=65535 (scale factor 0) = 65535
177      2.546875         {TCP:18, IPv4:1}        dc181.test.local           172.16.11.124 TCP     TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1074, Len=0, Seq=2447011944, Ack=4283854965, Win=16384 (scale factor 0) = 16384
178      2.546875         {TCP:18, IPv4:1}        172.16.11.124 dc181.test.local           TCP     TCP: Flags=....A..., SrcPort=1074, DstPort=DCE endpoint resolution(135), Len=0, Seq=4283854965, Ack=2447011945, Win=65535 (scale factor 0) = 65535

现在有一些DNS和LDAP信息出现在Test124和域控制器之间。我不确定为什么有这些信息,但由于太多了,我将略过这些帧中的一些:

179      2.546875         {MSRPC:19, TCP:18, IPv4:1}           172.16.11.124 dc181.test.local           MSRPC            MSRPC: c/o Bind:  UUID{E1AF8308-5D1F- 11C9-91A4-08002B14A0FA} Endpoint Mapper  Call=0x1  Assoc Grp=0x0  Xmit=0x16D0  Recv=0x16D0 
180      2.546875         {MSRPC:19, TCP:18, IPv4:1}           dc181.test.local           172.16.11.124 MSRPC            MSRPC: c/o Bind Ack:  Call=0x1  Assoc Grp=0x7DAD  Xmit=0x16D0  Recv=0x16D0 
181      2.546875         {MSRPC:19, TCP:18, IPv4:1}           172.16.11.124 dc181.test.local           EPM    EPM: Request: ept_map: NDR, Tracking Server Service v1.0, RPC v5, 0.0.0.0:135 (0x87) [DCE endpoint resolution(135)]
182      2.546875         {MSRPC:19, TCP:18, IPv4:1}           dc181.test.local           172.16.11.124 EPM    EPM: Response: ept_map: 0x16C9A0D6 - EP_S_NOT_REGISTERED
183      2.546875         {DNS:21, UDP:20, IPv4:1}    172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0x896A, QUERY (Standard query), Query  for  _ldap._tcp.Default- First-Site._sites.dc._msdcs.test.local of type SRV on class Internet
184      2.546875         {DNS:21, UDP:20, IPv4:1}    dc181.test.local           172.16.11.124 DNS    DNS: QueryId = 0x896A, QUERY (Standard query), Response - Success 
185      2.546875         {LDAP:23, UDP:22, IPv4:1} 172.16.11.124 dc181.test.local           LDAP  LDAP: Search Request, MessageID:4, BaseObject: NULL, SearchScope: base Object, SearchAlias: neverDerefAliases
186      2.546875         {LDAP:23, UDP:22, IPv4:1} dc181.test.local           172.16.11.124 LDAP  LDAP: Search Result Entry, MessageID:4, Status: Success
.
.
.
212      6.546875         {DNS:32, UDP:5, IPv4:1}      172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0x266D, QUERY (Standard query), Query  for  download.windowsupdate.com of type Host Addr on class Internet
213      6.546875         {ARP:4}          172.16.11.181 172.16.11.1     ARP     ARP: Request, 172.16.11.181 asks for 172.16.11.1
214      7.546875         {DNS:32, UDP:5, IPv4:1}      172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0x266D, QUERY (Standard query), Query  for  download.windowsupdate.com of type Host Addr on class Internet
215      8.546875         {DNS:32, UDP:5, IPv4:1}      172.16.11.124 dc181.test.local           DNS    DNS: QueryId = 0x266D, QUERY (Standard query), Query  for  download.windowsupdate.com of type Host Addr on class Internet
216      9.281250         {ARP:4}          172.16.11.181 172.16.11.1     ARP     ARP: Request, 172.16.11.181 asks for 172.16.11.1

到这里,脚本已经结束了,所以我停止了这个跟踪。

分析ChangeIPAddress.vbs的捕捉

我们现在知道了一些关于一个成功的远程脚本的捕捉大概会是什么样子的了:

●一些DNS和ARP信息

●使用三向握手建立TCP会话

●RPC绑定和DCOM

●更多的TCP握手

●Kerberos信息(主机是在同一个域中)

●更多的RPC/DCOM信息

●更多的TCP握手,Kerberos,RPC/DCOM及TCP通信

●更多的DCOM及随后的TCP会话拆除

所有这些仅仅在两秒钟内发生。

现在让我们看看我们对ChangeIPAddress.vbs(远程运行时产生一个RPC错误的脚本)的捕捉,看它与之前的有什么不同。

1          0.000000                                             NetmonFilter   NetmonFilter: Updated Capture Filter: None
2          0.000000                                             NetworkInfo    NetworkInfo: Network info for TEST124, Network Adapter Count = 1

这仅仅是一些Netmon信息。

3          0.000000         {DNS:3, UDP:2, IPv4:1}        test124.test.local          dc181.test.local           DNS    DNS: QueryId = 0x7869, QUERY (Standard query), Query  for  test125.test.local of type Host Addr on class Internet
4          0.000000         {DNS:3, UDP:2, IPv4:1}        dc181.test.local           test124.test.local          DNS    DNS: QueryId = 0x7869, QUERY (Standard query), Response - Success 
5          0.015625         {ARP:4}          172.16.11.124 172.16.11.125 ARP     ARP: Request, 172.16.11.124 asks for 172.16.11.125
6          0.015625         {ARP:4}          172.16.11.125 172.16.11.124 ARP     ARP: Response, 172.16.11.125 at 00-11- D8-E3-EC-84
7          0.015625         {TCP:6, IPv4:5}          test124.test.local          test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163285, Ack=0, Win=65535 (scale factor 0) = 65535
8          0.015625         {TCP:6, IPv4:5}          test125.test.local          test124.test.local          TCP     TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1063, Len=0, Seq=981335265, Ack=539163286, Win=65535 (scale factor 0) = 65535
9          0.015625         {TCP:6, IPv4:5}          test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163286, Ack=981335266, Win=65535 (scale factor 0) = 65535

这是一个ARP,一个DNS,然后是一个TCP握手——与前面的一样。

10        0.015625         {MSRPC:7, TCP:6, IPv4:5}   test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Bind:  UUID{99FCFEC4-5260-101B- BBCB-00AA0021347A} DCOM-IObjectExporter  Call=0x1  Assoc Grp=0x0  Xmit=0x16D0  Recv=0x16D0 
11        0.015625         {MSRPC:7, TCP:6, IPv4:5}   test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Bind Ack:  Call=0x1  Assoc Grp=0x32EA  Xmit=0x16D0  Recv=0x16D0 
12        0.031250         {MSRPC:7, TCP:6, IPv4:5}   test124.test.local          test125.test.local          DCOM            DCOM
13        0.031250         {MSRPC:7, TCP:6, IPv4:5}   test125.test.local          test124.test.local          DCOM            DCOM
14        0.078125         {TCP:8, IPv4:5}          test124.test.local          test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0, Seq=1367843928, Ack=0, Win=65535 (scale factor 0) = 65535
15        0.078125         {TCP:8, IPv4:5}          test125.test.local          test124.test.local          TCP     TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1064, Len=0, Seq=3625279350, Ack=1367843929, Win=65535 (scale factor 0) = 65535
16        0.078125         {TCP:8, IPv4:5}          test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0, Seq=1367843929, Ack=3625279351, Win=65535 (scale factor 0) = 65535
17        0.078125         {UDP:9, IPv4:1}         test124.test.local          dc181.test.local           KerberosV5            KerberosV5: TGS Request Realm: TEST.LOCAL Sname: RPCSS/test125.test.local 
18        0.078125         {UDP:9, IPv4:1}         dc181.test.local           test124.test.local          KerberosV5            KerberosV5: TGS Response Cname: Administrator 

RPC,DCOM,另一个TCP握手,然后是一些Kerberos信息。它看起来与之前的一样。

19        0.078125         {MSRPC:10, TCP:8, IPv4:5} test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Bind:  UUID{000001A0-0000-0000- C000-000000000046} DCOM-IRemoteSCMActivator  Call=0x2  Assoc Grp=0x32EA  Xmit=0x16D0  Recv=0x16D0 
20        0.093750         {ARP:11}        172.16.11.125 172.16.11.181 ARP     ARP: Request, 172.16.11.125 asks for 172.16.11.181
21        0.093750         {MSRPC:10, TCP:8, IPv4:5} test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Bind Ack:  Call=0x2  Assoc Grp=0x32EA  Xmit=0x16D0  Recv=0x16D0 
22        0.093750         {MSRPC:10, TCP:8, IPv4:5} test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{000001A0-0000-0000- C000-000000000046} DCOM-IRemoteSCMActivator  Call=0x2 
23        0.093750         {MSRPC:10, TCP:8, IPv4:5} test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x2  Assoc Grp=0x32EA  Xmit=0x16D0  Recv=0x16D0 
24        0.093750         {MSRPC:10, TCP:8, IPv4:5} test124.test.local          test125.test.local          DCOM            DCOM
25        0.093750         {MSRPC:10, TCP:8, IPv4:5} test125.test.local          test124.test.local          DCOM            DCOM
26        0.093750         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=.S......, SrcPort=1066, DstPort=1117, Len=0, Seq=1180773456, Ack=0, Win=65535 (scale factor 0) = 65535
27        0.093750         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: Flags=.S..A..., SrcPort=1117, DstPort=1066, Len=0, Seq=539972629, Ack=1180773457, Win=65535 (scale factor 0) = 65535
28        0.093750         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180773457, Ack=539972630, Win=65535 (scale factor 0) = 65535
29        0.093750         {UDP:13, IPv4:1}       test124.test.local          dc181.test.local           KerberosV5            KerberosV5: TGS Request Realm: TEST.LOCAL Sname: TEST125$ 
30        0.109375         {UDP:13, IPv4:1}       dc181.test.local           test124.test.local          KerberosV5            KerberosV5: TGS Response Cname: Administrator 

我们看到相同的模式。

31        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Bind:  UUID{00000143-0000-0000- C000-000000000046} DCOM-IRemUnknown2  Call=0x1  Assoc Grp=0x0  Xmit=0x16D0  Recv=0x16D0 
32        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Bind Ack:  Call=0x1  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
33        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{00000143-0000-0000- C000-000000000046} DCOM-IRemUnknown2  Call=0x1 
34        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x1  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
35        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
36        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
37        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{D4781CD6- E5D3-44DF-AD94-930EFE48A887} WMI-IWbemLoginClientID  Call=0x2 
38        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x2  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
39        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
40        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
41        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{F309AD18- D86A-11D0-A075-00C04FB68820} WMI-IWbemLevel1Login  Call=0x3 
42        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x3  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
43        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
44        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
45        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            
COM
46        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
47        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{9556DC99-828C- 11CF-A37E-00AA003240C7} WMI-IWbemServices  Call=0x5 
48        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x5  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
49        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
50        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
51        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
52        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
53        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{1C1C45EE- 4395-11D2-B60B-00104B703EFD} WMI- IWbemFetchSmartEnum  Call=0x7 54        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x7  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
55        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM
56        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
57        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          MSRPC            MSRPC: c/o Alter Cont:  UUID{423EC01E- 2E35-11D2-B604-00104B703EFD} WMI-IWbemWCOSmartEnum  Call=0x8 
58        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Alter Cont Resp:  Call=0x8  Assoc Grp=0x333E  Xmit=0x16D0  Recv=0x16D0 
59        0.109375         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM

然后一整串的RPC/DCOM信息,与其他跟踪一样的。

60        0.187500         {TCP:6, IPv4:5}          test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163382, Ack=981335462, Win=65339 (scale factor 0) = 65339
61        0.187500         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          DCOM            DCOM
62        0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to O1]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=539975906 - 539977366, Ack=1180776977, Win=65061 (scale factor 0) = 65061
63        0.187500         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180776977, Ack=539977366, Win=65535 (scale factor 0) = 65535
64        0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to O1]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=539977366 - 539978826, Ack=1180776977, Win=65061 (scale factor 0) = 65061
65        0.187500         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180776977, Ack=539978826, Win=65535 (scale factor 0) = 65535
66        0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to O1]Flags=...PA..., SrcPort=1117, DstPort=1066, Len=1449, Seq=539978826 - 539980275, Ack=1180776977, Win=65061 (scale factor 0) = 65061
67        0.187500         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Continued Response: WMI- IWbemWCOSmartEnum  Call=0x8  Context=0x5  Hint=0x198C  Cancels=0x0 
.
.
.
148      0.187500         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Continued Response: WMI- IWbemServices  Call=0x9  Context=0x3  Hint=0x1F84  Cancels=0x0 
149      0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to <>
150      0.187500         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540059825, Win=65535 (scale factor 0) = 65535
151      0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to <>
152      0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to <>
153      0.187500         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540062734, Win=65535 (scale factor 0) = 65535
154      0.187500         {MSRPC:14, TCP:12, IPv4:5}           test125.test.local          test124.test.local          MSRPC            MSRPC: c/o Continued Response: WMI- IWbemServices  Call=0x9  Context=0x3  Hint=0x904  Cancels=0x0 
155      0.187500         {TCP:12, IPv4:5}        test125.test.local          test124.test.local          TCP     TCP: [Continuation to <>
156      0.187500         {TCP:12, IPv4:5}        test124.test.local          test125.test.local          TCP     TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540065123, Win=65535 (scale factor 0) = 65535
157      0.187500         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local          test125.test.local          DCOM            DCOM

这里是RPC和TCP。你可以看到WMI接口的调用。

158      0.218750         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144

这又是什么?脚本已经成功将目标主机(Test125)的IP地址从 172.16.11.125修改成172.16.11.144,那么为什么目标使用ARP去尝试把它自己的IP地址解析成MAC地址呢?这是一个无故的 ARP(Gratuitous ARP),它发生在一个节点向它自己的IP地址发送一个ARP请求的情况下。为了确认它的新IP地址172.16.11.144没有被网络上的其他节点所使用。如果在它发送了几个ARP请求后没有收ARP响应,它就会认定它的新地址在网络中是唯一,然后这个地址将被保留。但如果另一个节点收到ARP请求发送了一个ARP响应,第1个节点就会认定网络上有IP地址冲突,然后它将失效它的IP地址(设为0.0.0.0)。

提示:如果你想要学习更多关于ARP的知识,请阅读Thomas Lee和Joseph Davies的《Microsoft?? Windows?? 2000 TCP/IP Protocols and Services Technical Reference》的第3章“寻址解析协议(Address Resolution Protocol, ARP)”。

这里事情似乎变乱了——你可以发现数据包的时间间隔明显增大。而且接下来似乎还发生了源节点(Test124)不停地尝试向目标发送告知TCP包,但总是到达不了。

159      0.296875         {TCP:8, IPv4:5}         test124.test.local         test125.test.local         TCP     TCP: Flags=....A..., SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0, Seq=1367846254, Ack=3625280836, Win=65535 (scale factor 0) = 65535
160      0.437500         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144
161      0.515625         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local         test125.test.local         DCOM            DCOM
162      1.062500         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local         test125.test.local         DCOM            DCOM
163      1.437500         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144
164      2.265625         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local         test125.test.local         DCOM            DCOM
165      2.453125         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144
166      3.437500         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144
167      4.437500         {ARP:15}       172.16.11.144 172.16.11.144 ARP    ARP: Request, 172.16.11.144 asks for 172.16.11.144
168      4.671875         {MSRPC:14, TCP:12, IPv4:5}           test124.test.local         test125.test.local         DCOM            DCOM

让我们使用NM3仔细地看看第159个数据包。(如图8)

 TCP连接问题

图8:TCP连接问题

从图中我们注意到源主机(Test124)仍然认为目标主机有IP地址172.16.11.125,所以它不停地尝试向Test125主机发送ACK以维持之前建立的连接。

现在让我们看看第161帧(如图9):

 RPC/DCOM问题

图9:RPC/DCOM问题

我们注意到由源主机(Test124)之前建立的与目标主机Tet125的RPC绑定正在尝试使用DCOM去调用Win32_NetworkAdapterConfiguration类的EnableStatic方法。(查看右侧的Hex Details窗口,你可以看到显示为UNICODE文本的RPC包的十六进制负载。)但在尝试使用DCOM时,源主机认为目标主机的IP地址仍然是172.16.11.125(见图中的Frame Details窗口)。

所以看起来那位读者说的是对的!

尝试和分析其余的ChangeIPAddress.vbs捕捉是很有趣的,但看起来我们已经可以判断我们远程脚本不能正常运行的原因了。正如我们在前一篇文章提到的,如果我们使用On Error Resume Next工作区,那么它就能正常工作了。

上一页  [1] [2] [3] [4] [5] [6] [7]  [9] [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第九部分:理解远程脚本

在这一系列中将学习如何使用远程脚本来管理Windows网络的脚本编写基本知识,原文发表于WindowsNetworking.com。

让我们回顾一下目前我们所了解到的关于使用WMI的远程脚本:

在这个系列文章的第六部分“远程脚本初探”一文中,我们尝试修改我们的ChangeIPAddress.vbs脚本,以便我们可以通过它来远程修改计算机的IP地址。通过这个方法我们了解到,我们需要使用“分组策略(Group Policy)”来激活目标计算机上的Windows防火墙的“远程管理例外”,否则脚本将无法工作。虽然最终我们让脚本工作了,但它超时了并且还返回了一个错误。

然后,在第七部分“修复神秘的错误”,我们发现可以在脚本中添加“On Error Resume Next”语句来绕过错误。但是,脚本仍然超时或者是用了很长的时间来完成运行。我向某个脚本高手请教了这个问题,我们对这个错误得到一个初步的解释,但是为了看看问题是否是普遍性的,我们创建了一个新的脚本ChangeGateway.vbs ,并且当我们远程运行此脚本时,它正常工作了。

最后,在第八部分“使用Network Monitor 3.0脚本修复远程脚本故障”,我们的一个读者提出一个简单的可能导致错误的原因:更改远程计算机的IP地址中断了计算机连接,从而导致脚本运行出错并最终超时退出。这听起来很合理,所以,当我们运行脚本时,我们尝试使用Network Monitor 3.0来监测当我们运行脚本会发生什么情况,同时我们确信我们的网络跟踪分析证实这位读者的观点是正确的。

然而,是时候是该回顾一下了。在我们继续更深入地之前,我们应该先学习的一些远程脚本的技术细节。不断地尝试是一件很好的事,但是有时候缺乏足够的知识积累我们就会很容易碰壁了。而学习这些基本知识往往可以帮助我们避免(或绕过去或者跳过去)碰壁。现在就让我们开始吧。

两种类型的远程脚本

确实有两种远程脚本。第一种是当我们在计算机A运行脚本时,脚本以计算机B为目标并在B上执行一些操作。之前我们使用了脚本ChangeIPAddress.vbs来尝试远程脚本,我们是将脚本中的这一行:

strComputer = "."

修改成:

strComputer = "xp2"

如果我们使用上面的第一行,并在计算机A上运行脚本 ,脚本以计算机A为目标(本地计算机或“.”)并修改了计算机A的IP地址。然而,如果我们使用上面的第二行,并在计算机A上运行脚本,脚本将以计算机B为目标(NetBIOS名为“xp2”的计算机)并修改了计算机B的IP地址。

但是,这里还有第二种远程脚本,它是这样运行的:我是登录到计算机A上的管理员,同时,我想使用一个脚本对计算机B上进行一些操作。但是,我想直接在计算机B上运行脚本,而不是在计算机A上运行脚本并计算机B作为脚本的操作目标。因此,我必须将我计算机A上的脚本转移到计算机B上并且在计算机B上运行脚本。如何才能做到这一点?如果我有一个Active Directory环境,那么我可以在远程计算机上尝试将脚本作为一个登录脚本运行。在接下来的文章中我们会研究如何做到这一点,但现在我们只要知道有这两种类型的远程脚本:

●在本地计算机上运行脚本,目标指向另一台远程计算机

●直接在远程计算机上运行脚本

让我们总结一下这2种远程脚本方法之间的区别:

●第一种远程脚本需要连接到远程计算机,然后运行脚本。

●第二类远程脚本需要部署脚本到远程计算机,然后运行脚本。

知道它们的区别了吗?

理解远程脚本连接

现在我们把重点放在第一类型的远程脚本(这在前面的几章中我们所尝试的做法)。一个脚本在本地计算机上运行的然后连接到远程计算机并对它运行操作,这意味着什么呢?这意味着三件事:

●网络连接
        ●用户身份
       ●适当的权限

网络连接

对于要在远程计算机上进行了一些操作的脚本,首先脚本需要与远程计算机建立网络连接。有哪些问题可能会阻止网络连接呢?

首先,可能会有一个域名解析问题。如果我们的脚本不能将远程计算机的主机名或FQDN(Fully-Qualified Domain Name,完整域名)解析为有效的IP地址,那么远程脚本将会运行失败。

第二,可能会有一个防火墙问题。我们在前一篇文章中看到,为了让我们的WMI脚本在远程计算机运行,我们必须打开远程计算机上的Windows防火墙的远程管理例外。如果你现在打开控制面板上的Windows防火墙,并选择“例外”选项卡,你将无法找到一个用来打开防火墙例外的“远程管理”的复选框。这其中的原因当然是,“控制面板”主要是提供给家庭用户来配置防火墙的。在一个Active Directory启用的业务环境下,首选的管理Windows防火墙的方式是使用“分组策略(Group Policy)”。我们在较早前的文章已经提到,我们需要配置的分组策略设置是这样的:

Computer Configuration\Administrative 
Templates\Network\NetworkConnections\Windows Firewall\Domain 
Profile\Windows Firewall: Allow inbound remote administration exception

●当你将这个策略指向一台远程计算机时,它会打开计算机上的两个TCP端口: 445和135 :
TCP端口445是Server Message Block (SMB)流量进入的端口,如果远程计算机上的防火墙关闭了这个端口,那么不仅你无法使用WMI连接它,而且你也无法使用标准的MMC控制台工具来连接它,如Computer Management。所以当端口关闭时,如果你尝试运行脚本操作远程的计算机,你可能会收到隐藏的错误,如“System error 53 has occurred. The network path was not found.”等等。
     ●TCP端口135是Distributed COM (DCOM)流量进入的端口。更具体地说,端口135是DCOM Service Control Manager (SCM )的一个监听端口,它提供了基于RPC的服务用于初始化COM对象等。

概括而言,如果想要从本地计算机运行WMI查询可以成功地使用RCP封装连接到在远程计算机上的WMI服务,并且可以在远程计算机上成功实例化DCOM对象,TCP端口135和445都必须在远程计算机上的防火墙上打开。

用户身份

当你运行一个脚本操作远程计算机时,同时该脚本能够与远程计算机建立网络连接,那么该脚本就能够在远程计算机上执行相应的操作。但是,所执行的操作成功与否取决于在远程计算机上运行该脚本的用户身份。所以举例说,如果我使用普通域用户帐户登录到计算机A上。然后,我运行脚本ChangeIPAddress.vbs操作远程计算机B。脚本使用RPC连接到计算机B的WMI服务上 ,然后它尝试修改计算机B的IP地址。但是结果脚本失败了。这是为什么?那么,到底是谁在远程计算机上尝试执行这个行动呢?是你——而你是一个本地计算机的域用户,当你在默认情况下运行该脚本时,它借用了你的身份,即脚本试图使用你的身份(你的域用户帐户)来执行操作。所以,当脚本试图改变远程计算机的IP地址时,实际上是你,一个域用户,在试图这样执行这个操作。这样做当然会失败,因为修改一个IP地址要求有本地管理员权限。

所以,如果你在计算机A上,以一个域用户登录,同时你还想要用你的脚本来改变计算机B的IP地址。你应该怎么做呢?

其实,你可以硬编码地将远程计算机的本地管理员帐户的密码直接写到我们的脚本中去。换言之,在我们的ChangeIPAddress.vbs脚本上,我们可以这样将:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

替换成:

strUser = "Administrator" strPassword = "Pa$$w0rd" Set objWMIService = GetObject("winmgmts:\\" & amp; strComputer & "\root\cimv2", strUser, strPassword)

问题是,这是不安全的——在你的脚本上,所有的人都可以从脚本中看到以文本方式记录的远程计算机的本地管理员帐户的密码!

如何删掉上面两行代码,然后在脚本运行时,以命令参数传递的形式给变量strUser和 strPassword赋值,是否可行呢?显然这是优于硬编码这些值到脚本上的方法,但是如果有任何人运行网络监测器(如Network Monitor 3.0 ),那么他们可以发现这些本应保密的认证信息,于是你可能又危害了你的远程计算机。

那么如果我们使用runas /user:Administrator cmd.exe运行命令提示符,然后在没有指定其他任何验证的情况下,在命令提示符上运行该脚本,又是否可行呢?这可能是你在需要确保脚本有适当的运行身份(通常是本地管理员的目标计算机)时的远程脚本运行的最好解决方案,尽管这个是有一点麻烦的。当然,你也可以简单地作为一个域管理员帐户登录到工作站,并只需打开一个命令提示符运行该脚本。

适当的权限

现在情况是这样,你正在计算机A上运行你的脚本,而该脚本准备在远程计算机B上执行一些操作。脚本已经和计算机B上的WMI服务建立了网络连接,并且该脚本正以其适当的身份(通常是本地管理员)在计算机B上尝试执行它的操作。那么在这个时候,到底还有什么可能会导致脚本运行失败呢?权限不够!如果脚本正在执行一些由ACL(比如修改文件系统对象或者在Active Directory创建一个对象或者激活DCOM对象)控制的操作,而如果你(脚本所使用的你的身份)没有合适的权限来执行这一行动,该脚本将失败。不幸的是,对于远程脚本来说,这往往是最难的一部分,因为在Windows平台上有NTFS权限、DCOM权限,以及大量的其他类型的权限。另外,你可能有正确的权限组,但是没有特定的权限,如执行一些操作的权限。例如,假设你要使用脚本来清除远程计算机上事件日志,但你的身份缺乏关于该远程计算机的SeSecurityPrivilege。结果会怎么样?你的脚本将失败。

对于远程脚本,还有很多需要学习的,不是吗?在我们的下一篇文章中,我们将继续对这个问题进行阐述。

上一页  [1] [2] [3] [4] [5] [6] [7] [8]  [10]  ... 下一页  >> 

使用脚本程序管理Windows网络 第十部分:远程脚本技巧

你知道可以使用VBScritp编写的WMI脚本吗?它可以帮助你远程管理你的Windows网络。这篇文章详细介绍了两个关于如何使用脚本管理Windows网络的技巧,原文发表在WindowsNetworking.com。

在前面的几篇文章中我们已经学习了关于Windows平台上远程脚本的概念和其他相关知识。在这篇文章中,我们将讨论与使用VBScript编写WMI脚本的远程脚本化相关的两个技巧。

首先,介绍一个来自《Windows Vista工具集》的技巧。这本书是专门针对在大中型企业网络环境中部署Windows Vista的IT人员使用的。我有幸作为主要作者参与这本书的撰写,并且得到Microsoft出版社授权,可以与大家一起分享这本非常棒的书中的一些节选。

技巧一:将Cscript.exe作为默认脚本部署在远程计算机上

第一个技巧,简单却很实用,但我们必须先介绍一些必需的背景知识。我相信大家知道目前有几种方法可以在Windows计算机调用脚本的。例如,如果在一台计算机上有一个脚本ChangeIPAddress.vbs,我们可以这样执行它:

 双击该.vbs文件或它的快捷方式。

 点击“开始”-“运行”,输入“ChangeIPAddress.vbs”后点击“OK”。

 打开命令提示符,转到脚本目录,输入ChangeIPAddress.vbs,回车。

完成这些步骤后出现的结果取决于计算机上的Windows Script Host (WSH)的默认设置。WSH是一个基于脚本引擎的与语言无关的脚本宿主。例如,WSH会使用VBScript脚本引擎运行VBScript脚本,所以WSH是作为脚本运行的“环境”存在的。但WSH实际上有两个默认的脚本宿主:

 Wscript.exe ,它提供了一个基于Windows的对话框用于设置脚本属性,并以窗口形式显示脚本输出。

 Cscript.exe ,它是在命令提示符上配置脚本属性和显示脚本输出。

让我们先看看两者之间的区别。我将使用第二章中的ChangeIPAddress.vbs脚本来演示这个问题。让我们在一个Windows Vista主机上打开命令提示符并使用这个脚本将主机的IP地址修改为172.16.11.173。这里需要注意的第一件事是修改网络配置需要本地主机的管理员权限,所以我需要右击 “附件”中的“命令提示符”快捷方式,选择“以管理员身份运行”。这时会弹出一个“用户帐号控制(UAC)”对话框,我会点击“继续”(如果我当前用户帐号是主机的本地管理员组的成员)或输入一个本地管理员帐号的认证信息(如果我的用户帐号仅仅是本地用户组的成员)。

无论是哪种方法,我都会打开一个管理员运行级别的命令提示符窗口,然后我输入下面的命令去修改主机的地址(图1):

 尝试使用脚本去修改IP地址

图1:尝试使用脚本去修改IP地址

当我按“回车”后,经了几秒钟后会有一个对话框弹出(图2):

 脚本的输出显示在一个对话框中

图2:脚本的输出显示在一个对话框中

这个消息是从什么地方来的?这是因为在我们的ChangeIPAddress.vbs脚本的最后包含有以下几行代码:

'Display result or error code
If errEnableStatic=0 Then
     Wscript.Echo "Adapter's IP address has been successfully changed to " & strAddress
Else
     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStatic
End If

所以结果是Wscript.Echo语句显示一个窗口化的输出(如,弹出一个对话框),而不是在命令提示符窗口中显示输出。这其中的原因是,Wscript.exe是主机默认的脚本宿主,而这就是它的默认处理方法,如:使用像这样的弹出窗口显示所有的脚本输出。

我们怎么能够改变它的这种默认行为而将脚本输出显示在命令提示符中呢?一种方法是显示式地调用命令行脚本宿主Cscript.exe来运行脚本。你可以这样做(图3):

 使用cscript.exe使脚本输出显示在命令提示符窗口中

图3:使用cscript.exe使脚本输出显示在命令提示符窗口中

但像这样每一次都必须在脚本名称前加入Cscript是很麻烦的,所以我们可以将先Cscript.exe设为所有WSH调用的默认脚本宿主,作法是这样:

 将cscript.exe设为默认的脚本宿主

图4:将cscript.exe设为默认的脚本宿主

现在我们可以直接运行脚本并在命令提示符窗口中显示它的结果,而不需要在前面加Cscript了(图5):

 脚本的输出直接显示在命令提示符窗口

图5:在Cscript.exe调为默认的脚本宿主后,脚本的输出直接显示在命令提示符窗口

现在你可能已经完全明白了,但是这里还有一个问题。我们有一批像ChangeIPAddress.vbs这样的脚本是要通过部署在目标主机上远程地运行的,它们是作为使用“分组策略”的登录脚本或启动脚本的。而这其中有一些脚本使用了Wscript.Echo语句去生成脚本输出。如果其中一个这样的脚本部署到远程主机上并在主机上运行,将会怎么样呢?脚本运行后,会有一系列的窗口出现在用户桌面,然后用户将不得不一个个地去点击OK关闭它们,然后才能让脚本继续执行下去。这太麻烦了!有什么办法可以解决这个问题呢?

是的,你可以有两个方法可以选择。第一,你可以编辑脚本,删除或注释掉所有的Wscript.Echo语句,这样脚本就不会产生任何输出。这也是很麻烦的,特别是如果你有大量这样的脚本。

那么第二种方法是什么呢?以下是摘自《Windows Vista工具集》的方法:

在一个使用“分组策略”管理桌面计算机的Active Directory环境中,你可以通过以下的步骤将OU中的所有计算机上的默认脚本宿主从Wscript.exe修改成Cscript.exe:

1.用记事本新建一个文本“ChangeToCscript.bat”,并在其中添加两行代码:

@echo off
cscript //h:cscript //s

2.打开链接到OU的GPO,转到Computer Configuration\Windows Settings\Scripts\Startup。

3.双击“Startup”策略设置,打开它的属性窗口。

4.点击“Show Files”按钮,将ChangeToCscript.bat从Windows资源浏览器拷贝/粘贴到子目录SYSVOL 中,这是启动脚本所在的目录。

5.在“Startup”策略设置的属性窗口中点击“Add”按钮。

6.点击“Browse”按钮并选择ChangeToCscript.bat。

7.关闭所有的属性窗口。

8.添加这个启动脚本到目标主机,会使得在这些计算机重新启动后,它们的默认脚本宿主从Wscript.exe变为Cscript.exe,而且不管对于标准用户还是本地计算机管理员的目标用户是都会生效。

注意:ChangeToCscript.bat必须作为“Startup”脚本运行,而不是“Logon”脚本。如果你把它作为Logon运行,这只会在目标用户是本地计算机管理员时才会有效。你现在已经感觉到使用两行的批处理文件就能解决问题很不错吧?现在你可以部署任何脚本到你的目标计算机,而不用担心用户会在他们的屏幕上碰到大量的窗口了。

技巧二:不需要指定管理员身份直接运行脚本

第二个技巧是一个读者读完我之前的一篇文章后提交给我的。我认为这是一个非常棒的方法,所以我问他是否可以共享给WindowsNetworking.com的其他读者,他同意了。所以我将直接引用他邮件,向大家介绍他提供的技巧:

我不输入身份认证信息而直接执行“运行”的方法是使用本地管理员帐号访问WMI,然后将本地管理员密码存储在一个在网络中共享的文本文件中,它是在受NTFS权限保护的。例如,如果“tech1 ”和“tech4 ”和“ tech5 ”是正常的域帐户(而不是域管理员) ,但这些用户已经被授权运行WMI脚本,那么我将给这些账户NTFS权限来获得包含本地管理员密码的文本文件,这样我就可以这样导入密码并连接:

Set objWMIService = GetObject("winmgmts:\\" & amp; strComputer & "\root\cimv2", strComputer & " \Administrator", strImportedPassword)
Well, the above is not 100% true. I actually use:
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
objSWbemLocator.Security_.Privileges.AddAsString("SeSecurityPrivilege")
Set objWMIService = objSWbemLocator.ConnectServer(strComputer, "root\cimv2", strComputer & amp; "\administrator", strPWD, "", "", &H80)
Set objReg = objSWbemLocator.ConnectServer(strComputer, "root\default", strComputer & amp; "\administrator", strPWD, "", "", &H80)
Set oReg = objReg.Get("StdRegProv")

……这样达成了同样的目标。

连接到本地管理员帐户的方法有另一个有趣的副作用;它不会在PC的“Documents and Settings”目录你的域帐号的帐号信息复本。当使用我的网域帐户时,有几个用户问道:“为什么你连接到我的电脑上?”并且很是怀疑我在窥探什么。通过使用本地管理员帐户,他们不知道有其他人连接(他们是无法看到安全日志)。

关于记录问题,实际中我们有几个不同的本地管理员密码可使用;因此脚本导入用户列表,并试图逐一尝试直到成功或试完所有选择。

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9]   ... 下一页  >>