A saída de texto dos comandos na xanela do intérprete de PowerShell é só un xeito de mostrar información nun formato axeitado para a percepción humana. En realidade o mércores
Imaxe:
Obxectos en PowerShell
Lembremos que un obxecto é unha colección de campos de datos (propiedades, eventos, etc.) e métodos para procesalos (métodos). A súa estrutura está especificada por un tipo, que normalmente se basea en clases utilizadas na plataforma unificada .NET Core. Tamén é posible traballar con obxectos COM, CIM (WMI) e ADSI. Son necesarias propiedades e métodos para realizar varias accións sobre os datos; ademais, en PowerShell, os obxectos pódense pasar como argumentos a funcións e cmdlets, asignar os seus valores a variables e tamén hai
Visualización da estrutura dos obxectos
Por exemplo, executemos o cmdlet Get-Process, que lle permite obter información sobre os procesos que se executan no sistema:
Mostrará algúns datos de texto formateados que non dan ningunha idea sobre as propiedades dos obxectos devoltos e os seus métodos. Para afinar a saída, necesitamos aprender a examinar a estrutura dos obxectos e o cmdlet Get-Member axudaranos con isto:
Get-Process | Get-Member
Aquí xa vemos o tipo e a estrutura, e coa axuda de parámetros adicionais podemos, por exemplo, mostrar só as propiedades do obxecto incluído na entrada:
Get-Process | Get-Member -MemberType Property
Estes coñecementos serán necesarios para resolver problemas de administración de forma interactiva ou para escribir os seus propios scripts: por exemplo, para obter información sobre procesos colgados mediante a propiedade Responding.
Filtrado de obxectos
PowerShell permite que os obxectos que cumpran unha determinada condición pasen por unha canalización:
Where-Object { блок сценария }
O resultado da execución do bloque de script entre parénteses debe ser un valor booleano. Se é verdadeiro ($true), o obxecto que se introduce no cmdlet Where-Object pasarase ao longo da canalización; se non, ($false) eliminarase. Por exemplo, imos amosar unha lista de servizos de Windows Server parados, é dicir. aqueles cuxa propiedade de estado está definida como "Detido":
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Aquí de novo vemos unha representación textual, pero se queres comprender o tipo e a estrutura interna dos obxectos que pasan pola canalización non é difícil:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Clasificación de obxectos
Cando se procesan obxectos, moitas veces hai que clasificalos. O cmdlet Sort-Object recibe os nomes das propiedades (claves de clasificación) e devolve os obxectos ordenados polos seus valores. É doado clasificar a saída dos procesos en execución polo tempo de CPU empregado (propiedade da CPU):
Get-Process | Sort-Object –Property cpu
O parámetro -Property pódese omitir ao chamar ao cmdlet Sort-Object; úsase por defecto. Para a ordenación inversa, use o parámetro -Descendente:
Get-Process | Sort-Object cpu -Descending
Selección de obxectos e as súas partes
O cmdlet Select-Object permítelle seleccionar un número específico de obxectos ao comezo ou ao final dunha canalización utilizando os parámetros -First ou -Last. Coa súa axuda, pode seleccionar obxectos individuais ou determinadas propiedades e tamén crear novos obxectos baseados neles. Vexamos como funciona o cmdlet usando exemplos sinxelos.
O seguinte comando mostra información sobre os 10 procesos que consumen a cantidade máxima de RAM (propiedade WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Pode seleccionar só certas propiedades dos obxectos que pasan pola canalización e crear outras novas baseadas nelas:
Get-Process | Select-Object ProcessName, Id -First 1
Como resultado da operación da canalización, recibiremos un novo obxecto, cuxa estrutura será diferente da estrutura devolta polo cmdlet Get-Process. Verifiquemos isto usando Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Teña en conta que Select-Object devolve un único obxecto (-First 1) que só ten dous dos campos que especificamos: os seus valores foron copiados do primeiro obxecto pasado á canalización polo cmdlet Get-Process. Unha das formas de crear obxectos nos scripts de PowerShell baséase en usar Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Usando Select-Object, pode engadir propiedades calculadas aos obxectos que deben representarse como
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Vexamos a estrutura dos obxectos que pasan polo transportador:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-Object, Group-Object e Measure-Object
Hai outros cmdlets para traballar con obxectos. Como exemplo, imos falar dos tres máis útiles:
Para cada obxecto permítelle executar código de PowerShell para cada obxecto da canalización:
ForEach-Object { блок сценария }
Grupo-Obxecto agrupa obxectos por valor de propiedade:
Group-Object PropertyName
Se o executas co parámetro -NoElement, podes saber o número de elementos dos grupos.
Medida-Obxecto agrega varios parámetros de resumo por valores de campo de obxecto na canalización (calcula a suma e tamén atopa o valor mínimo, máximo ou medio):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Normalmente, os cmdlets comentados úsanse de forma interactiva e adoitan crearse en scripts.
Creación de obxectos .NET e COM (New-Object)
Hai moitos compoñentes de software con interfaces .NET Core e COM que son útiles para os administradores do sistema. Usando a clase System.Diagnostics.EventLog, pode xestionar os rexistros do sistema directamente desde Windows PowerShell. Vexamos un exemplo de creación dunha instancia desta clase usando o cmdlet New-Object co parámetro -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Como non especificamos un rexistro de eventos específico, a instancia resultante da clase non contén datos. Para cambiar isto, cómpre chamar a un método construtor especial durante a súa creación usando o parámetro -ArgumentList. Se queremos acceder ao rexistro da aplicación, debemos pasar a cadea "Aplicación" como argumento ao construtor:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Teña en conta que gardamos a saída do comando na variable $AppLog. Aínda que as canalizacións úsanse habitualmente no modo interactivo, escribir guións adoita requirir manter unha referencia a un obxecto. Ademais, as clases básicas de .NET Core están contidas no espazo de nomes do sistema: PowerShell busca por defecto os tipos especificados nel, polo que escribir Diagnostics.EventLog en lugar de System.Diagnostics.EventLog é bastante correcto.
Para traballar co rexistro, pode usar os métodos axeitados:
$AppLog | Get-Member -MemberType Method
Digamos que se borra co método Clear() se hai dereitos de acceso:
$AppLog.Clear()
O cmdlet New-Object tamén se usa para traballar con compoñentes COM. Hai moitos deles, desde as bibliotecas que se proporcionan co servidor de scripts de Windows ata aplicacións ActiveX, como Internet Explorer. Para crear un obxecto COM, cómpre establecer o parámetro -ComObject co ProgId programático da clase desexada:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Para crear os teus propios obxectos cunha estrutura arbitraria, usar New-Object parece demasiado arcaico e engorroso; este cmdlet úsase para traballar con compoñentes de software externos a PowerShell. En próximos artigos este asunto será discutido con máis detalle. Ademais dos obxectos .NET e COM, tamén exploraremos obxectos CIM (WMI) e ADSI.
Chamada a métodos estáticos
Algunhas clases de .NET Core non se poden instanciar, incluíndo System.Environment e System.Math. Eles son
[System.Environment] | Get-Member
Para ver só membros estáticos, chame a Get-Member co parámetro -Static (teña en conta o tipo de obxecto):
[System.Environment] | Get-Member -Static
Para acceder ás propiedades e métodos estáticos, use dous dous puntos consecutivos en lugar dun punto despois do literal:
[System.Environment]::OSVersion
Ou
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Escriba PSCustomObject
Entre os numerosos tipos de datos dispoñibles en PowerShell, cómpre mencionar PSCustomObject, deseñado para almacenar obxectos cunha estrutura arbitraria. Crear un obxecto deste tipo usando o cmdlet New-Object considérase un xeito clásico, pero engorroso e obsoleto:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Vexamos a estrutura do obxecto:
$object | Get-Member
A partir de PowerShell 3.0, hai outra sintaxe dispoñible:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Podes acceder aos datos dunha das formas equivalentes:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Aquí tes un exemplo de conversión dunha táboa hash existente nun obxecto:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Unha das desvantaxes dos obxectos deste tipo é que a orde das súas propiedades pode cambiar. Para evitar isto, debes usar o atributo [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Hai outras opcións para crear un obxecto: máis arriba miramos usando o cmdlet
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
O cmdlet Add-Member permítelle engadir non só propiedades, senón tamén métodos a un $object creado previamente mediante a construción "-MemberType ScriptMethod":
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Teña en conta que usamos a variable $ScriptBlock de tipo ScriptBlock para almacenar o código do novo método.
Para eliminar propiedades, use o método correspondente:
$object.psobject.properties.remove('Name')
Creando as túas propias clases
PowerShell 5.0 introduciu a capacidade de definir
class MyClass
{
# тело класса
}
Este é un verdadeiro tipo .NET Core, cun corpo que describe as súas propiedades, métodos e outros elementos. Vexamos un exemplo de definición da clase máis sinxela:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Para crear un obxecto (instancia de clase), use o cmdlet
$object = New-Object -TypeName MyClass
ou
$object = [MyClass]::new()
Analizamos a estrutura do obxecto:
$object | Get-Member
Non se esqueza do ámbito: non pode facer referencia a un nome de tipo como unha cadea nin usar un literal de tipo fóra do script ou módulo no que se define a clase. Neste caso, as funcións poden devolver instancias de clase (obxectos) que serán accesibles fóra do módulo ou do script.
Despois de crear o obxecto, enche as súas propiedades:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Teña en conta que a descrición da clase especifica non só os tipos de propiedade, senón tamén os seus valores predeterminados:
class Example
{
[string]$Name = 'John Doe'
}
A descrición dun método de clase aseméllase á descrición dunha función, pero sen utilizar a palabra función. Como nunha función, os parámetros pásanse aos métodos se é necesario:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Agora o representante da nosa clase pode sorrir:
$object = [MyClass]::new()
$object.Smile($true)
Os métodos pódense sobrecargar; ademais, ten unha clase
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
A nosa descrición do traballo con obxectos en PowerShell non é exhaustiva. Nas seguintes publicacións tentaremos afondalo con exemplos prácticos: o quinto artigo da serie estará dedicado ás cuestións da integración de PowerShell con compoñentes de software de terceiros. As partes pasadas pódense atopar nas ligazóns a continuación.
Fonte: www.habr.com