Windows Server “8”中基于标准的管理

Microsoft Windows 对于基于标准的管理的支持由来已久。我们是分布式管理工作组 (DMTF) 的创始成员之一,并且首个推出了功能最丰富的公用信息模型 (CIM) 对象管理器 (CIMOM),即我们都熟悉的 Windows Management Instrumentation (WMI)。虽然 WMI 一直很好地服务于我们的客户和合作伙伴,但仍未实现基于标准的管理的坚定承诺。总的来说,现在的管理仍需使用供应商的特定工具环境 – 使用Windows 管理 Windows,使用Linux 管理 Linux,而网络和存储供应商管理他们自己的内容。对于客户仍然存在管理上的孤岛。某些产品可以衔接这些环境,但他们常常依赖特定的供应商,使管理再次陷入泥潭。对客户而言,缺少基于标准的管理是一个主要的软肋。

我们在与合作伙伴和客户的交流中花费了大量的时间,来了解他们对成功使用 Windows Server “8”的需求。云操作系统是我们特别关注的应用场景,而且很明显的是,对于这方面我们需要在基于标准的管理方面进行大量的投资。向云操作系统的重心转变显著增加了需要解决的管理问题。不仅是将关注的重点从管理一台服务器转变为管理许多服务器,而且为了能够融合成为综合性的计算平台,需要管理各种异构设备。如今,通过选择非常少的一组组件和限定组件资格,并安排大量开发人员编写组件特定的管理工具,云计算正在发挥应有的作用。通用的云计算需要基于标准的管理。这正是我们对 Windows Server “8”在基于标准管理方面进行大量投资的原因。

管理问题的核心在于需要一组分散的人员(他们常常具有相互冲突的利益)作出一组共同的决策。我们针对此问题的策略非常简单:创建一个能够轻松、合理地从事正确事情的价值链。开发组织关注开发某项产品花费的成本,以及给他们带来的收益。如果比率合适,我们便会开展工作,否则将会放弃。因此,我们的工作是尽可能减少实施基于标准的管理的成本和开销,同时尽可能实现收益最大化。本篇博文介绍了我们如何实现这一目标。本文不讨论其它主要的基于标准的管理计划:允许 Windows Server “8”发现和管理外部存储阵列的存储管理计划规范 (SMI-S)。我们将在以后的博文中对此进行讨论。

本博文包含的内容适合 IT 专业人员和开发人员。如果你是开发人员,本文提供的代码和构架师里可以你的工作变得轻松简单,或者如果您是一名 IT 专业人员,您也可能发现,本文为在 IT 基础结构的部署和架构决定作出合理决策方面具有宝贵的价值。

本博文由 Windows Server 团队首席架构师 Wojtek Kozaczynski 撰写。

--谨启!Jeffrey

背景知识

WMI 首先在 Windows 2000 中推出(而且可以向下应用于 NT4)。它采用基于 COM 的开发模型,而且编写类别提供程序并不适合胆小者。坦率地说,编写非常困难,而且正确编写更是难上加难。除了模型编程非常困难之外,团队还必须了解基于标准的管理的新环境,以及 CIM 架构、托管对象格式 (MOF) 语言和其它新术语、机制和工具。我们在最初的一些版本中做了相当全面的介绍,但许多团队对付出与收益比并不满意。 

等式的一个主要部分是收益方面。从头开始管理生态系统令人难以置信地困难。如果编写的提供程序无人调用,那么会产生什么价值?什么价值也没有。这正是系统管理服务器 (SMS),即现在所谓的系统中心配置管理器 (SCCM),在我们发布的同时增加了对 WMI 支持的原因(WMI 实际上源自 SMS 团队)。这是一种非常不错的做法,但存在两个问题:

  • 它对编写很大程度上以库存和监控管理的资源为重点的 WMI 提供程序产生刺激(与命令和控件相比),而且
  • SMS 的部署并不广泛,因此编写 WMI 提供程序的团队并不了解投资对客户的影响。 

自 WMI 发布以来,使用 WMI 提供程序的管理产品和工具的数量一直稳定增加,但是,长期来看,这与覆盖率的相应增加并不匹配。之后,事情随着 Hyper-V 而开始发生变化。DMTF 定义的原始管理架构注重世界上已经存在的情况,这与注重管理应用场景正好相反。对于这两种策略,都各有道理,但在谈到管理虚拟环境时,DMTF 需要实用主义团队的参与,当架构面世时,迅速加以采用。Hyper-V 团队开发了实施架构类的提供程序,而系统中心虚拟机管理器 (SCVMM) 团队开发了使用这些提供程序的管理工具。这种协作发挥的作用确实不错,而且使一些问题出现转机,原因在于它证明 WMI 不仅仅适合库存和监控。WMI 可以有效地支持配置、命令和控件。公平地说,许多团队已在之前完成了类似的工作,但没有一支团队认识到 Hyper-V 和 SCVMM 具有的可见性或影响力。

基于标准的管理的另一个重大变化是标准管理协议的定义和可用性。WMI 是托管许多标准类别提供程序的标准 CIMOM,但同时并不存在一种可互操作的管理协议,因此,WMI 使用了 DCOM。但是,这使其成为 Windows 管理 Windows 的管理孤岛。它很好地发挥了作用,但并没有实现基于标准的管理的愿景。这种情况随着 DMTF 定义和批准 WS 管理 (WS-MAN) 协议而发生了变化。这种基于 SOAP 的防火墙友好的协议允许任何操作系统上的客户端对在任何平台上运行的 CIMOM 调用运算。Microsoft 在 Windows Server 2003/R2 中首次部分实施了 WS-MAN,并将其命名为 Windows 远程管理 (WinRM)。它可以与其它平台上可用的许多 CIMOM/WS-MAN 堆栈进行互操作,这些平台包括 Openwsman(Perl、Python、Java 和 Ruby Bindings)、Wiseman(一种 Java 实施平台)和 OpenPegasus

一旦基于标准的管理客户端和 CIMOM 可以互操作,便迈出了第一步。但是,随着供应商使用这些协议开发真正无代理的管理解决方案,还开始强调不断增加的异构环境中的接合。实施规范的方法方面的差异,意味着工具需要编写特殊情况代码。困难的 API 使编写要求严格的应用程序变得非常困难。覆盖率方面的差距意味着供应商仍然必须安装代理,而供应商和客户却非常憎恨在机器上安装额外的代理。供应商憎恨的原因在于他们需要大量的工作来编写操作系统版本,并使它们保持最新。客户憎恨的原因在于它们使配置过程复杂化,而且产生的另一个问题是消耗宝贵的资源,并导致出错。

为什么变更?

早在 Windows Server “8”规划过程中,我们已认识到,不在基于标准的管理方面进行大量投资,便无法实现云操作系统。云环境中需要管理的内容太多,每一项资源的管理方式截然不同。考虑到我上面描述的情形,我们得出的结论是,我们需要:

  • 显著减少编写 WMI 提供程序和基于标准的管理工具所需的工作
  • 大幅提高可管理性覆盖率,特别是在配置、命令和控件领域  
  • 更新代码以符合最新的 DMTF 标准
  • 紧密集成 WMI 和 Windows PowerShell
  • 为在 Windows 或任何其它平台上使用基于标准的管理的每个人提供具有吸引力的清晰价值主张。

总结我们已完成的工作

现在,让我们从两个角度了解一下已完成的工作:IT 专业人员角度和 Windows/设备开发人员角度。

我们针对 IT 专业人员的目标是让他们使用 Windows PowerShell 管理一切内容,因此,我们需要为他们提供易于使用的 cmdlet,以便借助标准界面在远程机器或异构设备上远程管理资源。反过来,这使 IT 专业人员能够参照这些资源编写脚本,并编写连结数十台或数万台服务器和设备的工作流程,而且不必针对每种资源类型了解、配置和操作单独的技术和工具集。

我们针对 Windows/设备开发人员的目标是使定义和实施基于标准的管理界面变得简单、轻松,然后通过客户端 API、cmdlet 和 REST 端点显示这些界面。对于编写管理工具的开发人员,我们希望使管理解决方案的所有组件变得简单、轻松,其中包括向下的 DCOM Windows 服务器、基于标准的管理操作系统、服务器和设备。对于 Web 开发人员而言,我们希望通过 REST API 使得管理 Windows 变得简单、轻松。

现在,让我们从开发人员的角度开始,了解一下我们已完成的工作。下图显示的是我们称之为 CIM 堆栈的组件。  

 

  • 在提供程序开发领域,我们为 WMI 引入了新的管理基础结构 (MI) API,显著简化了新提供程序(图片中的 MI 提供程序)的开发。新工具根据 CIM 类规范生成框架提供程序。新的 API 支持 IT 专业人员期望的丰富的 cmdlet 语义:–WhatIf、-Confirm、-Verbose 以及进度栏和其它 cmdlet 行为。当旧的 CIM 客户端调用支持丰富语义的新提供程序时,这些 API 不起作用。但是,新的客户端和 Windows PowerShell 可以请求这些语义,通过新的API提供丰富的体验。
  • 我们使 WS-MAN 成为管理 Windows Server 的主要协议,并且向后兼容COM 和 DCOM 。我们已完成了整套 WS-MAN 协议操作,并针对效率和规模进行了优化。我们还增加了处理连接中断的支持,以使管理功能更加强大。从而简化在确定发生中断的情况下管理大量机器的工作。
  • 对于客户端开发人员而言,我们创建了新的 MI 客户端 API 和堆栈,它们可以通过 COM(本地)以及 DCOM 和 WS-Man(远程)与 WMI 进行通信。它还可以通过 WS-MAN 与任何兼容 CIM 的服务器进行通信。客户端 API(C/C++ 和 .Net)与提供程序 MI API 一致(它们共享主要的头文件)。

上面向我们介绍了构建针对在任何 CIMOM 中实施的 CIM 类的 Windows PowerShell 访问的基础,下图对此进行了说明。 

 

 

  • 我们创建了称为 CIM Cmdlet 的 Windows PowerShell 模块,其任务是直接响应通用 CIM 操作。该模块建立在客户端 .Net API 的基础之上,而且可以管理任何基于标准的管理资源。
  • 我们将 Windows PowerShell 修改为能够在运行时生成资源特定的 CIM cmdlet。这些 cmdlet 根据 Windows PowerShell-to-CIM 映射声明性的 XML 规范 (CDXML) 生成,可以本地或远程调用 CIM 类提供程序。这使开发人员能够编写 CIM 提供程序、编写 CDXML 映射文件,并使生成的 cmdlet 可用于每个运行 Windows PowerShell 3.0 的 Windows 设备。这同样对非 Windows 提供程序起作用。现在,想象一下这给设备供应商带来的价值。如果设备供应商实施符合标准的提供程序并包括此 CDXML 映射文件,则数亿台 Windows 机器将能够对设备进行管理,而且供应商不必编写、调试、分配或支持任何其它代码。当新版本的 Windows 面世时,无需编写任何代码即可支持供应商的设备。这为设备供应商支持基于标准的管理带来了巨大的激励。

在上图中,您可能注意到一个标有“NanoWBEM”的方框。现在,让我们谈一下这方面的内容。随着我们与合作伙伴和社区一起参与寻求基于标准的管理的计划,我们得到了各种各样的反馈。有些人觉得这是可以去做的正确事情,并且了解可能创造的业务机会,但对它是否真正起作用表示怀疑。当我们对此展开深入研究时,我们发现合作伙伴并没有感到他们可以成功使用现有的开源 CIMOM。同时,随着将功能扩展到管理 Linux 服务器,我们自己的系统中心团队也遇到了类似的问题。为了解决这些问题,系统中心团队启动了构建可移植、占用空间小、性能高的 CIMOM 的项目,结果便是 NanoWBEM。NanoWBEM 采用可移植的 C 语言编写,可以在 Linux、UNIX 和 Windows 上运行。由于其大小非常小,因此适合在网络设备、存储控制器和电话等小型设备上运行。NanoWBEM 使用与 WMI 相同的 MI 提供程序,因此,可以使用与开发人员用于创建 Windows 提供程序的相同工具来开发适合其它平台的提供程序。

现在,为了化解最初的担忧,我们的合作伙伴和社区正在计划使 NanoWBEM 可用于开源社区。

通过我上面描述的内容,我们两头受益:

  • 我们为 IT 专业人员提供了强大的工具,以便访问通过 CIM 类别提供程序实现的基于标准的管理 API。如果 MI 提供程序没有实施这些类,则它们可以支持扩展的 Windows PowerShell 语义,例如进程、-WhatIf、-Confirm 和 –Verbose。
  • 我们还为托管软件和设备开发人员提供了以比以前显著更低的成本创建新 MI 提供程序的工具,而且使 IT 专业人员可以通过 Windows PowerShell 模块以非常小的增量成本进行管理。

最后,对希望从非 Windows 平台管理 Windows 的 Web 开发人员而言,我们开发了 Management OData IIS Extension。它包含简化构建 REST API(OData 服务端点)的工具和组件。

OData 是一组用于构建 REST API 的 URL 惯例、工具、组件和库。使 OData 服务脱颖而出的是它们基于明确的域模型,这些模型定义了它们的数据内容和行为。这使得能够自动生成丰富的客户端库(例如 Windows/IoS/Android 电话、浏览器、Python、Java 等),从而简化开发可用于各种设备和平台的解决方案。  

许多产品具有完整的 Windows PowerShell API,而且现在需要在云环境中托管它们的 REST API。这正是我们首次使用注重显示 Windows PowerShell cmdlet 组的 OData 的原因。

 

 

但是,我们针对未来的版本设计了常规用途的解决方案。Rest API(特别是 OData)与 CIM 数据模型非常恰当地映射,因此,我们做的是提供将 cmdlet 组映射入 CIM 数据的一种机制,然后将数据模型显示为一个 OData 服务端点。

CIM 堆栈简要介绍

在前面的一节中,我从高层面概括了我们已完成的工作。这不可避免地为大家留下了疑问:它在实践中如何发挥作用?在团队的博客中,我们将深入介绍 Windows Sever “8”管理平台的所有功能和组件。同时,对于我们当中的新手,我将从 IT 专业人员的体验开始,“简要介绍”各项功能。

CIM cmdlet

IT 专业人员有两种机制可以管理 CIM 类。第一种选择是使用来自 CimCmdlets 模块的通用 CIM cmdlet,该模块默认情况下导入到 PowerShell_ISE 和 PowerShell。熟悉 CIM 的 IT 专业人员对该模块的 cmdlet 应非常熟悉,因为它们可以直接映射到通用 CIM/WS-Man 操作。 例如,三个不同的 Get-CimInstance cmdlet 参数组直接映射到 CIM/WS-MAN 通用操作。GetInstance、EnumerateInstances 和 QueryInstances。该模块还包括用于创建远程服务器连接(会话)和检查通过 CIMOM 注册的类定义的 cmdlet。

新的 CIM cmdlet 取代只在 Windows 到 Windows 环境中起作用的 *-Wmi* cmdlet。经过优化的 cmdlet 可以通过 WS-MAN 发挥作用,并继续通过 DCOM 无缝地工作,因此,作为一名 IT 专业人员,不再需要两组命令即可管理 Windows 和非 Windows 机器。

下面的示例说明了获取在本地计算机上的 WMI root\cimv2 命名空间中注册的 Win32_Service 类的属性名称和类型。

从远程服务器获取 Win32 服务的名称与此一样简单。

 

从 CDXML 生成的基于 CIM 的 Cmdlet

IT 专业人员也可以使用 Windows PowerShell 使用 CDXML 映射文件生成的 cmdlet。此模型允许开发人员编写一段代码,并获取 Windows PowerShell 和 WMI 两种生态系统的好处。它还允许以对某些操作系统功能团队具有特殊好处的本机代码编写 cmdlet。尽管基于 CIM 的 cmdlet 编写为 WMI 提供程序的形式,但外观和感觉与 Windows PowerShell cmdlet 几乎一样:

  • 它们提供以任务为导向的抽象,隐藏命名空间、类名称、方法名称等实施详情。
  • 它们支持完整的 Windows PowerShell 语义:-WhatIf、-Confirm 等…
  • 它们一致支持丰富操作控件:-AsJob、-Throttlelimit 等…
  • 它们封装为 Windows PowerShell 模块,可以使用获取/导入模块 cmdlet 发现。

用于生成基于 CIM 的 cmdlet 的 CDXML 文件将 cmdlet 动词、名词和参数映射到 Cmdlet 适配器。Cmdlet 适配器是将 Windows PowerShell cmdlet 的要求映射入指定技术的 .NET 类。我们针对 CIM 类推出 Cmdlet 适配器,但任何人都可以编写自己的 Cmdlet 适配器(例如将 cmdlet 与 Java 类相映射)。映射文件的文件扩展名是 .CDXML(Cmdlet 定义 XML)。许多相关的 CDXML 文件可以和描述返回的对象和如何格式化对象的文件一起,合并入 Windows PowerShell 模块。

这种机制的优点在于 Windows PowerShell 可以从远程 CIMOM 导入 .CDXML 模块,然后创建管理该服务器上的类的 cmdlet,而且无需具备有关它们的任何先备知识。换句话说,CIMOM 可以在运行时向其类显示服务器特定的 Windows PowerShell 接口,而且无需安装任何软件!

创作 CDXML 文件需要与指定任何其它 cmdlet 相当的详细信息水平,以及有关与 CIM 类函数映射的信息。为了简化这项任务,我们开发了 CDXML 编辑工具,我们将在单独的博文中详细介绍。 在不深入了解详细信息的情况下,现在让我们通过一个简单的示例,举例说明生成的基于 CIM 的 cmdlet 背后的理念。我在上面介绍了如何使用 CIM cmdlet 访问 Win32_Service 类及其实例。 下面的 .CDXML 文件定义了 Get-Win32Service 生成的基于 CIM 的 cmdlet,其将针对相同的类调用枚举方法。您在文件中无法找到该 Get-Win32Service cmdlet 的名称,因为它是从默认的名词 Win32Service 和动词 Get 默认生成。文件中的 <QueryableProperties> 元素定义 Windows PowerShell 用于查询 Win32_Service 类实例的属性。在我们的案例中,我们希望查询的属性是服务“名称”。 

下面的一系列 Windows PowerShell 命令将 .CDXML 文件导入为模块,列出了模块中定义的新 cmdlet,然后显示其签名。请注意,由于在 .CDXML 文件中我们声明参数“名称”是强制的 (<cmdletParameterMetadata IsMandatory="true" cmdletParameterSets="ByName" />),“名称”在 Get-Win32Service cmdlet 签名中显示为唯一的强制参数。

注意:如果您对我们如何完成此任务感到好奇,可以参阅我们使用以下命令动态生成的 cmdlet。

我们新创建的 cmdlet (Get-Win32Service) 作用与任何其它 cmdlet 类似,而且正如我上面提到的那样,可以作为背景工作执行。 在针对大量服务器执行命令时,限制 (-ThrottleLimit) 非常有用。您可以针对成百上千台服务器运行命令,并限制允许运行多少并发的未处理请求。

我们推出了具有 130 个 cmdlet 的 Windows PowerShell V1 和具有 230 个 cmdlet 的 Windows PowerShell V2。对于 With Windows PowerShell V3,Windows Server “8”配有超过 2,300 个 cmdlet。相当大部分的 cmdlet 使用 WMI MI 提供程序和 .CDXML 文件编写。这意味着这些函数可以通过 Windows PowerShell 和基于基准的管理进行使用。最近,我们还证实了使用 WS-MAN 从 Linux 客户端机器安装一组 Windows 服务器角色的能力,令受众大为震惊! 

 

CIM 客户端 .Net API

Windows PowerShell 中的 CIM cmdlet 和基于 CIM 的 cmdlet 都可以在新的 MI .Net 客户端 API 的基础上实施。尽管 IT 专业人员不可能编写 C# 客户端代码,管理工具开发人员毫无疑问会进行编写,那么让我们了解一个简单的示例。

客户端 API 支持与服务器的同步和异步交互。同步操作返回 CIM 类实例的 IEnumerable<CimInstance> 集合。异步操作使用来自反应性扩展的异步的、可观测的集合概念,产生有效、简单和紧凑的客户端代码。下面是一个简单的命令行程序示例,该程序在远程计算机上枚举 Win32_Service 类的实例。我的目的不是讨论客户端 API,而是说明产生的程序如何紧凑、简洁。  

 

处理枚举的代码位于主函数的三个突出显示的行中。这些代码行将枚举 Win32_Service 实例的结果转化为可观测的 CimInstance 对象集合,并将消费者观察者对象与该集合相关联。观察者包含三个处理返回的实例、最终结果和错误的回调。 这使得在仅仅几个代码行中针对远程 CIM 服务器执行丰富的管理功能变得简单而又轻松。 

 

新的 WMI 提供程序

我以前说过,我们大幅简化了 MI 提供程序的开发。许多事情有助于实现这种简化。

下图说明了编写提供程序涉及的步骤。提供程序可以实施一个或多个 CIM 类,而第一步则是以 MOF 规范语言描述这些 CIM 类。下一步是生成实施 CIM 类的提供程序框架。我们提供 Convert-MofToProvider.exe 实用程序来实现此步骤的自动化。此实用程序将类定义作为输入,并创建许多 C 标题和代码文件。其中的两个文件值得注意。

  • 第一个文件称为架构文件,它包含所有数据结构的定义,其中包括提供程序使用的 CIM 类实例。它使提供程序强类型化,而且易于与 Visual Studio 的智能感应和自动完成功能相协作。此文件不得手动编辑。

  • 另一个文件是提供程序代码文件,它包含提供程序的框架。这是唯一应编辑的文件。它包含所有 CIM 类方法的代码,以及返回未实施结果的方法主体。因此,生成的提供程序可以构建,可以注册并运行,但不执行任何操作。

 

接下来的一步是用相应的逻辑填充 CIM 类方法。完成这一步之后,可以注册和测试提供程序。我们还通过构建仅仅采用一个输入的新注册工具大大简化了提供程序注册,此工具便是提供程序 DLL。我们可以做到这一点的原因在于 MI 提供程序将它们的类定义编译进架构文件中。

为了使新的提供程序能够与 Windows PowerShell 完美协作,我们添加了扩展的 Windows PowerShell 语义 API。该功能的本质是提供程序可以在执行运算时从用户获取输入,条件是调用运算的 cmdlet 包含 –Confirm 或 –WhatIf 参数。下面的代码段来自枚举、停止和开始 Win32 服务的测试提供程序,并且说明了功能如何发挥作用。该代码是停止服务并询问用户(MI_PrompUser() 函数)是否想停止服务的运算的一部分,并具有以“名称”参数的形式指定给运算的名称。如果答案是“否”(bContinue == FALSE) 或者函数失败,这意味着提供程序不能达及用户,提供程序不会停止进程,但会编写返回给用户的消息(MI_WriteVerbose() 函数)并终止运算。  

管理 OData

我想简要介绍的最后一项功能是用于构建基于 OData 的 REST 管理端点的 IIS 扩展名。该功能背后的理念是我们可以声明性地配置如何向 Windows PowerShell 模块中的 cmdlet 分派端点服务请求。现在,我使用一个可用于枚举、创建和终止 Windows 进程的一个非常简单的端点示例,解释一下工作原理。

端点的目录包括下图中所示的三个文件。

 

 

架构文件包含端点实体的定义,而且在加载端点时加载架构文件。模块文件用于定义处理端点请求所调用的 Windows PowerShell cmdlet。分派的文件通过定义为不同的客户端请求调用哪些 cmdlet 来将另外两个项目联系起来。在我们的示例中,它将查询 Win32 进程映射到 Get-Win32_Process cmdlet,然后使用通用 CIM cmdlet 与 WMI 进行通信。下面的屏幕截图中显示了此端点配置的结果,该结果是针对 URL 的响应

https://wojtek8srv3:8000/Management/Process.svc/Win32Process?$filter=Name eq 'svchost.exe'&$select=ProcessId。 

 

总结

Jeffrey 常常指出,“没有人关注您的前几百万行代码”。“百万”是一个任意选择的非常大的数字,但暗喻每一项软件产品必须积累至关重要的大量基础组件,然后才能带来有意义的价值。但是,一旦达到至关重要的数量,即使一些附加的代码行都会产生显著的差异。

遵循这一暗喻,我觉得,在 Windows Server “8”中,我们已经编写了“前百万”行的基于标准的管理平台代码。我们弥合了管理逐渐复杂的云基础结构的 IT 专业人员与构建必须托管的内容的 Windows 和设备开发人员之间的鸿沟。我们奠定了一个一致的基础,这一基础从一端的低级 CIM 接口跨越到另一端以 IT 专业人员为导向的 Windows PowerShell 和 OData 接口。 我们为实施基于标准的管理的异构设备创造了明确而又极具吸引力的价值,而且我们实现了综合的覆盖度,从而使管理工具提供程序可以使用基于标准的管理对 Windows 进行管理。