上一次我们学习了文件系统的操作,能够读取、写入基于文本的文件,搜索本地及远程文件、目录。本次我们来操作下Windows服务,首先来回顾一下Windows服务的基本概念:
本系列所有脚本均在Windows Server 2008 R2 DataCenter (PowerShell 2.0) + PowerGUI Script Editor Free Edition x64中测试通过。
1、Windows服务介绍(摘自MSDN)
Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这些功能使服务非常适合在服务器上使用,每当需要使用不会影响在同一台计算机上工作的其他用户的功能时也适用。还可以在不同于登录用户的特定用户帐户或默认计算机帐户的安全上下文中运行服务。有关服务和 Windows 会话的更多信息,请参见 MSDN Library 的 Platform SDK 文档中的关于服务一节。
通过创建作为服务安装的应用程序,可以轻松地创建服务。例如,假设要监视性能计数器数据并对阈值做出反应。可以编写一个侦听性能计数器数据的 Windows 服务应用程序、部署该应用程序并开始收集和分析数据。
将服务创建为 Microsoft Visual Studio 项目,并在其中定义代码,以控制哪些命令可以发送到服务以及接收到这些命令时采取的操作。可以发送到服务的命令包括启动、暂停、继续和停止该服务;还可以执行自定义命令。
创建并生成了应用程序后,可以通过运行命令行实用工具 InstallUtil.exe 并将路径传递给服务的可执行文件,或通过使用 Visual Studio 的部署功能来安装该应用程序。然后可以使用"服务控制管理器"启动、停止、暂停、继续和配置服务。这些任务中的许多种也可以在"服务器资源管理器"的"服务"节点中或通过使用 ServiceController 类来完成。
服务应用程序与其他 Visual Studio 应用程序
服务应用程序与其他许多项目类型的功能在几个方面有所不同:
.NET Framework 支持的 Windows 服务类不支持与交互区域(即登录用户)进行交互。同时,.NET Framework 不包含表示区域和桌面的类。如果 Windows 服务必须与其他区域进行交互,则需要访问非托管的 Windows API。有关更多信息,请参见 Platform SDK 文档中的窗口区域和桌面。
设计 Windows 服务与用户或其他区域的交互时必须非常小心,应考虑某些情况,例如没有登录的用户或用户具有一组意外的桌面对象的情况。在某些情况下,编写一个在用户控制下运行的 Windows 应用程序可能更为妥当。
服务生存期
服务在其生存期内要经历几个内部状态。首先,将服务安装在将要运行它的系统上。此过程执行服务项目的安装程序,并将服务加载到该计算机的"服务控制管理器"中。"服务控制管理器"是由 Windows 提供的管理服务的核心实用工具。
Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面。这些功能使服务非常适合在服务器上使用,每当需要使用不会影响在同一台计算机上工作的其他用户的功能时也适用。还可以在不同于登录用户的特定用户帐户或默认计算机帐户的安全上下文中运行服务。有关服务和 Windows 会话的更多信息,请参见 MSDN Library 的 Platform SDK 文档中的关于服务一节。
通过创建作为服务安装的应用程序,可以轻松地创建服务。例如,假设要监视性能计数器数据并对阈值做出反应。可以编写一个侦听性能计数器数据的 Windows 服务应用程序、部署该应用程序并开始收集和分析数据。
将服务创建为 Microsoft Visual Studio 项目,并在其中定义代码,以控制哪些命令可以发送到服务以及接收到这些命令时采取的操作。可以发送到服务的命令包括启动、暂停、继续和停止该服务;还可以执行自定义命令。
创建并生成了应用程序后,可以通过运行命令行实用工具 InstallUtil.exe 并将路径传递给服务的可执行文件,或通过使用 Visual Studio 的部署功能来安装该应用程序。然后可以使用"服务控制管理器"启动、停止、暂停、继续和配置服务。这些任务中的许多种也可以在"服务器资源管理器"的"服务"节点中或通过使用 ServiceController 类来完成。
服务应用程序与其他 Visual Studio 应用程序
服务应用程序与其他许多项目类型的功能在几个方面有所不同:
.NET Framework 支持的 Windows 服务类不支持与交互区域(即登录用户)进行交互。同时,.NET Framework 不包含表示区域和桌面的类。如果 Windows 服务必须与其他区域进行交互,则需要访问非托管的 Windows API。有关更多信息,请参见 Platform SDK 文档中的窗口区域和桌面。
设计 Windows 服务与用户或其他区域的交互时必须非常小心,应考虑某些情况,例如没有登录的用户或用户具有一组意外的桌面对象的情况。在某些情况下,编写一个在用户控制下运行的 Windows 应用程序可能更为妥当。
服务生存期
服务在其生存期内要经历几个内部状态。首先,将服务安装在将要运行它的系统上。此过程执行服务项目的安装程序,并将服务加载到该计算机的"服务控制管理器"中。"服务控制管理器"是由 Windows 提供的管理服务的核心实用工具。
服务加载后,必须启动。启动服务使服务开始运行。可以从"服务控制管理器"、从"服务器资源管理器"或通过调用 Start 方法从代码启动服务。Start 方法将处理传递给应用程序的 OnStart 方法并处理您在该处定义的任何代码。
运行的服务可以以这种状态无限期地存在下去,直到它被停止或暂停或者计算机关闭。服务可以以三种基本状态之一存在:Running、Paused 或 Stopped。服务还可以报告挂起命令的状态:ContinuePending、PausePending、StartPending 或 StopPending。这些状态指示命令已经发出(如暂停正在运行的服务的命令),但尚未执行。您可以查询 Status 以确定服务的状态,也可以使用 WaitForStatus 在以上任一状态出现时执行操作。
可以从"服务控制管理器"、从"服务器资源管理器"或通过从代码调用方法来暂停、停止或继续服务。每种操作都可以调用服务中的一个相关过程(OnStop、OnPause 或 OnContinue),在其中可以定义当服务状态更改时所执行的其他处理。
服务类型
在 Visual Studio 中使用 .NET Framework 可以创建两种类型的服务。进程中的唯一服务被指定为 Win32OwnProcess 类型。与其他服务共享进程的服务被指定为 Win32ShareProcess 类型。可通过查询 ServiceType 属性检索服务类型。
如果查询不是在 Visual Studio 中创建的现有服务,则偶尔还可能看到其他服务类型。有关这些内容的更多信息,请参见 ServiceType。
服务和 ServiceController 组件
ServiceController 组件用于连接到已安装的服务并操作其状态;使用 ServiceController 组件可以启动和停止服务、暂停和继续其运行以及将自定义命令发送到服务。但是,在创建服务应用程序时不需使用 ServiceController组件。实际上,多数情况下,ServiceController 组件存在于与定义服务的 Windows 服务应用程序不同的应用程序中。
部署和安装服务
Visual Studio 随附有安装组件,这些组件可以安装与服务应用程序相关的资源。安装组件在正在安装到的系统上注册一项单个的服务,并使"服务控制管理器"知道该服务的存在。
在将安装程序添加到应用程序之后,下一步是创建安装项目,该项目将安装已编译的项目文件并运行安装服务所需的安装程序。若要创建完整的安装项目,您必须将服务项目的输出添加到该安装项目,然后添加自定义操作以安装您的服务。
2、PowerShell中关于服务的命令如下:
Get-Service |
Set-Service |
Start-Service |
Stop-Service |
Restart-Service |
New-Service |
Suspend-Service |
Resume-Service |
从字面意思就可以看出其作用,下面来测试一下。
2.1、获取系统中的所有服务,将处于"运行" 状态的标记为黄字黑底,并非别按照显示名称、服务状态排序:
$services = Get-Service | Sort -Property DisplayName,Status
foreach($service in $services)
{
if($service.Status -eq "Running")
{
Write-Host "$($service.DisplayName) is $($service.Status)" -ForegroundColor Yellow -BackgroundColor Black
}
else
{
Write-Host "$($service.DisplayName) is $($service.Status)"
}
}
运行结果:
注意表达式$($service.DisplayName)的用法。
2.2、遇到一个新命令时,快速了解其成员的好方法是对其调用 Get-Member:
Get-Service | Get-Member
运行结果:
获取名称中包含"SQL"的服务:
Get-Service | Where {$_.Name -like "*SQL*"}
运行结果:
注意,服务控制台中的"Name"是PowerShell中的"DisplayName":
在PowerShell 2.0中,新增了 –ComputerName参数,可以查看远程计算机上的服务,虚拟机的IP和服务如下:
查看此远程计算机上的服务:
Get-Service -ComputerName 192.168.200.132
运行结果:
-ComputerName支持IP地址、NetBios名称和域名,为远程管理提供了极大的便利性。
2.3、更改服务的启动状态:
Set-Service SQLWriter -StartupType Automatic –PassThru
运行结果:
同样可以更改远程计算机上的服务:
Set-Service pla -ComputerName 192.168.200.132 -StartupType Manual –PassThru
运行结果:
为了安全起见,PowerShell设计为只能使用Get-Service、Set-Service操作远程计算机上的服务。
2.4、启动、停止、重启服务:
Start-Service SQLWriter -PassThru
Stop-Service SQLWriter -PassThru
Restart-Service SQLWriter –PassThru
运行结果:
暂停、恢复服务:
注意并不是每一个服务都支持暂停、恢复操作,因此我们先获取支持暂停、恢复的服务:
Get-Service | Where {$_.CanPauseAndContinue}
运行结果:
这些是我本机所有支持暂停、恢复的服务,还是很少的。
Suspend-Service MSSQLSERVER -PassThru
Resume-Service MSSQLSERVER –PassThru
运行结果:
2.5、获取服务的依赖服务与被依赖服务:
Get-Service "Remote Procedure Call (RPC)" –RequiredServices
Get-Service "Remote Procedure Call (RPC)" –DependentServices
运行结果:
可以看到,众多服务依赖于RPC服务。
小结:
本次我们对Windows服务这一重要的实体进行了介绍,练习了一些简单的命令。此外在PowerShell 2.0中,可以进行远程服务管理,这对于管理员来说是个利好消息,但是这也或多或少带来了一些安全隐患。下一次我们将练习操作Windows进程。