前言:很多情况下,用户办公地点变更涉及到其办公电脑IP地址变更,同时用户只是普通用户权限,而且不能告诉用户管理员密码。通常我们会利用远程桌面在电脑还未搬离原地的情况下更改IP,如果用户操作系统是win2000或者用户搬迁之前根本未通知网管(别笑,很多企业很多员工就是这样,没把网管放在眼里,有时候我们也不给面子,就让他们把电脑再搬到我们这里来,我们亲自更改),而更多时候我们就得亲自过去更改IP了。
前几日看了一篇文章,有了点儿灵感。经过反复测试发现基本可行。
实验环境:一台主机安装了一个虚拟网卡,初始IP:10.11.12.13 其中10为整个网络IP地址头字段,每台主机IP都是10开头;11代表主机所在vlan;12.13代表主机地址。每台主机更改IP其实就是更改vlan字段以及对应网关,其它字段不变。为了测试方便,脚本中规定如果主机属于vlan 11,就更改为vlan 35,如果属于vlan 35,再更改回vlan 11,这样方便我反复测试。
解决途径:普通用户界面下肯定无法更改IP,所以需要借助runas 命令,但是runas命令需要提示输入管理员密码,所以需要事先将密码写入脚本中。同时虽然普通批处理脚本可以更改IP,但是无法自动获取变量,所以需要借助VBS脚本,通过 WMI 类 Win32_NetworkAdapterConfiguration 提供的属性和方法,获取当前IP,从而得到当前vlan和主机地址。
附
Win32_NetworkAdapterConfiguration IP 地址分配属性
属性 |
类型 |
说明 |
DefaultIPGateway |
字符串数组 |
计算机系统使用的默认网关的 IP 地址数组。 |
DHCPEnabled |
布尔 |
如果是 True,DHCP 服务器会在建立网络连接时自动为计算机系统分配一个 IP 地址。 |
DHCPLeaseExpires |
datetime |
DHCP 服务器为计算机分配的租用 IP 地址的到期日期和时间。 |
DHCPLeaseObtained |
datetime |
DHCP 服务器为计算机分配的 IP 地址获得租约的日期和时间。 |
DHCPServer |
字符串 |
DHCP 服务器的 IP 地址。 |
GatewayCostMetric |
Uint16 |
用于计算最快、最可靠或最廉价路由的整数成本跃点数值(从 1 到 9999)数组。这个参数与 DefaultIPGateway 属性之间存在一一对应关系。 |
IPConnectionMetric (Windows XP 的新增属性) |
Uint32 |
绑定了 IP 的适配器的已配置路由的使用成本;对于 IP 路由表中的路由来说,这是一个加权值。如果在 IP 路由表中有多个指向目标计算机的路由,将使用跃点数最少的路由。默认值是 1。 |
IPAddress |
字符串 |
与当前网络适配器相关的所有 IP 地址构成的数组。 |
IPSubnet |
字符串 |
与当前网络适配器相关的所有子网掩码构成的数组。 |
上表中的所有属性都是只读的。类型 uint16 和 uint32 是由强类型编程语言使用的无符号整数类型;VBScript 可将它们有效地作为整数进行处理。
Win32_NetworkAdapterConfiguration IP 地址分配方法
方法 |
参数 |
说明 |
EnableDHCP |
无 |
为使用这个网络适配器的服务启用 DHCP。DHCP 允许动态分配 IP 地址。 |
EnableStatic |
IPAddress – 字符串数组 SubnetMask – 字符串数组 |
为目标网络适配器启用静态 TCP/IP 寻址。这样便会对此网络适配器禁用 DHCP。 |
ReleaseDHCPLease |
无 |
释放已绑定到启用了 DHCP 的特定网络适配器的 IP 地址。 警告 如果在本地计算机上启用 DHCP,该选项会对这个特定的网络适配器禁用 TCP/IP。如果您没有访问目标系统的其他路径(即另一个绑定 TCP/IP 的网络适配器),所有 TCP/IP 通信都会中断。 |
ReleaseDHCPLeaseAll |
无 |
静态方法。释放已绑定到所有启用了 DHCP 的网络适配器的 IP 地址。 警告 如果在本地计算机上启用 DHCP,此选项将终止所有的 DHCP TCP/IP 连接。 |
RenewDHCPLease |
无 |
续订启用了 DHCP 的特定网络适配器上的 IP 地址。DHCP 服务器分配的 IP 地址的租约有一个截止日期;如果客户端打算继续使用分配的 IP 地址,就必须进行续订。 |
RenewDHCPLeaseAll |
无 |
静态方法。续订所有启用了 DHCP 的网络适配器的 IP 地址。DHCP 服务器分配的 IP 地址的租约有一个截止日期;如果客户端打算继续使用分配的 IP 地址,就必须进行续订。 |
SetGateways |
DefaultIPGateway – 字符串数组 GatewayCostMetric – unit16 |
指定一个网关列表,这些网关用于将数据包路由到该网络适配器连接的子网以外的子网。该方法仅在网络适配器处于静态 IP 模式时才有效。 |
上表中的所有方法都返回一个正整数:
? |
0 表示成功完成。 |
? |
1 表示成功完成,并需要重新启动。 |
? |
大于 1 的数字表示出现了某种问题,方法无法完成。WMI SDK 列出了这些方法的返回值的含义。 |
解决步骤:
1、 建立run.bat
@echo off
ECHO.set sh=WScript.CreateObject("WScript.Shell")>_TEMP.VBS
ECHO.WScript.Sleep 1000 >>_TEMP.VBS
ECHO.sh.SendKeys "runas /env /user:bl\run" >>_TEMP.VBS
ECHO.WScript.Sleep 1000 >>_TEMP.VBS
ECHO.sh.SendKeys " ""wscript //nologo \"".\chgip.vbs\""""" >>_TEMP.VBS
ECHO.WScript.Sleep 1000 >>_TEMP.VBS
ECHO.sh.SendKeys "{enter}" >>_TEMP.VBS
ECHO.WScript.Sleep 5000 >>_TEMP.VBS
ECHO.sh.SendKeys "1234" >>_TEMP.VBS
ECHO.sh.SendKeys "{enter}" >>_TEMP.VBS
start /B cmd.EXE
cscript //nologo _TEMP.VBS
del _temp.vbs
其中 bl\run 为域管理员账号,1234为要输入的密码
在这里遇到的主要问题就是在输入密码后,sleep的时间不好掌握,建议不要将管理员密码设置过长,否则会出现密码还未输入完毕,已经执行下一条指令(输入回车),导致密码输入错误。到现在为止我还没发现更好的解决办法,希望有人可以继续研究。
2、 建立chgip.vbs
On Error Resume Next
dim vlan,endip
strComputer = "."
intReboot = 0
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colNicConfigs = objWMIService.ExecQuery _
("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each objNicConfig In colNicConfigs
WScript.Echo VbCrLf & " Network Adapter " & objNicConfig.Index & _
VbCrLf & " " & objNicConfig.Description & VbCrLf
if left(objNicConfig.IPAddress(i),5)="10.11" Then
vlan=mid(objNicConfig.IPAddress(i),4,2)
endip=mid(objNicConfig.IPAddress(i),6,len(objNicConfig.IPAddress(i))-5)
arrIPAddresses = Array("10.35" & endip)
arrSubnetMasks = Array("255.255.0.0")
arrGateWays = Array("10.35.1.254")
WScript.Echo " 网络地址更改中......"
intReturn = objNicConfig.EnableStatic(arrIPAddresses, arrSubnetMasks) + objNicConfig.SetGateways(arrGateWays)
If intReturn = 0 Then
strIPAddresses = Join(arrIPAddresses, ",")
strSubnetMasks = Join(arrSubnetMasks, ",")
WScript.Echo " 网络地址更改为:" & _
VbCrLf & " IP Addresses: " & strIPAddresses & VbCrLf & _
" Subnet Masks: " & strSubnetMasks
ElseIf intReturn = 1 Then
intReboot = intReboot + 1
WScript.Echo " 网络地址已更改 " & _
VbCrLf & " 系统需要重新启动"
Else
WScript.Echo " 无法更改网络地址,请联系信息工程处"
End If
Elseif left(objNicConfig.IPAddress(i),5)="10.35" Then
vlan=mid(objNicConfig.IPAddress(i),4,2)
endip=mid(objNicConfig.IPAddress(i),6,len(objNicConfig.IPAddress(i))-5)
arrIPAddresses = Array("10.11" & endip)
arrSubnetMasks = Array("255.255.0.0")
arrGateWays = Array("10.10.1.254")
WScript.Echo " 网络地址更改中......"
intReturn = objNicConfig.EnableStatic(arrIPAddresses, arrSubnetMasks) + objNicConfig.SetGateways(arrGateWays) If intReturn = 0 Then
strIPAddresses = Join(arrIPAddresses, ",")
strSubnetMasks = Join(arrSubnetMasks, ",")
WScript.Echo " 网络地址更改为:" & _
VbCrLf & " IP Addresses: " & strIPAddresses & VbCrLf & _
" Subnet Masks: " & strSubnetMasks
ElseIf intReturn = 1 Then
intReboot = intReboot + 1
WScript.Echo " 网络地址已更改 " & _
VbCrLf & " 系统需要重新启动"
Else
WScript.Echo " 无法更改网络地址,请联系信息工程处"
End If
else
WScript.Echo " 网络地址无需更改"
End If
Next
If (intReboot > 0) Then
WScript.Echo VbCrLf & "系统需要重新启动以保证启用所有更改 "
End If
3、 利用winrar创建自解压文件
按理说做步骤2就可以了,为了让很基础的普通用户不去阅读run.bat内容,以保护写在内部的管理员密码,特意创建一个自解压文件,每次自解压之后自动运行run.bat。当然对于高级用户而言,这种方法颇有掩耳盗铃之嫌了。
评论