PowerShell解释器窗口中命令的文本输出只是一种以适合人类感知的形式显示信息的方式。 实际上星期三
目录:
PowerShell 中的对象
让我们回想一下,对象是数据字段(属性、事件等)和处理它们的方法(方法)的集合。 它的结构由类型指定,该类型通常基于统一.NET Core平台中使用的类。 还可以使用 COM、CIM (WMI) 和 ADSI 对象。 对数据执行各种操作需要属性和方法;此外,在PowerShell中,对象可以作为参数传递给函数和cmdlet,将它们的值赋给变量,还有
查看对象的结构
例如,让我们运行 Get-Process cmdlet,它允许您获取有关系统中运行的进程的信息:
它将显示一些格式化的文本数据,这些数据不提供有关返回对象及其方法的属性的任何信息。 为了微调输出,我们需要学习如何检查对象的结构,Get-Member cmdlet 将帮助我们完成此任务:
Get-Process | Get-Member
在这里,我们已经看到了类型和结构,并且在附加参数的帮助下,我们可以仅显示输入中包含的对象的属性:
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"}
这里我们再次看到了文本表示,但是如果你想了解通过管道传递的对象的类型和内部结构并不困难:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
对对象进行排序
当管道处理对象时,经常需要对它们进行排序。 Sort-Object cmdlet 传递属性名称(排序键)并返回按其值排序的对象。 通过花费的 CPU 时间(cpu 属性)对正在运行的进程的输出进行排序很容易:
Get-Process | Sort-Object –Property cpu
调用 Sort-Object cmdlet 时可以省略 -Property 参数;默认情况下使用该参数。 对于反向排序,请使用 -Descending 参数:
Get-Process | Sort-Object cpu -Descending
选择对象及其部分
Select-Object cmdlet 允许您使用 -First 或 -Last 参数在管道的开头或结尾选择特定数量的对象。 在它的帮助下,您可以选择单个对象或某些属性,还可以基于它们创建新对象。 让我们通过简单的示例来了解 cmdlet 的工作原理。
以下命令显示有关消耗最大 RAM 量(WS 属性)的 10 个进程的信息:
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
您可以仅选择通过管道的对象的某些属性,并基于它们创建新的属性:
Get-Process | Select-Object ProcessName, Id -First 1
作为管道操作的结果,我们将收到一个新对象,其结构将与 Get-Process cmdlet 返回的结构不同。 让我们使用 Get-Member 来验证这一点:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
请注意,Select-Object 返回一个对象 (-First 1),该对象仅包含我们指定的两个字段:它们的值是从 Get-Process cmdlet 传递到管道的第一个对象中复制的。 在 PowerShell 脚本中创建对象的方法之一是基于使用 Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
使用 Select-Object,您可以将计算属性添加到需要表示为的对象
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
我们来看一下通过传送带的物体的结构:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-对象、组-对象和测量-对象
还有其他用于处理对象的 cmdlet。 作为例子,我们来谈谈三个最有用的:
每个对象 允许您为管道中的每个对象运行 PowerShell 代码:
ForEach-Object { блок сценария }
组对象 按属性值对对象进行分组:
Group-Object PropertyName
如果使用 -NoElement 参数运行它,您可以找出组中的元素数量。
测量对象 按管道中的对象字段值聚合各种汇总参数(计算总和,同时还求最小值、最大值或平均值):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
通常,所讨论的 cmdlet 是交互式使用的,并且通常是在脚本中创建的。
创建 .NET 和 COM 对象(新对象)
有许多具有 .NET Core 和 COM 接口的软件组件对系统管理员很有用。 使用 System.Diagnostics.EventLog 类,您可以直接从 Windows PowerShell 管理系统日志。 让我们看一下使用带有 -TypeName 参数的 New-Object cmdlet 创建此类实例的示例:
New-Object -TypeName System.Diagnostics.EventLog
由于我们没有指定特定的事件日志,因此生成的类实例不包含数据。 要更改此设置,您需要在创建过程中使用 -ArgumentList 参数调用特殊的构造函数方法。 如果我们想访问应用程序日志,我们应该将字符串“Application”作为参数传递给构造函数:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
请注意,我们将命令的输出保存在 $AppLog 变量中。 尽管管道通常用于交互模式,但编写脚本通常需要维护对对象的引用。 此外,核心 .NET Core 类包含在 System 命名空间中:PowerShell 默认情况下会查找其中的指定类型,因此编写 Diagnostics.EventLog 而不是 System.Diagnostics.EventLog 是非常正确的。
要使用日志,您可以使用适当的方法:
$AppLog | Get-Member -MemberType Method
假设如果有访问权限,则由 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。 他们是
[System.Environment] | Get-Member
要仅查看静态成员,请使用 -Static 参数调用 Get-Member(注意对象类型):
[System.Environment] | Get-Member -Static
要访问静态属性和方法,请在文字后面使用两个连续的冒号而不是句点:
[System.Environment]::OSVersion
或
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
类型 PSCustomObject
在 PowerShell 中可用的众多数据类型中,值得一提的是 PSCustomObject,它专为存储具有任意结构的对象而设计。 使用 New-Object cmdlet 创建这样的对象被认为是一种经典但麻烦且过时的方法:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
我们看一下对象的结构:
$object | Get-Member
从 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()
这种类型的对象的缺点之一是它们的属性顺序可以改变。 为了避免这种情况,您必须使用 [ordered] 属性:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
还有其他用于创建对象的选项:上面我们查看了使用 cmdlet
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Add-Member cmdlet 不仅允许您使用“-MemberType ScriptMethod”构造向先前创建的 $object 添加属性,还可以添加方法:
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
请注意,我们使用 ScriptBlock 类型的 $ScriptBlock 变量来存储新方法的代码。
要删除属性,请使用相应的方法:
$object.psobject.properties.remove('Name')
创建您自己的课程
PowerShell 5.0 引入了定义的能力
class MyClass
{
# тело класса
}
这是真正的 .NET Core 类型,其主体描述了其属性、方法和其他元素。 让我们看一个定义最简单的类的示例:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
要创建对象(类实例),请使用 cmdlet
$object = New-Object -TypeName MyClass
или
$object = [MyClass]::new()
我们来分析一下对象的结构:
$object | Get-Member
不要忘记范围:您不能将类型名称作为字符串引用,也不能在定义该类的脚本或模块之外使用类型文字。 在这种情况下,函数可以返回可在模块或脚本外部访问的类实例(对象)。
创建对象后,填写其属性:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
请注意,类描述不仅指定属性类型,还指定它们的默认值:
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)
方法可以重载;此外,类还具有
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
我们对在 PowerShell 中使用对象的描述并不详尽。 在接下来的出版物中,我们将尝试通过实际示例来加深它:该系列的第五篇文章将专门讨论 PowerShell 与第三方软件组件的集成问题。 过去的部分可以在下面的链接中找到。
来源: habr.com