什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

PowerShell解释器窗口中命令的文本输出只是一种以适合人类感知的形式显示信息的方式。 实际上星期三 重点 使用对象:cmdlet 和函数接收它们作为输入并 在出口处返回,并且交互式和脚本中可用的变量类型基于 .NET 类。 在本系列的第四篇文章中,我们将更详细地研究如何使用对象。

目录:

PowerShell 中的对象
查看对象的结构
过滤对象
对对象进行排序
选择对象及其部分
ForEach-对象、组-对象和测量-对象
创建 .NET 和 COM 对象(新对象)
调用静态方法
类型 PSCustomObject
创建您自己的课程

PowerShell 中的对象

让我们回想一下,对象是数据字段(属性、事件等)和处理它们的方法(方法)的集合。 它的结构由类型指定,该类型通常基于统一.NET Core平台中使用的类。 还可以使用 COM、CIM (WMI) 和 ADSI 对象。 对数据执行各种操作需要属性和方法;此外,在PowerShell中,对象可以作为参数传递给函数和cmdlet,将它们的值赋给变量,还有 命令组合机制 (输送机或管道)。 管道中的每个命令将其输出依次逐个对象传递到下一个命令。 对于处理,您可以使用编译的 cmdlet 或创建您自己的 高级功能对管道中的对象执行各种操作:过滤、排序、分组,甚至更改其结构。 以这种形式传输数据具有很大的优势:接收团队不需要解析字节流(文本),通过调用适当的属性和方法可以轻松检索所有必要的信息。

查看对象的结构

例如,让我们运行 Get-Process cmdlet,它允许您获取有关系统中运行的进程的信息:

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

它将显示一些格式化的文本数据,这些数据不提供有关返回对象及其方法的属性的任何信息。 为了微调输出,我们需要学习如何检查对象的结构,Get-Member cmdlet 将帮助我们完成此任务:

Get-Process | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

在这里,我们已经看到了类型和结构,并且在附加参数的帮助下,我们可以仅显示输入中包含的对象的属性:

Get-Process | Get-Member -MemberType Property

以交互方式解决管理问题或编写自己的脚本将需要这些知识:例如,使用 Responding 属性获取有关挂起进程的信息。

过滤对象

PowerShell允许满足特定条件的对象通过管道传递:

Where-Object { блок сценария }

执行括号内的脚本块的结果必须是布尔值。 如果为 true ($true),则输入到Where-Object cmdlet 的对象将沿着管道传递,否则($false) 将被删除。 例如,让我们显示已停止的 Windows Server 服务的列表,即Status 属性设置为“Stopped”的那些:

Get-Service | Where-Object {$_.Status -eq "Stopped"}

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

这里我们再次看到了文本表示,但是如果你想了解通过管道传递的对象的类型和内部结构并不困难:

Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

对对象进行排序

当管道处理对象时,经常需要对它们进行排序。 Sort-Object cmdlet 传递属性名称(排序键)并返回按其值排序的对象。 通过花费的 CPU 时间(cpu 属性)对正在运行的进程的输出进行排序很容易:

Get-Process | Sort-Object –Property cpu

调用 Sort-Object cmdlet 时可以省略 -Property 参数;默认情况下使用该参数。 对于反向排序,请使用 -Descending 参数:

Get-Process | Sort-Object cpu -Descending

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

选择对象及其部分

Select-Object cmdlet 允许您使用 -First 或 -Last 参数在管道的开头或结尾选择特定数量的对象。 在它的帮助下,您可以选择单个对象或某些属性,还可以基于它们创建新对象。 让我们通过简单的示例来了解 cmdlet 的工作原理。

以下命令显示有关消耗最大 RAM 量(WS 属性)的 10 个进程的信息:

Get-Process | Sort-Object WS -Descending | Select-Object -First 10

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

您可以仅选择通过管道的对象的某些属性,并基于它们创建新的属性:

Get-Process | Select-Object ProcessName, Id -First 1

作为管道操作的结果,我们将收到一个新对象,其结构将与 Get-Process cmdlet 返回的结构不同。 让我们使用 Get-Member 来验证这一点:

Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

请注意,Select-Object 返回一个对象 (-First 1),该对象仅包含我们指定的两个字段:它们的值是从 Get-Process cmdlet 传递到管道的第一个对象中复制的。 在 PowerShell 脚本中创建对象的方法之一是基于使用 Select-Object:

$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

使用 Select-Object,您可以将计算属性添加到需要表示为的对象 哈希表。 在这种情况下,其第一个键的值对应于属性名称,第二个键的值对应于当前管道元素的属性值:

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

我们来看一下通过传送带的物体的结构:

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

ForEach-对象、组-对象和测量-对象

还有其他用于处理对象的 cmdlet。 作为例子,我们来谈谈三个最有用的:

每个对象 允许您为管道中的每个对象运行 PowerShell 代码:

ForEach-Object { блок сценария }

组对象 按属性值对对象进行分组:

Group-Object PropertyName

如果使用 -NoElement 参数运行它,您可以找出组中的元素数量。

测量对象 按管道中的对象字段值聚合各种汇总参数(计算总和,同时还求最小值、最大值或平均值):

Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum

通常,所讨论的 cmdlet 是交互式使用的,并且通常是在脚本中创建的。 功能 包含 Begin、Process 和 End 块。

创建 .NET 和 COM 对象(新对象)

有许多具有 .NET Core 和 COM 接口的软件组件对系统管理员很有用。 使用 System.Diagnostics.EventLog 类,您可以直接从 Windows PowerShell 管理系统日志。 让我们看一下使用带有 -TypeName 参数的 New-Object cmdlet 创建此类实例的示例:

New-Object -TypeName System.Diagnostics.EventLog

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

由于我们没有指定特定的事件日志,因此生成的类实例不包含数据。 要更改此设置,您需要在创建过程中使用 -ArgumentList 参数调用特殊的构造函数方法。 如果我们想访问应用程序日志,我们应该将字符串“Application”作为参数传递给构造函数:

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

请注意,我们将命令的输出保存在 $AppLog 变量中。 尽管管道通常用于交互模式,但编写脚本通常需要维护对对象的引用。 此外,核心 .NET Core 类包含在 System 命名空间中:PowerShell 默认情况下会查找其中的指定类型,因此编写 Diagnostics.EventLog 而不是 System.Diagnostics.EventLog 是非常正确的。

要使用日志,您可以使用适当的方法:

$AppLog | Get-Member -MemberType Method

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

假设如果有访问权限,则由 Clear() 方法清除:

$AppLog.Clear()

New-Object cmdlet 还用于处理 COM 组件。 其中有很多 - 从 Windows 脚本服务器提供的库到 ActiveX 应用程序,例如 Internet Explorer。 要创建 COM 对象,您需要使用所需类的编程 ProgId 设置 -ComObject 参数:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

要创建具有任意结构的自己的对象,使用 New-Object 似乎过于陈旧和麻烦;此 cmdlet 用于与 PowerShell 外部的软件组件配合使用。 在以后的文章中,我们将更详细地讨论这个问题。 除了.NET 和COM 对象之外,我们还将探索CIM (WMI) 和ADSI 对象。

调用静态方法

某些 .NET Core 类无法实例化,包括 System.Environment 和 System.Math。 他们是 静止的 并且仅包含静态属性和方法。 这些本质上是在不创建对象的情况下使用的参考库。 您可以通过将类型名称括在方括号中来通过文字引用静态类。 但是,如果我们使用 Get-Member 查看对象的结构,我们将看到类型 System.RuntimeType 而不是 System.Environment:

[System.Environment] | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

要仅查看静态成员,请使用 -Static 参数调用 Get-Member(注意对象类型):

[System.Environment] | Get-Member -Static

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

要访问静态属性和方法,请在文字后面使用两个连续的冒号而不是句点:

[System.Environment]::OSVersion

$test=[System.Math]::Sqrt(25) 
$test
$test.GetType()

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

类型 PSCustomObject

在 PowerShell 中可用的众多数据类型中,值得一提的是 PSCustomObject,它专为存储具有任意结构的对象而设计。 使用 New-Object cmdlet 创建这样的对象被认为是一种经典但麻烦且过时的方法:

$object = New-Object  –TypeName PSCustomObject -Property @{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'}

我们看一下对象的结构:

$object | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

从 PowerShell 3.0 开始,可以使用另一种语法:

$object = [PSCustomObject]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

您可以通过等效方式之一访问数据:

$object.Name

$object.'Name'

$value = 'Name'
$object.$value

以下是将现有哈希表转换为对象的示例:

$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

这种类型的对象的缺点之一是它们的属性顺序可以改变。 为了避免这种情况,您必须使用 [ordered] 属性:

$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

还有其他用于创建对象的选项:上面我们查看了使用 cmdlet 选择对象。 剩下的就是弄清楚添加和删除元素。 对上一个示例中的对象执行此操作非常简单:

$object | Add-Member –MemberType NoteProperty –Name Age  –Value 33
$object | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

Add-Member cmdlet 不仅允许您使用“-MemberType ScriptMethod”构造向先前创建的 $object 添加属性,还可以添加方法:

$ScriptBlock = {
    # код 
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member

请注意,我们使用 ScriptBlock 类型的 $ScriptBlock 变量来存储新方法的代码。

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

要删除属性,请使用相应的方法:

$object.psobject.properties.remove('Name')

创建您自己的课程

PowerShell 5.0 引入了定义的能力 使用面向对象编程语言的语法特征。 服务词 Class 就是用于此目的,之后您应该指定类的名称并在运算符括号中描述其主体:

class MyClass
{
    # тело класса
}

这是真正的 .NET Core 类型,其主体描述了其属性、方法和其他元素。 让我们看一个定义最简单的类的示例:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
}

要创建对象(类实例),请使用 cmdlet 新对象,或 [MyClass] 类型的文字并且 伪静力法 新(默认构造函数):

$object = New-Object -TypeName MyClass

или

$object = [MyClass]::new()

我们来分析一下对象的结构:

$object | Get-Member

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

不要忘记范围:您不能将类型名称作为字符串引用,也不能在定义该类的脚本或模块之外使用类型文字。 在这种情况下,函数可以返回可在模块或脚本外部访问的类实例(对象)。

创建对象后,填写其属性:

$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

请注意,类描述不仅指定属性类型,还指定它们的默认值:

class Example
{
     [string]$Name = 'John Doe'
}

类方法的描述类似于函数的描述,但不使用函数词。 与在函数中一样,如有必要,参数会传递给方法:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
     
     #описание метода
     Smile([bool]$param1)
     {
         If($param1) {
            Write-Host ':)'
         }
     }
}

现在我们班代表会微笑了:

$object = [MyClass]::new()
$object.Smile($true)

方法可以重载;此外,类还具有 静态属性和方法,以及名称与类本身名称一致的构造函数。 脚本或 PowerShell 模块中定义的类可以作为另一个类的基础 - 这就是继承的实现方式。 在这种情况下,允许使用现有的 .NET 类作为基类:

class MyClass2 : MyClass
{
      #тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)

我们对在 PowerShell 中使用对象的描述并不详尽。 在接下来的出版物中,我们将尝试通过实际示例来加深它:该系列的第五篇文章将专门讨论 PowerShell 与第三方软件组件的集成问题。 过去的部分可以在下面的链接中找到。

第 1 部分:基本 Windows PowerShell 功能
第 2 部分:Windows PowerShell 编程语言简介
第 3 部分:将参数传递给脚本和函数,创建 cmdlet

什么是 Windows PowerShell 以及它的用途是什么? 第 4 部分:使用对象、自己的类

来源: habr.com

添加评论