什么是Windows PowerShell?它吃什么?第5部分:访问外部对象



Windows操作系统支持各种对象基础结构。您可以使用应用程序编程接口(API)来访问它们,但是开发成熟的应用程序并不总是合理的。PowerShell具有特殊的cmdlet,允许您以交互方式访问.NET,COM,WMI(CIM)和ADSI对象。在本系列第四部分中,我们以.NET Core类为重点学习了基础知识,现在,我们想加深主题并了解PowerShell与外部对象交互的功能。

目录:


使用JSON,XML和CSV
使用WMI和CIM
使用COM对象
使用ADSI目录服务
格式化输出

使用JSON,XML和CSV


在PowerShell脚本中,您通常必须解析JSON,XML和CSV数据。通常,在使用Internet服务或配置文件时会出现这种需求。一些管理员尝试使用正则表达式解析数据,但是没有必要做出这样的牺牲:PowerShell具有用于双向转换的特殊cmdlet。



JSON格式允许您描述各种对象,并且实质上是可以嵌套的哈希表。相应地,使用PowerShell将JSON对象转换为.NET对象很容易。由于Internet服务通常会提供很长的行而不是格式精美的文件,因此此转换对于以交互方式工作也很有用。在下面的示例中,我们使用多行文本变量来描述JSON对象:

$user = @"
{
   "firstName": "Ivan",
   "lastName": "Danko",
   "address": {
       "streetAddress": "Kremlin",
       "city": "Moscow"
   },
   "phoneNumbers": [
       "+7 495 1234567",
       "+7 499 1234567"
   ]
}
"@ | ConvertFrom-Json



反问题以类似的方式解决:

$file = Get-ChildItem C:\Windows\System32\notepad.exe
$file.VersionInfo | ConvertTo-Json



生成的JSON格式字符串很容易通过网络发送到另一个应用程序。例如,它可以是某些RESTful服务。使用ConvertFrom-Csv,ConvertTo-Csv和ConvertTo-Xml cmdlet的方式大致相同,我们建议读者自己研究它。

要使用XML和CSV,我们将需要其他cmdlet:



使用这些工具,您需要了解将二进制对象转换为文本格式仅保存其属性的值,而不保存方法的值。仅在有效的情况下,才能使用PowerShell将JSON,XML或CSV数据转换为.NET对象。

使用WMI和CIM


Windows Management Instrumentation(WMI)是WBEM(基于Web的企业管理)标准的Microsoft开发和Windows适应的实现。它基于创建通用解决方案以监视企业的分布式信息环境并管理其组件的想法。 WBEM数据结构又基于公共信息模型(CIM),该模型实现了一种面向对象的方法来表示计算机系统。 Windows中WMI的进一步开发和支持已经停止; Microsoft建议使用类似的机制来管理基础结构-CIM对象。为了与它们一起使用,特殊的cmdlet出现在PowerShell 3.0中,我们将与WMI对应的cmdlet一起考虑。如果代码包含使用WMI的cmdlet调用,则应尽可能重写它。



在CIM模型的框架(在WMI中也使用)中,操作系统数据以具有属性和方法的类的形式表示。类按照名称空间技术或管理区域按层次结构排序并在逻辑上相关。有一个根Root名称空间,它具有以下子空间:CIMv2,Default,Secutiry和WMI。为了明确标识类(对象)的实例并描述相应资源的状态,使用了类属性,这些属性通常是只读的。方法用于管理资源。

可以通过完整路径访问类实例,该路径具有以下形式:

[\\ComputerName\NameSpace][:ClassName][.KeyProperty1=Value1][,KeyProperty2=Value2]…]

其中
ComputerName是计算机的名称;
NameSpace-名称空间;
ClassName-类的名称;
KeyProperty1 =值1,KeyProperty2 =值2-对象的属性以及用于标识对象的值。

在PowerShell之前,不存在简单的WMI工具。要访问这些对象,您必须使用高级语言(C ++,Visual Basic,Java Script)编写相当复杂的程序,或者使用自己的语言研究WMIC shell(WMI命令行,也已停产)。通过PowerShell,普通用户可以通过命令行或脚本访问WMI对象。首先,连接到WMI子系统,并使用Get-WmiObject cmdlet(别名gwmi)获得可用类的列表。若要获取CIM类的列表,请使用Get-CimClass cmdlet。

Get-CimClass
Get-WmiObject -List



我们已经在本地计算机上列出了这些类,但是您可以连接到远程计算机:

Get-CimClass -ComputerName IP- 
Get-CimClass -ComputerName _

要么

Get-WmiObject -ComputerName IP- -List
Get-WmiObject -ComputerName _ -List

默认情况下,Get-CimClass和Get-WmiObject cmdlet连接到Root \ CIMV2名称空间,该名称空间存储了大量用于管理系统的类。要更改名称空间,请使用-Namespace参数:

Get-CimClass -Namespace Root
Get-WmiObject -Namespace Root -List

知道了类的名称后,获取它的实例并不难。以下命令返回Win32_Service的所有实例,即 在本地计算机上注册的服务:

Get-WmiObject Win32_Service

与其他类型的对象一样,使用Get-Member显示属性和方法的列表。WMI对象方法可以直接访问,也可以使用Invoke-WmiMethod cmdlet访问。您还可以将cmdlet用于WMI对象以进行排序,过滤,分组等。

Get-WmiObject Win32_Service | Get-Member



若要获取CIM对象(类的实例),请使用Get-CimInstance cmdlet。与WMI不同,生成的CIM对象(结果对象或类实例)不包含类方法。由于无法直接提取方法,因此必须调用Invoke-CimMethod cmdlet。考虑Win32_Service类-在系统上运行的服务)及其在本地计算机上的后台打印程序服务的实例:

Get-CimInstance Win32_service -filter "Name='spooler'" 



让我们看一下结果对象的结构:

Get-CimInstance Win32_service -filter "Name='spooler'" | Get-Member



在这一点上,使用cmdlet处理CIM对象的好处尚不明显。它们主要涉及分布式环境中的远程工作,并且将在致力于解决实际管理问题的系列的最后一篇文章中进行详细讨论。

还有一个特定于WMI的工具包:WMI查询语言(WQL),一种类似SQL的查询语言。启动服务系统时,用于搜索所有初创公司的WQL查询如下所示:

select * from win32_service where startmode="Auto"

在PowerShell中,它们执行如下:

Get-WmiObject -Query 'select * from win32_service where startmode="Auto"'



使用COM对象


为了确保Windows中应用程序之间的交互,开发了一种用于链接和嵌入对象的技术(对象链接和嵌入或OLE)。后来,出现了OLE自动化技术,借助该技术,自动化客户端应用程序可以调用其他应用程序的功能-自动化服务器。 OLE和OLE Automation基于组件对象模型(COM)的核心技术,该组件对象模型为软件组件提供了一个二进制标准。使用它创建并在操作系统中注册的对象可以在其他应用程序中使用可执行文件或动态库来使用。

在90年代中期,代替OLE,开始使用另一个术语-ActiveX。在.NET平台出现之前,ActiveX技术被认为是关键,并且COM对象仍被积极地用于将应用程序集成到Windows中-许多Microsoft和第三方产品都是自动化服务器,并通过它们提供对服务的访问。为了访问对象,使用ProgID-在Windows注册表中注册时分配给它们的符号标识符。它具有以下形式:

_..

通常不指示版本:

_.

可用的ProgID的一些示例是:InternetExplorer.Application(Internet Explorer应用程序),Word.Application(Microsoft Word应用程序),WScript.Shell(Windows脚本宿主或WSH脚本服务器对象模型中的Shell类)。

您可以使用上一篇文章中讨论的New-Object cmdlet创建对象的实例,并使用Get-Member查看其结构:

$myshell = New-Object -ComObject WScript.Shell
$myshell | Get-Member



要使用对象,必须使用属性和方法。说,要在用户桌面上创建快捷方式,您需要调用CreateShortcut()方法:

$link = $myshell.CreateShortcut("$Home\Desktop\Home.lnk")

请注意,快捷方式也是一个COM对象:

$link | Get-Member



我们仍然需要填写其属性并保存:

$link.TargetPath = $Home
$link.Save()

这样,我们在活动用户的桌面上创建了一个快捷方式,现在我们将使用Shell.Application COM对象的示例来分析使用外部自动化服务。使用它,您可以在Windows资源管理器中自动执行一些操作:

$myshell=New-Object -ComObject Shell.Application

或简称:

$myshell=New-Object -com Shell.Application
$myshell | Get-Member



Shell.Application对象具有许多不同的窗口管理方法。例如,要显示给定目录的内容,请使用Explore():

$myshell.Explore("c:\")

使用Help()方法调用帮助系统:

$myshell.Help()


还有三种调用搜索对话框的方法:FindFiles(),FindComputer()和FindPrinter()。

$myshell.FindFiles()
$myshell.FindComputer()
$myshell.FindPrinter()

您可以使用FileRun()方法打开程序启动对话框,并且要调用日期/时间设置窗口,则需要SetTime()方法。例如,有用于调用任务栏设置窗口的方法,指示可用cpl文件之一的控制面板元素,用于管理打开的窗口的方法:

$myshell.MinimizeAll()
$myshell.UndoMinimizeAll()
$myshell.TileHorizontally()
$myshell.TileVertically()

Windows()方法允许您在资源管理器或Internet Explorer中访问打开的窗口的集合。让我们看看该集合可用的属性和方法:

$myshell.Windows() | Get-Member



还有其他有用的COM对象,其数量取决于系统中安装的软件。曾几何时,Windows中的主要自动化工具是WSH脚本服务器,其对象模型还包括COM对象:旨在与我们已经提到的WScript.Network和WScript.Shell的网络功能一起使用。后者不仅可以在桌面上创建快捷方式,还可以借助它的帮助显示例如带有消息和按钮的信息窗口,在应用程序之间切换,启动程序或模拟按键。

使用ADSI目录服务


通常,目录是指信息源,其中存储了有关某些对象的数据。目录服务是指分布式计算机系统的一部分,该系统允许您访问和操作存储的对象。目录服务可以合并有关网络对象和对其进行操作的服务的数据,它代表与网络资源进行交互的单个入口点。异构计算机网络中可能有许多这样的服务:用于非域计算机的本地SAM(安全帐户管理器),Active Directory等。

与不同目录服务的交互需要不同的工具,这会带来某些不便。从Windows 2000开始,Microsoft已为不依赖特定网络访问协议的操作系统引入了统一的Active Directory服务接口(ADSI)技术。为了找到对象,为目录定义了名称空间。由于不同的目录服务使用不同的命名方法,因此ADSI定义了一个唯一标识任何对象的约定。引入了两部分绑定字符串或ADsPath的概念。名称的第一部分定义目录服务(ADSI提供程序),第二部分-对象在目录中的位置。以下是指定不同ADSI提供程序的示例:

LDAP://用于基于LDAP的目录服务,包括 用于Active Directory;

WinNT://用于本地计算机。

在PowerShell中没有使用ADSI的特殊cmdlet。而是使用强制转换运算符[ADSI],后跟绑定字符串。例如,要从域test.ru连接到用户Ivanov,需要以下构造:

$user = [ADSI]"LDAP://CN=Ivanov,DC=TEST,DC=RU"

要使用本地帐户,您将必须使用相应名称连接到计算机(要连接到本地计算机,只需使用点号代替名称):

$computer = [ADSI]"WinNT://."

例如,在本地计算机上创建一个新用户Ivanov:

$user = $computer.Create("user","Ivanov")
$user.Put("Description","  PowerShell")
$user.SetInfo()

现在连接到它:

$user1 = [ADSI]"WinNT://./Ivanov,user"
$user1.Description



输出格式


交互式工作通常需要显示数据。在其他Shell中,命令和实用程序本身用于格式化输出,但是函数和cmdlet返回的二进制对象通常不知道如何执行此操作。在PowerShell中,输出由四个特殊的cmdlet格式化,这些cmdlet通过管道馈送对象。可以使用Get-Help获得更多详细信息:

Format-Table以表的形式格式化输出,该表的列包含对象属性的值或计算出的值。支持分组数据的功能;

Format-List将对象显示为属性列表,每个属性都显示在新行上。支持分组数据的功能;

格式自定义使用自定义视图格式化输出;

格式将对象格式化为一张宽表,其中每个对象仅显示一个属性。

如果未调用任何列出的cmdlet,则使用适合于所显示数据类型的格式化模块。显示规则以扩展名.ps1xml的XML格式存储在配置文件中,位于$ PSHome目录中。可以使用以下命令获取它们的列表:

dir $pshome\*format*.ps1xm

不建议手动编辑配置文件;最好使用Update-FormatData cmdlet创建自己的配置文件并将其包含在下载文件列表中。如果未定义所需类型的默认格式化程序,PowerShell将在列表中的屏幕上显示对象的属性。

到此结束了在PowerShell中使用对象的描述,本系列的最后一篇文章将致力于解决管理企业分布式信息环境的实际问题。在其中,所有描述的工具对我们都很有用。主要重点将放在CIM对象及其与WMI的比较上。过去的部分可以在下面的链接中找到。



1: Windows PowerShell
2: Windows PowerShell
3: ,
4: ,


All Articles