PowerShell2.0之维护网络(三)设置网络适配器


如果计算机中有多个网络适配器,在Windows原有的cmd下配置其属性很困难,用户必须确保配置了适当的适配器并确认要禁用的不是正在使用中的网络适配器。本节介绍在处理多个网络适配器时可能出现的问题及其解决方法。

(1)检测多个网络适配器

对于Windows系统来说,操作系统会将无线网络放在所有网络连接中优先级最高的网络使用。这对于普通用户可能是很方便的,一旦周围有无线网络就可以自动连接到无线网络中,便捷而有效。但是对于网络管理员来说这个特性可能会带来麻烦,甚至是安全问题。如出差在外的人员无法通过所在地的有线网络访问Internet。Windows Vista通常会建议启用无线网络适配器来上网,而如果听从了这个建议,并连接到不安全的网络,如图1所示,计算机可能存在很大的安全威胁。

image

图1 连接到不安全的网络

创建一个名为“GetNetID.ps1”的脚本显示连接到本地计算机的网络适配器名称、接口索引编号、适配器信息及其介质形式,这些属性对于创建资产清单非常有用。该脚本的代码如下:

Get-WmiObject -Class win32_networkadapter |

format-table -Property name, interfaceIndex, `

adapterType, macAddress –autosize

该脚本中通过使用Get-WmiObject cmdlet并检索Win32_NetWorkAdapter WMI类信息,最后将输出的信息通过管道传递给Format-Table cmdlet格式化输出的内容,而仅限定输出Name、InterfaceIndex、AdapterType及MacAddress属性。-autosize参数可以配合Format-Table使用,以进一步整理输出内容并调整显示方式,执行结果如图2所示。

image

图2 执行结果

(2)将网络适配器信息写入Excel文件

当系统中有多个网络适配器时通过控制台查看这些网络适配器的信息会显得信息量太大,无法细致地查看和处理,这时需要将信息写入到Excel文件中。创建名为“WriteNetworkAdapterInfoToExcel.ps1”的脚本获得安装在本地计算机上所有网络适配器的配置信息,并写入本地的Excel文件中便于后期分析,其代码如下:

$strPath="C:\PowerShell\CHAPTER18\netAdapter.xls"

$objExcel=New-Object -ComObject Excel.Application

$objExcel.Visible=-1

$WorkBook=$objExcel.Workbooks.Add()

$sheet=$workbook.worksheets.item(1)

$x=2

$Computer = $env:computerName

$objWMIService = Get-WmiObject -class win32_NetworkAdapter `

-computer $Computer

for($b=1 ; $b -le 10 ; $b++)

{$sheet.Cells.item(1,$b).font.bold=$true}

$sheet.Cells.item(1,1)=("Name of Adapter")

$sheet.Cells.item(1,2)=("Interface Index")

$sheet.Cells.item(1,3)=("Index")

$sheet.Cells.item(1,4)=("DeviceID")

$sheet.Cells.item(1,5)=("AdapterType")

$sheet.Cells.item(1,6)=("MacAddress")

$sheet.Cells.item(1,7)=("netconnectionid")

$sheet.Cells.item(1,8)=("NetConnectionStatus")

$sheet.Cells.item(1,9)=("NetworkAddresses")

$sheet.Cells.item(1,10)=("PermanentAddress")

ForEach ($objNet in $objWMIService)

{

$sheet.Cells.item($x, 1)=($objNet.Name)

$sheet.Cells.item($x, 2)=($objNet.InterfaceIndex)

$sheet.Cells.item($x, 3)=($objNet.index)

$sheet.Cells.item($x, 4)=($objNet.DeviceID)

$sheet.Cells.item($x, 5)=($objNet.adapterType)

$sheet.Cells.item($x, 6)=($objNet.MacAddress)

$sheet.Cells.item($x,7)=($objNet.netconnectionid)

$sheet.Cells.item($x,8)=($objNet.NetConnectionStatus)

$sheet.Cells.item($x,9)=($objNet.NetworkAddresses)

$sheet.Cells.item($x,10)=($objNet.PermanentAddress)

If($objNet.AdapterType -notMatch ‘ethernet’)

{

$sheet.Cells.item($x,5).font.colorIndex=3 # 32 is blue 16 silver/gray 8 is Aqua, 4 is green, 3 is red

$sheet.Cells.item($x,5).font.bold=$true

}

$x++

}

$range = $sheet.usedRange

$range.EntireColumn.AutoFit()

IF(Test-Path $strPath)

{

Remove-Item $strPath

$objExcel.ActiveWorkbook.SaveAs($strPath)

}

ELSE

{

$objExcel.ActiveWorkbook.SaveAs($strPath)

}

能够看到上述脚本中网络适配器信息的代码量很少,大多数代码主要是关于对Excel文件的操作方法。在通过PowerShell操作Excel之前需要指定Excel文件的存放路径,在该脚本中将其放在$strPath变量中。随后创建一个Excel.Application COM对象的实例,用于创建和操作Excel表格。为操作Excel模块,将保存在$objExcel变量中的Excel.Application对象的Visible属性设置为-1,表示窗口可见。然后在Excel中添加一个新的工作簿,打开第1个工作表并将引用信息保存在$sheet变量中。为此需要引用新创建并保存在$workbook变量中的新工作簿对象,然后使用item方法返回第1个工作表。

接下来声明变量$x,并赋值为2,指定从第2行开始写。随后为了在WMI查询中能够使用计算机名,进入env:\这个PS的驱动器中并获得用于保存计算机名的环境变量computerName的值保存在$Computer变量中。其后使用Get-WmiObject cmdlet查询Win32_NetworkAdapter WMI类,查询得到的Management对象保存在$objwmiService变量中。

下一段代码为从WMI中获得的每个属性提供标题行,这里使用for循环指定需要用粗体显示的行。为了将该行标题显示为粗体,将该字体的Bold属性设置为True。设置标题后使用Foreach语句在WMI对象之间遍历,以找出所需的特定信息并将其插入到相应的列中。这里使用item方法来引用相应的单元格,需要为该方法提供横轴和纵轴的坐标信息,以使光标在单元格中定位。为了让操作过程简单而便捷,这里使用变量$x跟踪要写入的行。通过改变其值来移动光标,特定的纵轴指定保存特定数据的列。检查网络适配器为以太网适配器或其他类型的最简单方法是检查Win32_NetworkAdapter WMI类中的AdapterType属性,该脚本的目的是标记非以太网适配器,所以使用-notmatch操作符比较适配器类型。如果适配器类型不是“ethernet”(以太网),则改变字体的颜色并用粗体显示。处理每一条网络适配器记录后使用递增运算符++使$x变量值递增,这样随后的一条适配器信息才可写入表格的下一行。

创建并显示整个表后,通常需要必要改变列宽以显示完整的信息。为此在该脚本中使用AutoFit()方法用于表格内特定范围内的列对象,定义范围的简单方法是使用工作表对象的UseRange属性。

规整表格内容和格式之后,务必保存当前文档。如果工作簿已经存在,则将其删除,然后将工作表保存在新的工作簿中;否则直接将工作表保存为新工作簿。该脚本执行后的工作簿如图3所示。

image

图3 脚本执行后的工作簿

(3)识别已连接的网络适配器

多重网络环境在提供了便利的同时,也给计算机安全带来极大的威胁。计算机系统中多个网络一旦被桥接,而网络中又存在安全和不安全的网络,则恶意用户可以通过这种网桥攻击安全网络。

对于复杂网络环境下的计算机,多重网络环境在提供便利的同时,也给计算机带来了极大的威胁。计算机系统中多个网络一旦被桥接起来,而网络中又存在安全和不安去的网络,恶意用户可以通过这种网桥对安全网络进行攻击。这就会给安全网络造成很大的威胁。

为了避免由于复杂网络环境下可能由网络适配器桥接造成的安全风险,创建名为“FindConfigurationOfConnectedAdapters.ps1”的脚本识别连通多个计算机的网络适配器。该脚本仅返回已经连通的网络适配器的数据,如果没有活动连接,则不会返回任何数据。该脚本的代码如下:

$computer="localhost"

$connected=2

Get-WmiObject -Class win32_networkadapter -computername $computer `

-filter "netconnectionstatus = $connected" |

foreach-object `

{

Get-WmiObject -Class win32_networkadapterconfiguration `

-computername $computer -filter "Index = $($_.deviceID)"

}

该脚本使用了两个WMI类,其中Win32_NetworkAdapter WMI类具有名为“Connected”的属性,而Win32_NetworkAdapterConfiguration WMI类则无。

该脚本首先定义变量$compute用于执行WMI查询,$connected用于显示NetConnectionStatus属性值表示计算机是否已经连接。随后查询Win32_NetworkAdapter类,这样可获得一个可以代表网络适配器是否连接的Management对象。如果只希望已经连接的网络适配器的信息,则可以使用-filter参数。这些信息会通过管道命令发送到Foreach-Object cmdlet,在其中查询Win32_NetworkAdapterConfiguration类。并使用筛选器查询上文中筛选后的网络适配器,适配器可以通过当前管道对象的DeviceID识别。

(4)设置静态IP地址

很多时候,网络管理员需要为网络设备指定静态IP,以便有效地管理服务器。尽管在如图4所示的“Internet协议(TCP/IP)属性”对话框中很容易设置静态IP地址,但是设置大量服务器则比较麻烦。

image

图4 “Internet协议(TCP/IP)属性”对话框

PowerShell可以使用Win32_NetworkAdapterConfiguration WMI类中包括的14个方法,创建名为“SetStaticIP.ps1”的脚本中演示其中的3个方法。

该脚本的代码如下:

param($computer="localhost",$q,$ip,$sm,$dg,$dns,$help)

function funHelp()

{

$helpText=@"

DESCRIPTION:

NAME: SetStaticIP.ps1

Sets a static IP address on a local or remote machine.

PARAMETERS:

-computerName Specifies the name of the computer upon which to run the script

-q Queries all IP bound network adapters

-ip IP address to use

-sm Subnet mask to use

-dg Default gateway to use

-dns Dns server to use

-help prints help file

SYNTAX:

SetStaticIP.ps1 -q "yes" -computer WebServer

Lists all the network adapters bound to IP on a computer named WebServer

SetStaticIP.ps1

Lists all the network adapters bound to IP on local computer

SetStaticIP.ps1 -ip "10.0.0.1" -sm "255.0.0.0" -dg "10.0.0.5" -dns "10.0.0.2"

Sets the Ip address to 10.0.0.1 and the subnet mask to 255.0.0.0 and the default

Gateway to 10.0.0.5 with a dns server of 10.0.0.2 on the local machine

SetStaticIP.ps1 -help ?

Displays the help topic for the script

"@

$helpText

exit

}

function FunEvalRTN($rtn)

{

Switch ($rtn.returnvalue)

{

0 { Write-Host -foregroundcolor green "No errors for $strCall" }

66 { Write-Host -foregroundcolor red "$strCall reports" `

" invalid subnetMask" }

70 { Write-Host -ForegroundColor red "$strCall reports" `

" invalid IP" }

71 { Write-Host -ForegroundColor red "$strCall reports" `

" invalid gateway" }

91 { Write-Host -ForegroundColor red "$strCall reports" `

" access denied"}

96 { Write-Host -ForegroundColor red "$strCall reports" `

" unable to contact dns server"}

DEFAULT { Write-Host -ForegroundColor red "$strCall service reports" `

" ERROR $($rtn.returnValue)" }

}

$rtn=$strCall=$null

}

if($help) { funhelp }

if($q)

{

Get-WmiObject -Class win32_networkadapterconfiguration `

-computer $computer -filter "ipenabled = ‘true’"

exit

}

if(!$ip) { funhelp }

if(!$sm) { funhelp }

if(!$dg) { funhelp }

if(!$dns) { funhelp }

$global:RTN = $null

$metric = [int32[]]1

$objWMI = Get-WmiObject -Class win32_networkadapterconfiguration `

-computer $computer -filter "ipenabled = ‘true’"

$RTN=$objwmi.EnableStatic($ip, $sm)

$strCall="enable static IP and subnet mask"

FunEvalRTN($rtn)

$RTN=$objwmi.SetGateways($dg, $metric)

$strCall="enable set default gateway and metric"

FunEvalRTN($rtn)

$RTN=$objwmi.SetDNSServerSearchOrder($dns)

$strCall="Set the dns server search order"

FunEvalRTN($rtn)

在脚本中定义了FunEvalRTN函数,用于判断调用不同的WMI方法以配置IP地址后返回的代码。在该函数内部使用switch语句判断返回代码的ReturnValue属性,如果ReturnValue的值是0,表示没有出错。而其他值均代表命令没有成功完成。

Ø 0:没有错误,正常完成操作。

Ø 66:错误的子网掩码。

Ø 70:非法IP。

Ø 71:非法的网关。

Ø 91:访问被拒绝。

Ø 96:不能连接到DNS服务器。

Ø default 表示出现错误,但错误不在上述情况。

如果希望返回的字符串包括更多信息,那么可以包括一个变量$strCall,其中包括生成ReturnValue调用的方法名称。

该脚本会检查-q参数,如果存在该参数堆栈中会存在$q变量,脚本运行WMI查询并显示所有启用IP地址的网络适配器信息。在设置相关网络参数时要求相关参数不能为空;否则将无法设置IP信息,并调用funhelp函数获得帮助信息。

随后使用$global标记生成全局变量,并使其名称成为全局性的。为了以数组形式保存存在的网关地址,在脚本中使用[int32]类型约束符,以保证输入的数字是int32数据类型。然后在类型约束符内部插入一对空的方括号标示对约束符的调用,接下来将数组指定给方法调用中使用的变量$metric。此脚本的执行结果如图5所示。

image

图5 执行结果

由于Windows Vista和Windows Server2008与Windows XP之间的网络WMI模型已经存在很大的区别,并且该脚本中使用的EnableStatic()、SetGateways()和SetDNSServerSearchOrder()等方法均是Vista以后操作系统中的新增方法,所以这个脚本仅适用于Vista以上版本的Windows操作系统中的PowerShell。

(5)启用DHCP

除了可以对网络适配器绑定IP外,还可以使用DHCP(Dynamic Host Configuration Protocol)服务器获取IP地址,启用DHCP的目的就是为了防止由于静态地址绑定而造成对网络地址的大量占用。DHCP的工作原理一般分为4步,即客户端查找DHCP Server、Server提供IP租用地址、客户端接受IP租约和租约确认。服务器之类的计算机需要指定IP地址;否则一旦IP地址被更换,用户将无法连接到服务器。比较好的策略就是为服务器预留一定得地址段,为服务器绑定IP地址,而PC则可以使用DHCP获取IP地址。

创建名为“WorkWithDHCP.ps1”的脚本用于报告DHCP状态、启用DHCP、释放由DHCP分配的IP地址,并更新由DHCP分配的IP地址,其代码如下:

param($computer="localhost",$action,$help)

function funHelp()

{

$helpText=@"

DESCRIPTION:

NAME: WorkWithDHCP.ps1

Works with DHCP settings on a local or remote machine.

PARAMETERS:

-computerName Specifies the name of the computer upon which to run the script

-action <q(uery) e(nable) r(elease) rr(release/renew) action to perform

-help prints help file

SYNTAX:

WorkWithDHCP.ps1 -q "yes" -computer WebServer

Queries DHCP settings on a computer named WebServer

WorkWithDHCP.ps1 -action e

enables DHCP on local computer

WorkWithDHCP.ps1 -action r

Releases the DHCP address on the local machine

WorkWithDHCP.ps1 -action rr

Releases and then renews the DHCP address on the local machine

WorkWithDHCP.ps1 -help ?

Displays the help topic for the script

"@

$helpText

exit

}

function FunEvalRTN($rtn)

{

Switch ($rtn.returnvalue)

{

0 { Write-Host -foregroundcolor green "No errors for $strCall" }

82 { Write-Host -foregroundcolor red "$strCall reports" `

" Unable to renew DHCP lease" }

83 { Write-Host -ForegroundColor red "$strCall reports" `

" Unable to release DHCP lease" }

91 { Write-Host -ForegroundColor red "$strCall reports" `

" access denied"}

DEFAULT { Write-Host -ForegroundColor red "$strCall service reports" `

" ERROR $($rtn.returnValue)" }

}

$rtn=$strCall=$null

}

if($help) { funhelp }

$global:RTN = $null

if(!$action) { $action="q" }

$objWMI = Get-WmiObject -Class win32_networkadapterconfiguration `

-computer $computer -filter "ipenabled = ‘true’"

Switch($action)

{

"e" {

$rtn = $objWMI.EnableDHCP() ;

$strCall = "Enable DHCP" ;

FunEvalRTN($rtn)

}

"r" {

$rtn = $objWMI.ReleaseDHCPLease() ;

$strCall = "Release DHCP address" ;

FunEvalRTN($rtn)

}

"rr" {

$rtn = $objWMI.RenewDHCPLease() ;

$strCall = "Release and Renew DHCP address" ;

FunEvalRTN($rtn)

}

"q" {

"DHCP Server: $($objWMI.dhcpserver)"

"Lease obtained: " + [Management.ManagementDatetimeConverter]::`

todatetime($objWMI.DHCPleaseObtained)

"Lease expires: " + [Management.ManagementDatetimeConverter]::`

todatetime($objWMI.DHCPleaseExpires)

}

}

该脚本首先使用param语句定义3个参数,其中-computer参数的默认值为localhost。然后声明全局变量RTN,并将其设置为$null,用于在代码段之间传递参数。如果没有提供任何参数,则显示当前DHCP的配置信息。如果$action变量没有参数,则默认为q参数,用于检索现有DHCP信息。

接下来使用switch语句对判断$action变量值,如果为e,则在目标计算机上启用DHCP。这里调用enableDHCP()方法为$strCall变量指定一个字符串,并将其传递给FunEvalRTN函数判断enableDHCP()方法是否成功执行;如果为r,则调用releaseDHCP()方法释放DHCP地址,并返回值$strCall传递给FunEvalRTN函数判断是否执行成功;如果为rr,则更新DHCP地址为$strCall变量指定字符串,然后判断返回值。

在switch语句的最后需要显示提供当前IP地址的DHCP服务器的地址,并查询获得租约的时间和过期时间。需要将UTC事件对象转换为客户端所需的正常时间,为此可以使用Manangement.ManangementDateTimeConverter这个.NET框架的类,并调用其中的toDateTime静态方法将UTC格式的日期时间对象传递给该方法。该脚本的执行结果如图13所示。

image

图6 查询和更新DHCP信息

上面脚本中使用的EnableDHCP()、ReleaseDHCPLease()和RenewDHCPLease()等方法均是Vista以后的操作系统新增的方法,该脚本仅适用于Windows Vista及其以上版本。

 

作者: 付海军
版权:本文版权归作者所有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
个人网站: http://txj.lzuer.com/


发表回复