关注领域: PowerShell,云计算,互联网技术发展,下一代互联网安全,软件测试,数据库设计,擅长系统分析、架构设计与软件项目管理。
个人简介:
甘肃武威人,毕业于兰州大学,曾任职于多家IT企业,有多年软件开发、系统架构、系统运营经验。组织和参与过多个国家和部委大型信息系统的设计、开发、测试、优化和运营工作,具有多年项目管理和团队组织经验。
个人主页:
http://txj.shell.tor.hu
CSDN:
http://blog.csdn.net/fuhj02
博客园:
http://fuhj02.cnblogs.com
图1 在“网络连接”窗口中查看每个适配器的详细信息 创建名为“GetNetAdapterConfig.ps1”的脚本收集特定网络适配器的用于排错的详细信息,并且通过指定关键字仅返回有关网络适配器的特定配置信息,其代码如下: param($computer="localhost",$query,$help) function funHelp() { $helpText=@" DESCRIPTION: NAME: GetNetAdapterConfig.ps1 Produces a listing of network adapter configuration information on a local or remote machine. PARAMETERS: -computer Specifies the name of the computer to run the script -help prints help file -query the type of query < ip, dns, dhcp, all > SYNTAX: GetNetAdapterConfig.ps1 -computerName WebServer Lists default network adapter configuration on a computer named WebServer GetNetAdapterConfig.ps1 -computerName WebServer -query IP Lists IPaddress, IPsubnet, DefaultIPgateway, MACAddress on a computer named WebServer GetNetAdapterConfig.ps1 -computerName WebServer -query DNS Lists DNSDomain, DNSDomainSuffixSearchOrder, DNSServerSearchOrder, DomainDNSRegistrationEnabled on a computer named WebServer GetNetAdapterConfig.ps1 -computerName WebServer -query DHCP Lists Index,DHCPEnabled, DHCPLeaseExpires, DHCPLeaseObtained, DHCPServer on a computer named WebServer GetNetAdapterConfig.ps1 -computerName WebServer -query ALL Lists all network adapter configuration information on a computer named WebServer GetNetAdapterConfig.ps1 -help ? Prints the help topic for the script "@ $helpText exit } if($help) { "Printing help now..." ; funHelp } $class="win32_networkadapterconfiguration" $IPproperty="IPaddress, IPsubnet, DefaultIPgateway, MACAddress" $dnsProperty="DNSDomain, DNSDomainSuffixSearchOrder, ` DNSServerSearchOrder, DomainDNSRegistrationEnabled" $dhcpProperty="Index,DHCPEnabled, DHCPLeaseExpires, ` DHCPLeaseObtained, DHCPServer" if($query) { switch($query) { "ip" { $query="Select $IPproperty from $class" } "dns" { $query="Select $dnsProperty from $class" } "dhcp" { $query="Select $dhcpProperty from $class" } "all" { $query = "Select * from $class" ; ` Get-WmiObject -Query $query | format-list * ; exit } DEFAULT { $query = "Select * from $class" ; ` Get-WmiObject -Query $query ; exit } } } ELSE { $query = "Select * from $class" ; ` Get-WmiObject -Query $query ; exit } Get-WmiObject -query $query | format-table [a-z]* -AutoSize 该脚本使用param语句定义了3个参数,即-computer、-query及-help。其中设置-computer的默认值为localhost。如果用户未指定计算机,则默认返回本地计算机的网络配置。 接下来针对帮助信息创建的funhelp函数用于输出帮助信息,当用户未输入参数或输入错误的参数时,调用该函数提示输入的错误及正确的输入。脚本中使用if语句检查$help变量是否存在,因为只有用户在调用脚本时指定了-help参数,该变量才会存在。随后初始化用于WMI查询的变量,这些变量的存在是为了便于在后面对命令行应用中实现灵活调用。在用户输入的参数中包括-query参数时,脚本将会调用switch语句判断$query变量值。并执行相应的操作,输出ip、dns、dhcp和所有条目的信息。在$query变量无输入的情况下还特别使用ELSE语句将WMI对象中的所有属性发送给Get-WmiObject cmdlet查询,在控制台输出当前计算机中的所有网络连接的信息。在代码的最后将Get-WmiObject cmdlet查询的结果通过管道传递给Format-Table cmdlet格式化输出,在使用Format-Tables时需要指定符合Get-WmiObject cmdlet输出代码格式的参数。该脚本的执行结果如图2和图3所示。
图2 查询当前主机DHCP信息
图3 未指定检索项默认会输出所有的网络适配器信息 作者: 付海军
图1 检查未启动的自动运行服务是排错的基本步骤 为了便于在脚本中查询未启动的自动运行服务,创建名为“AutoServiceNotRunning.ps1”的脚本,其代码如下: param($computer="localhost", [switch]$help) function funHelp() { $helpText=@" DESCRIPTION: NAME: AutoServicesNotRunning.ps1 Displays a listing of services that are set to automatic, but are not presently running PARAMETERS: -computer The name of the computer -help prints help file SYNTAX: AutoServicesNotRunning.ps1 -computer WebServer Displays a listing of all non running servicesthat are set to automatically start on a computer named WebServermunich AutoServicesNotRunning.ps1 Displays a listing of all services that are set to automatic, but are not presently running on the local machine AutoServicesNotRunning.ps1 -help ? Displays the help topic for the script "@ $helpText exit } if($help){ "Obtaining help ..." ; funhelp } $wmi = Get-WmiObject -Class win32_service -computername $computer ` -filter "state <> 'running' and startmode = 'auto'" if($wmi -eq $null) { "No automatic services are stopped" } Else { "There are $($wmi.count) automatic services stopped. The list follows ... " foreach($service in $wmi) { $service.name } } 该脚本使用Get-WmiObject cmdlet查询Win32_Service WMI类,通过自定义仅返回设置为自动运行服务器的当前状态,输出信息说明其是否正常。通过指定-computername参数选择本地或远程计算机,使用-filter参数减少返回的Win32_Service类的实例数量。因为只需要知道启动类型设置为自动,但未运行的服务。需要判断查询WMI结果,如果$wmi变量值为空,则表示自动运行的服务正常;如果有未运行自动启动的服务,则输出其数量,然后使用foreach语句输出其名称。此脚本的执行结果如图2所示。
图2 执行结果 作者: 付海军
图1 输出磁盘信息
图2 磁盘和磁盘分区的关系 创建名为“ReportDiskPartition.ps1”的脚本,用于获取系统中存在的分区属性。其中将检查变量$args的值,以判断执行脚本时是否传递参数。如果不存在该变量,则表明在运行脚本时未提供参数。此时脚本会作为本地计算机处理,即传递localhost给$args变量。如果传递问号给脚本,则返回当前脚本的帮助信息,该脚本的代码如下: if(!$args) { Write-Host -foregroundcolor green ` 'Querying localhost ...' $args = 'localhost' } if($args -eq "?") { " ReportDiskPartition.ps1 DESCRIPTION: This script can take a single argument, computer name. It will display drive configuration on either a local or a remote computer. You can supply either a ? or a name of a local machine. EXAMPLE: ReportDiskPartition.ps1 remoteComputerName reports on disk partition information on a computer named remoteComputerName The script will also display this help file. This is done via the ? argument as seen here. ReportDiskPartition.ps1 ? " } Get-WmiObject -Class Win32_DiskPartition ` -computer $args 其中使用Get-WmiObject cmdlet及-class参数搜索Win32_DiskPartition WMI类,并获得磁盘分区的配置信息和值。如果使用$args参数提供了要查询磁盘分区信息的计算机名,则可使用-computer参数为Get-WmiObject提供计算机名,执行结果如图24所示。
图3 执行结果 2 匹配磁盘和分区 匹配驱动器和分区之后,还需要相应处理磁盘和分区的脚本,因为有时需要特定驱动器的分区信息。创建名为“ReportSpecificDiskPartition.ps1”的脚本来获取硬盘特定分区的配置信息,其代码如下: param($computer="localhost",$disk="磁盘 #0,分区 #0",$help) if($computer) { Write-Host -foregroundcolor green ` "Querying $computer ..." } if($disk) { Write-Host -foregroundcolor green ` "Querying $disk for partition information ..." } if($help) { " ReportSpecificDiskPartition.ps1 DESCRIPTION: This script can take a multiple arguments, computer name, drive number and help. It will display partition configuration on either a local or a remote computer. You can supply either help, drive and name of a local or remote machine. EXAMPLE: ReportSpecificDiskPartition.ps1 -computer remoteComputername reports on disk partition on drive 0 on a computer named remoteComputerName ReportSpecificDiskPartition.ps1 -computer remoteComputername -disk '磁盘 #0,分区 #0' reports on disk partition on drive 1 on a computer named remoteComputerName ReportSpecificDiskPartition.ps1 -help y Prints out the help information seen here. " Exit } Get-WmiObject -Class Win32_DiskPartition ` -computer $computer | Where-Object { $_.name -match $Disk } | format-list [a-z]*
图1 系统性能计数器
图2 “添加计数器”对话框 其中包括性能计数器名,如%Processor Time和Handle Count等,以及计数器对应的范例。当需要获取处理器相关的性能计数器数据时,默认以处理器命名。如果有多个处理器,则为计数器分别添加类似于#1、#2和#3这样的后缀。如果需要处理多个实例,则在添加计数器的过程中制定相应的实例。 5.1 Consuming Counter Data PowerShell没有内置的cmdlet用于获取性能计数器的值,所以必须使用.NET的类。为此创建System.Diagnostics.PerformanceCounter的实例,配置其中的属性并不断调用NextValue()方法来获取相应的值。在开始操作性能计数器之前,需要首先配置用户权限为管理员权限。然后创建脚本用于监视CPU的使用率,将脚本命名为“Monitor-CpuUsage.ps1”。将会用性能计数器获取并显示当前CPU每秒的占用率,这个脚本会一直循环执行下去;除非用户按Ctrl-C终止。其代码如下: $counter = New-Object Diagnostics.PerformanceCounter $counter.CategoryName = "Processor" $counter.CounterName = "% Processor Time" $counter.InstanceName = "_Total" while ($true) { $value = $counter.NextValue() Write-Host "CPU: $value" sleep 1 } 其中涉及的计数器名和实例名都可以很容易地从“添加计数器”对话框中找到,Monitor-CpuUsage.ps1脚本的执行结果如图20所示。
图3 执行结果 从图中可以看到此时的CPU负载并不重,只达到10%左右,用户可以用类似的方法获取其他性能计数器的数据。 5.2 监视程序 当使用程序时发生不正常的情况时,通常都会造成占用大量的系统资源而导致系统重启。这时使用性能计数器可以监控程序的运行情况,即在运行程序的同时启动监视脚本。该脚本会实时获取和分析性能数据,当发生异常时会向用户发出警告。 针对意外终止的应用程序创建一个监视脚本Monitor-Crashes.ps1,脚本将会启动外部进程。当程序意外退出时,脚本会将重启5次应用程序之后停止尝试,其代码如下: function Start-Process { Write-Host "Starting process..." .\UnpredictableCrash.exe } for ($i = 0; $i -lt 5; $i++) { Start-Process Write-Host "Process exited $($i + 1) times." } Write-Host "Program restart limit exceeded." 该脚本的执行结果如图21所示。
图1 创建自定义的电源计划 创建名为“SetPowerConfig.ps1”的脚本用于设置电源计划,代码如下: param($c, $t, $q, $help) function funline ($strIN) { $num = $strIN.length for($i=1 ; $i -le $num ; $i++) { $funline += "=" } Write-Host -ForegroundColor yellow `n$strIN Write-Host -ForegroundColor darkYellow $funline } function funHelp() { $helpText=@" DESCRIPTION: NAME: SetPowerConfig.ps1 Sets power config on a local machine. PARAMETERS: -c(hange) <mp,mb,dp,db,sp,sb,hp,hb> -q(uery) detailed query of current power plan -t(ime out) time out value for change. Required when using -c to change a value -help prints help file SYNTAX: SetPowerConfig.ps1 Displays error message. Must supply a parameter SetPowerConfig.ps1 -c mp -t 10 Sets time out value of monitor when on power to10 minutes SetPowerConfig.ps1 -c mb -t 5 Sets time out value of monitor when on battery to 5 minutes SetPowerConfig.ps1 -c dp -t 15 Sets time out value of disk when on power to 15 minutes SetPowerConfig.ps1 -c db -t 7 Sets time out value of disk when on battery to 7 minutes SetPowerConfig.ps1 -c sp -t 30 Sets time out value of standby when on power to 30 minutes SetPowerConfig.ps1 -c sb -t 10 Sets time out value of standby when on battery to 10 minutes SetPowerConfig.ps1 -c hp -t 45 Sets time out value of hibernate when on power to 45 minutes SetPowerConfig.ps1 -c hb -t 15 Sets time out value of hibernate when on battery to 15 minutes SetPowerConfig.ps1 -q c Lists detailed configuration settings of the current power scheme SetPowerConfig.ps1 -help ? Displays the help topic for the script "@ $helpText exit } if($help){funline("Obtaining help ...") ; funhelp } $computer = (New-Object -ComObject WScript.Network).computername if($q) { funline("Power configuration on: $($computer)") powercfg -query exit } if($c -and !$t) { $(Throw 'A value for $t is required. Try this: SetPowerConfig.ps1 -help ?') } switch($c) { "mp" { powercfg -CHANGE -monitor-timeout-ac $t } "mb" { powercfg -CHANGE -monitor-timeout-dc $t } "dp" { powercfg -CHANGE -disk-timeout-ac $t} "db" { powercfg -CHANGE -disk-timeout-dc $t } "sp" { powercfg -CHANGE -standby-timeout-ac $t } "sb" { powercfg -CHANGE -standby-timeout-dc $t } "hp" { powercfg -CHANGE -hibernate-timeout-ac $t } "hb" { powercfg -CHANGE -hibernate-timeout-dc $t } DEFAULT { "$c is not allowed. Try the following: SetPowerConfig.ps1 -help ?" } } 该脚本首先使用param语句定义了4个参数,即-c、-t、-q和-help。其中-q指定查询,-help指定输出帮助。-c和-t必须同时使用,因为-t值指定修改电源计划的参数超时值,如果该值为空,脚本执行将出错。该脚本使用WScript.Network对象获得本机的计算机名,因此可以使用New-Object cmdlet配合-comobject参数。通过小括号将这些内容括起作为一个对象,使用ComputerName属性并将结果保存在$computer变量中。 如果在脚本执行时提供了参数-q,那么会出现$q变量。这样可使用funline函数将计算机名作为标题输出,并使用Powercfg工具提供参数-query,从而得到本机当前的详细电源计划。 如果提供了参数-c,则必须使用参数-t。这是因为$t变量中包括的是时间信息,需要为-c参数中指定的操作指定有限的超时时间,这样才不会无限期地等待。如果仅有$c变量,则使用throw语句输出红色的错误信息,并停止脚本执行。 接下来脚本根据-c参数值匹配switch语句中的分支,如果值为mp,则使用包括在$t变量值作为交流电情况下的显示器超时时间的分钟数;如果值为mb,并且计算机在使用电池供电,则会使用$t变量值设置显示器的超时时间;如果值为db,则配置当前电源计划在达到$t变量设定的分钟数后关闭驱动器;如果值为sp,则在使用交流电的情况下当空闲时间超过$t变量设定的分钟数后计算机将会进入待机状态;如果需要计算机休眠,则使用hp,并修改用于交流电下休眠的电源计划值;如果使用hb,则为电池模式下的休眠值。 此脚本在Windows Server 2008和Windows XP下通过-q参数查询电源方案的结果如图2和图3所示。
图2 在Windows 2008中列出当前系统电源计划的详细方案
图3 在WindowsXP中获取到的电源计划的信息 作者: 付海军
图1 Windows Server 2008中的电源策略设置界面 创建名为“ReportPowerConfig.ps1”的脚本,根据用户提供的如下参数提供相应的电源配置信息。 a:当前主机中活动的电源设置。 l:当前主机中的所有电源配置。 q:当前主机中的所有可用休眠状态。 w:当前主机中的上次唤醒事件。 d:当前主机中的所有的设备。 dv:当前主机中的所有设备的详细信息。 dwa:当前主机中已配置且可唤醒当前主机的设备。 dwp:当前主机中所有配置为可从睡眠中唤醒计算机的设备。 该脚本的代码如下: param($a="a", $help) function funline ($strIN) { $num = $strIN.length for($i=1 ; $i -le $num ; $i++) { $funline += "=" } Write-Host -ForegroundColor yellow `n$strIN Write-Host -ForegroundColor darkYellow $funline } function funHelp() { $helpText=@" DESCRIPTION: NAME: ReportPowerConfig.ps1 Prints power config on a local machine. PARAMETERS: -a(ction) action to perform <a(ctive scheme), l(ist), q(uery), d(evice), dv(evice verbose), dwa(evice wake armed), dwp(evice wake programable)> -help prints help file SYNTAX: ReportPowerConfig.ps1 Lists power configuration on local computer ReportPowerConfig.ps1 -a a Lists active power configuration on local computer ReportPowerConfig.ps1 -a l Lists all power configuration on local computer ReportPowerConfig.ps1 -a q Lists all available sleep states on local computer ReportPowerConfig.ps1 -a w Lists last wake event on local computer ReportPowerConfig.ps1 -a d Lists all devices on local computer ReportPowerConfig.ps1 -a dv Lists all devices on local computer - verbose ReportPowerConfig.ps1 -a dwa Lists devices configured to wake the local computer ReportPowerConfig.ps1 -a dwp Lists devices that are user confiurable to wake the computer from sleep on local computer ReportPowerConfig.ps1 -help ? Displays the help topic for the script "@ $helpText exit } if($help){funline("Obtaining help ...") ; funhelp } $computer = (New-Object -ComObject WScript.Network).computername funline("Power configuration on: $($computer)") switch($a) { "a" { POWERCFG -GETACTIVESCHEME ; "`r"} "l" { powercfg -LIST } "q" { powercfg -AVAILABLESLEEPSTATES } "w" { powercfg -lastwake } "d" { powercfg -devicequery all_devices } "dv" { powercfg -devicequery all_devices_verbose } "dwa" { powercfg -devicequery wake_armed } "dwp" { powercfg -devicequery wake_programmable } } 在脚本中首先使用param语句定义了两个命令行参数-a和-help,-a指定脚本执行的操作,默认值为a;-help指定显示帮助信息,包括描述、参数及语法范例。要强调的是这个脚本无法在远程执行。 获取计算机名称时可以使用WScript.Network COM对象,并使用New-Object cmdlet创建该对象,然后提供-comobject参数。选择ComputerName属性,计算机名自动保存在$computer变量中。该脚本中的大部分的逻辑控制在switch语句中完成,这些语句通过判断命令行中的$a变量值选择相应的分支。如果值为a,则使用Powercfg工具获取当前电源计划。执行结果如图2和图3所示,可以看到当前计算机可以由网卡远程唤醒。需要强调的是由于Windows XP和Windows Server 2008的powercfg工具的工作环境不同,所以将-a参数的a或q选项传递给脚本使将会抛出“参数无效,键入"/?"得到帮助”的提示信息。
图2 列出当前系统中可用的电源计划
图3 获取可从睡眠中唤醒计算机的设备 作者: 付海军