代码改变世界

PowerShell2.0之Windows排错(二)查看服务依存性

2011-01-17 23:57  @天行健中国元素  阅读(1543)  评论(0编辑  收藏  举报

Windows中的系统服务具有依存性,如果一个服务未启动,可能导致更多依赖于它的服务均无法启动。以Base Filtering Engine服务为例,其基本筛选引擎(BFE)是一种管理防火墙和 Internet 协议安全(IPsec)策略及实施用户模式筛选的服务,停止或禁用BFE服务将大大降低系统的安全,并造成IPsec管理和防火墙应用程序产生不可预知的行为。在Windows Server 2008中,这个服务依赖于Remote Procedure Call(RPC)服务,而IKE and AuthIP IPsec Keying Modules、Internet Connection Sharing(ICS)、IPsec Policy Agent、Routing and Remote Access和Windows Firewall这5个服务依赖于它。使用服务依存性有利于开发人员直接使用系统中的任何功能,降低开发工作量。与此同时带来的缺点是很难判断一些看似没有任何相互没有关联的服务之间的关系,在图形界面中可以通过服务控制台了解这些信息。为此双击服务列表中的一个服务,然后打开“依存关系”选项卡,如图1所示。

image

图1 “依存关系”选项卡

为在非图形界面,如远程或者Windows Server 2008 Server Core下查看服务的依存关系,便于进一步查找和排除错误,创建名为“ServiceDependencies.ps1”的脚本。其代码如下:

$erroractionpreference = "SilentlyContinue" # hides any cryptic error messages due to security

Param($computer = "localhost", [switch]$help)

function funline ($strIN)

{

$num = $strIN.length

for($i=1 ; $i -le $num ; $i++)

{ $funline = $funline + "=" }

Write-Host -ForegroundColor yellow $strIN

Write-Host -ForegroundColor darkYellow $funline

}

function funHelp()

{

$helpText=@"

DESCRIPTION:

NAME: ServiceDependencies.ps1

Displays a listing of services and their dependencies

PARAMETERS:

-computer The name of the computer

-help prints help file

YNTAX:

ServiceDependencies.ps1 -computer WebServer

Displays a listing of services and their dependencies on a computer named WebServer

ServiceDependencies.ps1

Displays a listing of services and their dependencies on the local machine

ServiceDependencies.ps1 -help ?

Displays the help topic for the script

"@

$helpText

exit

}

if($help){ "Obtaining help ..." ; funhelp }

$dependentProperty = "name", "displayname", "pathname",

"state", "startmode", "processID"

$antecedentProperty = "name", "displayname",

"state", "processID"

if($computer = "localhost") { $computer = $env:computername }

funline("Service Dependencies on $($computer)")

New-Variable -Name c_padline -value 14 -option constant # allows for length of

displayname

Get-WmiObject -Class Win32_DependentService -computername $computer |

Foreach-object `

{

"=" * ((([wmi]$_.dependent).pathname).length + $c_padline)

Write-Host -ForegroundColor blue "This service:"

[wmi]$_.Dependent |

format-list -Property $dependentProperty

Write-Host -ForegroundColor cyan "Depends on this service:"

[wmi]$_.Antecedent |

format-list -Property $antecedentProperty

"=" * ((([wmi]$_.dependent).pathname).length + $c_padline) + "`n"

}

因为某些服务即使使用本地管理员组账户登录也无法访问,而且有些服务是系统自身运行时使用的服务,不允许用户操作,所以为了避免执行脚本时出现错误,该脚本首先将$erroractionpreference自动变量赋值为SilentlyContinue。

接下来使用param语句定义命令行-computer参数指定运行这个脚本的主机和在需要时显示帮助信息-help参数,并使用了之前脚本中定义过的funline函数输出标题信息。在后面定义了$dependentProperty和$antecedentProperty变量分别保存属性列表,在执行WMI类查询时可以得到与这两个变量对应的属性值。在param语句中的$computer变量值是localhost,默认指向本机。如果在调用此脚本时传递了-computer参数,则默认使用该参数。如果用户没有提供计算机名,则需要将localhost翻译为本机的主机名,主机名可以通过查询PS驱动器的$env变量获取。随后使用New-Variable cmdlet创建c_padline常量,并使用-option参数,New-Variable cmdlet的-name参数不需要变量名以美元符开头。

最后使用Get-WmiObject cmdlet查询WMI类Win32_DependentService,这个WMI类是个关联类,与另外两个WMI类,即Win32_BaseService和Win32_BaseService有关(注意这不是错误,这个类可以关联自身,通过这种方式可以知道服务之间的依存关系)。可以使用Get-WmiObject cmdlet的-computername参数使脚本具有查询本地或远程WMI的能力,命令结尾使用管道对象将处理后的结果对象传递给ForEach-Object cmdlet。随后使用[WMI]management对象获得有关服务依存性的信息,并将结果management对象用管道发送给Format-List cmdlet输出保存在$dependentProperty变量中的所有结果。

该脚本的执行结果如图2所示。

image

图2 执行结果

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