O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

A saída de texto de comandos na janela do PowerShell é apenas uma forma de exibir informações de uma maneira compreensível para os seres humanos. Na realidade, o ambiente é orientado trabalha com objetos: cmdlets e funções recebem esses objetos como entrada e retornam como saída, enquanto os tipos de variáveis disponíveis no modo interativo e em scripts são baseados em classes .NET. No quarto artigo da série, exploraremos o trabalho com objetos em mais detalhes.

Conteúdo:

Objetos no PowerShell
Visualizando a estrutura dos objetos
Filtrando objetos
Classificando objetos
Extraindo objetos e suas partes
ForEach-Object, Group-Object e Measure-Object
Criando objetos .NET e COM (New-Object)
Chamando métodos estáticos
Tipo PSCustomObject
Criando suas próprias classes

Objetos no PowerShell

Lembre-se de que um objeto é um conjunto de campos de dados (propriedades, eventos etc.) e métodos para manipulá-los. Sua estrutura é definida pelo tipo, que geralmente é baseado nas classes utilizadas na plataforma unificada .NET Core. Também é possível trabalhar com objetos COM, CIM (WMI) e ADSI. Propriedades e métodos são necessários para executar diversas ações sobre os dados, além disso, no PowerShell, os objetos podem ser passados como argumentos para funções e cmdlets, atribuindo seus valores a variáveis, e também existe um mecanismo de composição de comandos (pipeline). Cada comando no pipeline passa sua saída para o próximo sequencialmente — objeto por objeto. Para processamento, podem ser utilizados cmdlets compilados ou você pode criar suas próprias funções avançadas, para realizar diversas manobras com objetos no pipeline: filtragem, classificação, agrupamento e até mesmo alteração de sua estrutura. A transmissão de dados dessa forma tem uma vantagem significativa: o comando receptor não precisa lidar com a análise sintática do fluxo de bytes (texto), toda a informação necessária é facilmente extraída por meio do acesso às propriedades e métodos correspondentes.

Visualizando a estrutura dos objetos

Por exemplo, vamos executar o cmdlet Get-Process, que permite obter informações sobre os processos em execução no sistema:

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Ele exibirá na tela alguns dados de texto formatados, que não fornecem uma visão clara das propriedades dos objetos retornados e seus métodos. Para uma exploração mais detalhada da saída, é necessário aprender a investigar a estrutura dos objetos, e o cmdlet Get-Member nos ajudará com isso:

Get-Process | Get-Member

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Aqui já vemos o tipo e a estrutura, e com parâmetros adicionais podemos, por exemplo, exibir apenas as propriedades do objeto que entrou:

Get-Process | Get-Member -MemberType Property

Esse conhecimento será útil para resolver tarefas de administração em modo interativo ou para escrever seus próprios scripts: digamos, para obter informações sobre processos congelados pela propriedade Responding.

Filtrando objetos

O PowerShell permite passar objetos através do pipeline que atendem a uma determinada condição:

Where-Object { bloco do script }

O resultado da execução do bloco de script entre chaves deve ser um valor lógico. Se for verdadeiro ($true), o objeto que entrou no cmdlet Where-Object será passado adiante no pipeline, caso contrário (valor $false), ele será removido. Por exemplo, vamos exibir uma lista de serviços parados do Windows Server, ou seja, aqueles cujo status tem o valor "Stopped":

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Aqui novamente vemos uma representação textual, mas se desejarmos, entender o tipo e a estrutura interna dos objetos que passam pelo pipeline não é difícil:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Classificando objetos

Ao processar objetos pelo pipeline, frequentemente surge a necessidade de ordená-los. O cmdlet Sort-Object recebe os nomes das propriedades (chaves de ordenação) e retorna os objetos ordenados por seus valores. A saída dos processos em execução pode ser facilmente ordenada pelo tempo de CPU utilizado (propriedade cpu):

Get-Process | Sort-Object –Property cpu

O parâmetro -Property ao chamar o cmdlet Sort-Object pode ser omitido — ele é usado por padrão. Para a ordenação inversa, é utilizado o parâmetro -Descending:

Get-Process | Sort-Object cpu -Descending

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Extraindo objetos e suas partes

O cmdlet Select-Object permite destacar um número específico de objetos no início ou no final do pipeline com os parâmetros -First ou -Last. Com ele, é possível escolher objetos individuais ou propriedades específicas, além de criar novos objetos com base neles. Vamos analisar o funcionamento do cmdlet com exemplos simples.

O próximo comando exibe informações sobre 10 processos que consomem a maior quantidade de memória RAM (propriedade WS):

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

É possível destacar apenas certas propriedades dos objetos que passam pelo pipeline e criar novos com base nelas:

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

Como resultado do pipeline, obteremos um novo objeto cuja estrutura será diferente da estrutura retornada pelo cmdlet Get-Process. Vamos verificar isso com o Get-Member:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Observe que o Select-Object retorna um único objeto (-First 1), que possui apenas os dois campos que especificamos: seus valores foram copiados do primeiro objeto passado para o pipeline pelo cmdlet Get-Process. Uma das maneiras de criar objetos em scripts PowerShell é baseada no uso do Select-Object:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Com o Select-Object é possível adicionar propriedades calculadas aos objetos que precisam ser apresentadas como tabelas hash. O valor da primeira chave corresponde ao nome da propriedade, enquanto o valor da segunda chave é o valor da propriedade para o elemento atual do pipeline:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Vamos dar uma olhada na estrutura dos objetos que estão passando pelo pipeline:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

ForEach-Object, Group-Object e Measure-Object

Existem outros cmdlets para trabalhar com objetos. Para exemplificar, falaremos sobre três dos mais úteis:

ForEach-Object permite executar código na linguagem PowerShell para cada objeto no pipeline:

ForEach-Object { bloco de script }

Group-Object agrupa objetos com base no valor de uma propriedade:

Group-Object PropertyName

Se executá-lo com o parâmetro -NoElement, é possível descobrir a contagem dos elementos em cada grupo.

Measure-Object agrega diferentes parâmetros resumos com base nos valores dos campos dos objetos no pipeline (calcula a soma, e também encontra o valor mínimo, máximo ou médio):

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

Normalmente, os cmdlets discutidos são usados em modo interativo, enquanto em scripts, frequentemente, são criados funções com blocos Begin, Process e End.

Criando objetos .NET e COM (New-Object)

Existem muitos componentes de software com interfaces .NET Core e COM que são úteis para administradores de sistema. Com a classe System.Diagnostics.EventLog é possível gerenciar os logs do sistema diretamente do Windows PowerShell. Vamos detalhar um exemplo de criação de uma instância dessa classe utilizando o cmdlet New-Object com o parâmetro -TypeName:

New-Object -TypeName System.Diagnostics.EventLog

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Como não especificamos um determinado log de eventos, a instância da classe recebida não contém dados. Para alterar isso, é necessário chamar um método construtor especial durante sua criação usando o parâmetro -ArgumentList. Se quisermos acessar o log de aplicativos, devemos passar a string "Application" como argumento para o construtor:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Observe que a saída do comando foi salva na variável $AppLog. Embora no modo interativo geralmente sejam utilizados pipelines, a escrita de scripts frequentemente requer a сохранение uma referência ao objeto. Além disso, as classes principais do .NET Core estão contidas no namespace System: o PowerShell procura, por padrão, os tipos especificados nele, portanto, é totalmente correto escrever Diagnostics.EventLog em vez de System.Diagnostics.EventLog.

Para trabalhar com o log, podemos chamar os métodos correspondentes:

$AppLog | Get-Member -MemberType Method

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Digamos que ele é limpo pelo método Clear() na presença de permissões de acesso:

$AppLog.Clear()

O cmdlet New-Object também é usado para trabalhar com componentes COM. Existem muitos — desde bibliotecas de scripts do Windows entregues com o servidor até aplicativos ActiveX, como o Internet Explorer, por exemplo. Para criar um objeto COM, é necessário especificar o parâmetro -ComObject com o identificador ProgId da classe desejada:

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

Para criar seus próprios objetos com uma estrutura arbitrária, o uso do New-Object parece excessivamente arcaico e volumoso; esse cmdlet é utilizado para trabalhar com componentes de software externos ao PowerShell. Em artigos futuros, essa questão será explorada com mais detalhes. Além de objetos .NET e COM, também estudaremos objetos CIM (WMI) e ADSI.

Chamando métodos estáticos

Não é possível criar instâncias de algumas classes .NET Core: incluem-se entre elas System.Environment e System.Math. Elas são estáticas e contêm apenas propriedades e métodos estáticos. Na verdade, são bibliotecas de referência que são usadas sem a criação de objetos. Para referenciar uma classe estática, pode-se usar o literal, colocando o nome do tipo entre colchetes. Ao fazer isso, se olharmos a estrutura do objeto usando Get-Member, veremos o tipo System.RuntimeType em vez de System.Environment:

[System.Environment] | Get-Member

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Para visualizar apenas elementos estáticos, é necessário chamar Get-Member com o parâmetro -Static (note o tipo do objeto):

[System.Environment] | Get-Member -Static

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Para acessar propriedades e métodos estáticos, utilizam-se dois pontos consecutivos em vez de um ponto após o literal:

[System.Environment]::OSVersion

Ou

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Tipo PSCustomObject

Entre os inúmeros tipos de dados disponíveis no PowerShell, merece destaque o PSCustomObject, destinado a armazenar objetos com estrutura arbitrária. Criar tal objeto com o cmdlet New-Object é considerado um método clássico, mas volumoso e obsoleto:

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

Vamos observar a estrutura do objeto:

$object | Get-Member

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

A partir do PowerShell 3.0, há também uma outra sintaxe disponível:

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

Os dados podem ser acessados de uma das seguintes maneiras equivalentes:

$object.Name

$object.'Name'

$value = 'Name'
$object.$value

Vamos dar um exemplo de conversão para um objeto de uma tabela hash existente:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Uma das desvantagens dos objetos desse tipo é que a ordem de suas propriedades pode mudar. Para evitar isso, é necessário usar o atributo [ordered]:

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

Existem outras opções para criar um objeto: acima, abordamos o uso do cmdlet Select-Object. Agora falta entender como adicionar e remover elementos. Fazer isso para o objeto do exemplo anterior é bastante simples:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

O cmdlet Add-Member permite adicionar não apenas propriedades, mas também métodos ao objeto $object usando a construção '-MemberType ScriptMethod':

$ScriptBlock = {
    # código 
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member

Observe que, para armazenar o código do novo método, usamos a variável $ScriptBlock do tipo ScriptBlock.

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Para remover propriedades, utiliza-se o método correspondente:

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

Criando suas próprias classes

No PowerShell 5.0, a definição de classes foi introduzida. usando a sintaxe característica das linguagens de programação orientadas a objetos. Para isso, a palavra-chave Class é usada, seguida pelo nome da classe e a descrição de seu corpo entre chaves:

class MyClass
{
    # corpo da classe
}

Este é um tipo real do .NET Core, cujo corpo descreve suas propriedades, métodos e outros elementos. Vamos considerar um exemplo da definição da classe mais simples:

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

Para criar um objeto (instância da classe) usamos o cmdlet New-Object, ou o literal do tipo [MyClass] e o método pseudo-estático new (construtor padrão):

$object = New-Object -TypeName MyClass

ou

$object = [MyClass]::new()

Vamos analisar a estrutura do objeto:

$object | Get-Member

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Não devemos nos esquecer do escopo: não se pode referir ao nome do tipo como uma string ou usar o literal do tipo fora do script ou módulo onde a classe é definida. Nesse caso, funções podem retornar instâncias da classe (objetos) que estarão disponíveis fora do módulo ou script.

Após a criação do objeto, vamos preencher suas propriedades:

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

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Vale notar que na descrição da classe definimos não apenas os tipos das propriedades, mas também seus valores padrão:

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

A descrição do método da classe se assemelha à descrição de uma função, mas sem o uso da palavra-chave function. Assim como nas funções, os métodos podem receber parâmetros, se necessário:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
     
     # descrição do método
     Smile([bool]$param1)
     {
         If($param1) {
            Write-Host ':)'
         }
     }
}

Agora, um representante da nossa classe consegue sorrir:

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

Os métodos podem ser sobrecarregados, além disso, a classe pode ter propriedades e métodos estáticos, bem como construtores, cujos nomes coincidem com o nome da própria classe. Uma classe definida em um script ou módulo PowerShell pode servir como base para outra — assim se realiza a herança. Nesse caso, classes existentes do .NET podem ser usadas como classes base:

class MyClass2 : MyClass
{
      # corpo da nova classe, que é base para MyClass
}
[MyClass2]::new().Smile($true)

Nossa descrição sobre o trabalho com objetos no PowerShell é difícil de considerar completa. Nas próximas publicações, tentaremos aprofundá-la com exemplos práticos: o quinto artigo da série será dedicado às questões de integração do PowerShell com componentes de software de terceiros. As partes anteriores podem ser encontradas nos links abaixo.

Parte 1: principais recursos do Windows PowerShell
Parte 2: introdução à linguagem de programação Windows PowerShell
Parte 3: passagem de parâmetros para scripts e funções, criação de cmdlets

O que é o Windows PowerShell e como usá-lo? Parte 4: Trabalhando com objetos, classes próprias

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster