PowerShell实现Windows排错指南 - 查看服务依存性

发布时间: 2011/1/19 10:41:58

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 执行结果

赞助商