O que é o Windows PowerShell e o que ele come? Parte 2: Introdução à linguagem de programação

Historicamente, os utilitários de linha de comando nos sistemas Unix são mais desenvolvidos do que no Windows; no entanto, com o advento de uma nova solução, a situação mudou.



Para o PowerShell, você pode escrever scripts em uma linguagem interpretada de múltiplos paradigmas que contém elementos da programação processual clássica, orientada a objetos e até funcional: ramificação condicional, loops, variáveis, matrizes, tabelas de hash, classes, tratamento de erros, bem como funções, cmdlets e pipelines . O artigo anterior foi dedicado aos conceitos básicos de trabalho em um ambiente e agora oferecemos aos nossos leitores um pequeno guia para programadores.

Índice:


Comentários
Variáveis ​​e seus tipos
Variáveis ​​do sistema
Escopos Variáveis ​​de
ambiente (
aritmética )
Operadores aritméticos e de comparação Operadores de atribuição
Operadores lógicos
Transição condicional
Loops
Matrizes
Tabelas de hash
Funções
Tratamento de erros Você

pode escrever código em qualquer editor de texto ou no ambiente de desenvolvimento integrado - a maneira mais fácil de executar Windows PowerShell ISE incluído nos sistemas operacionais Microsoft Server. Isso é necessário apenas para scripts bastante complexos: conjuntos curtos de comandos são mais fáceis de executar interativamente.

Comentários


O uso de comentários é considerado parte de um bom estilo de programação, juntamente com recuo e espaços adequados:

#       —     .

<# 

             . 
            .

#>

Variáveis ​​e seus tipos


Variáveis ​​no PowerShell são nomeadas objetos. Seus nomes podem incluir um sublinhado, além de letras e números. O símbolo $ é sempre usado antes do nome e, para declarar uma variável, basta indicar ao intérprete um nome válido:

imagem

Para inicializar a variável (atribuir um valor a ela), o operador de atribuição (symbol =) é usado:

$test = 100

Você pode declarar uma variável indicando seu tipo entre colchetes (operador de conversão de tipo) antes do nome ou valor:

[int]$test = 100

$test = [int]100

É importante entender que as variáveis ​​no PowerShell são objetos completos (classes) com propriedades e métodos cujos tipos são baseados nos disponíveis no .NET Core. Listamos os principais:
Tipo (classe .NET)
Descrição
Exemplo de código
[string]
System.String
Unicode 
$test = «»
$test = ''
[char]
System.Char
Unicode (16 )
[char]$test = 'c'
[bool]
System.Boolean
( True False)
[bool]$test = $true
[int]
System.Int32
(32 )
[int]$test = 123456789
[long]
System.Int64
(64 )
[long]$test = 12345678910
[single]
System.Single
32
[single]$test = 12345.6789
[double]
System.Double
64 (8 )
[double]$test = 123456789.101112
[decimal]
System.Decimal
Número de ponto flutuante de 128 bits (não se esqueça de incluir d no final)
[decimal] $ test = 12345.6789d
[DateTime]
System.DateTime
data e hora 
$ test = Get-Date
[matriz]
System.Object []
uma matriz cujo índice de elemento começa em 0
$ test_array = 1, 2, "teste", 3, 4
[hashtable]
System.Collections.Hashtable
tabelas de hash - matrizes associativas com chaves nomeadas, baseadas no princípio: @ {key = "value"}
$ test_hashtable = @ {one = "one"; dois = "dois"; três = "três"}

O PowerShell oferece suporte à conversão implícita de tipo; além disso, o tipo da variável pode mudar rapidamente (por exemplo, usando o operador de atribuição) se não for especificado à força - nesse caso, o intérprete emitirá um erro. Você pode determinar o tipo de uma variável do exemplo anterior chamando o método GetType ():

$test.GetType().FullName

imagem

Há vários cmdlets para gerenciar variáveis. Sua lista em um formato conveniente é exibida usando o comando:

Get-Command -Noun Variable | ft -Property Name, Definition -AutoSize -Wrap

imagem

Para exibir as variáveis ​​declaradas e seus valores, você pode usar o cmdlet especial:

Get-Variable | more

Esse método parece excessivamente pesado; é muito mais conveniente trabalhar com variáveis ​​por meio de operadores ou acessando suas propriedades e métodos diretamente. No entanto, os cmdlets têm o direito de existir porque permitem especificar alguns parâmetros adicionais. É importante entender que as variáveis ​​de usuário são definidas apenas dentro da sessão atual. Depois de fechar o console ou concluir o script, eles são excluídos.

Variáveis ​​do sistema


Além das declaradas pelo usuário, existem variáveis ​​internas (do sistema) que não são excluídas após o término da sessão atual. Eles são divididos em dois tipos, enquanto os dados de status do PowerShell são armazenados em variáveis ​​automáticas, que não podem receber valores arbitrários por conta própria. Isso inclui, por exemplo, $ PWD:

$PWD.Path

imagem

Para armazenar configurações do usuário, você precisa de variáveis ​​de preferência cujos valores possam ser alterados. Por exemplo, com a ajuda de $ ErrorActionPreference, a resposta do interpretador de comandos para a ocorrência de erros não críticos é definida.

Além de operadores e cmdlets, o pseudo-acumulador Variable: existe para acessar variáveis ​​declaradas. Você pode trabalhar com ele por analogia com outras unidades, e as variáveis ​​nesse caso se parecem com objetos do sistema de arquivos:

Get-ChildItem Variable: | more

ou

ls Variable: | more

imagem

Escopos


Para variáveis ​​no PowerShell, existe a noção de escopo. A ação da área global (Global) se estende a toda a sessão atual - inclui, por exemplo, variáveis ​​do sistema. Variáveis ​​locais estão disponíveis apenas na área em que foram definidas: digamos, dentro da função. Há também o conceito de escopo de script, mas para comandos de script, é essencialmente local. Por padrão, ao declarar variáveis, eles recebem um escopo local e, para mudar isso, é necessária uma construção especial do formulário: $ Global: variable = value.

Por exemplo, assim:

$Global:test = 100

variáveis ​​ambientais


Outra pseudo-unidade Env está disponível no PowerShell, que pode ser usada para acessar variáveis ​​de ambiente. Quando o shell é iniciado, eles são copiados do processo pai (ou seja, do programa que iniciou a sessão atual) e geralmente seus valores iniciais coincidem com os valores no painel de controle. Para exibir variáveis ​​de ambiente, use o cmdlet Get-ChildItem ou seus aliases (liases): ls e dir.

dir Env:

imagem

Essas variáveis ​​são sequências de bytes (ou caracteres, se você preferir), cuja interpretação depende apenas do programa que as utiliza. * - Os cmdlets variáveis ​​não funcionam com variáveis ​​de ambiente. Para acessá-los, você precisará usar o prefixo do disco:

$env:TEST = "Hello, World!"

imagem

Operadores aritméticos e de comparação


O PowerShell possui os seguintes operadores aritméticos: + (adição), - (subtração), * (multiplicação), / (divisão) e% (módulo ou restante da divisão). O resultado de uma expressão aritmética é calculado da esquerda para a direita, de acordo com a ordem de operações geralmente aceita, e parênteses são usados ​​para agrupar partes da expressão. Os espaços entre os operadores são ignorados, eles são usados ​​apenas para facilitar a percepção. O operador + também concatena e o operador * repete as linhas. Se você tentar adicionar um número a uma string, ele será convertido em uma string. Além disso, o PowerShell tem muitos operadores de comparação que verificam a correspondência entre dois valores e retornam booleano True ou False:
Operador
Descrição
Exemplo de código
-eq
Igual (analógico = ou == em outros idiomas)
$ test = 100
$ test -eq 123 
-ne
Diferente (analógico <> ou! =)
$ teste = 100
$ teste -ne 123   
-gt
Maior que / Mais (analógico>)
$ teste = 100
$ teste -gt 123
-ge
Maior que ou igual / Maior que ou igual (analógico> =)
$ teste = 100
$ teste -ge 123
-lt
Menor que (analógico <)
$ teste = 100
$ teste -lt 123  
-le
Menor ou igual / Menor ou igual (analógico <=)
$ teste = 100
$ teste -le 123

Existem outros operadores semelhantes que permitem, por exemplo, comparar seqüências de caracteres com um caractere curinga ou usar expressões regulares para corresponder aos padrões. Nós os consideraremos em detalhes nos seguintes artigos. Os símbolos <,> e = não são usados ​​para comparação, pois são usados ​​para outros fins.

Operadores de atribuição


Além do operador mais comum =, existem outros operadores de atribuição: + =, - =, * =, / = e% =. Eles alteram o valor antes da atribuição. Os operadores unários ++ e - se comportam de maneira semelhante, que aumentam ou diminuem o valor de uma variável - eles também se relacionam com operadores de atribuição.

Operadores lógicos


A comparação não é suficiente para descrever condições difíceis. Você pode anotar quaisquer expressões lógicas usando os operadores: -and, -or, -xor, -not e! .. Eles funcionam como em outras linguagens de programação e você pode usar parênteses para especificar a ordem de cálculo:

("" -eq "") -and (100 -eq 100)

-not (123 -gt 321) 

!(123 -gt 321)

Salto condicional


Os operadores de ramificação no PowerShell são padrão: IF (IF ... ELSE, IF ... ELSEIF ... ELSE) e SWITCH. Considere seu uso com exemplos:

[int]$test = 100
if ($test -eq 100) {
      Write-Host "test = 100"
}



[int]$test = 50
if ($test -eq 100) {
       Write-Host "test = 100"
}
else {
      Write-Host "test <> 100"
}



[int]$test = 10
if ($test -eq 100) {
      Write-Host "test = 100"
}
elseif ($test -gt 100) {
      Write-Host "test > 100"
}
else {
       Write-Host "test < 100"
}



[int]$test = 5
switch ($test) {
     0 {Write-Host "test = 0"}
     1 {Write-Host "test = 1"}
     2 {Write-Host "test = 2"}
     3 {Write-Host "test = 3"}
     4 {Write-Host "test = 4"}
     5 {Write-Host "test = 5"}
     default {Write-Host "test > 5    "}
}

Ciclos


Existem vários tipos de loops no PowerShell: WHILE, WHILE, WHITE, UNTIL, FOR e FOREACH.

O loop de pré-condição funciona se / enquanto estiver em execução:

[int]$test = 0
while ($test -lt 10) {
      Write-Host $test
      $test = $test + 1
}

Os loops com uma pós-condição funcionarão pelo menos uma vez, porque a condição é verificada após a iteração. Nesse caso, DO WHILE funciona enquanto a condição é verdadeira e ATÉ - enquanto é falso:

[int]$test = 0
do {
      Write-Host $test
      $test = $test + 1 
}
while ($test -lt 10)



[int]$test = 0
do {
      Write-Host $test
      $test = $test + 1 
}
until ($test -gt 9)


O número de iterações do loop FOR é conhecido antecipadamente:

for ([int]$test = 0; $test -lt 10; $test++) {
       Write-Host $test
}


Em um loop FOREACH itera sobre elementos de uma matriz ou coleção (tabela de hash):

$test_collection = "item1", "item2", "item3"
foreach ($item in $test_collection)
{
        Write-Host $item
}

Matrizes


As variáveis ​​do PowerShell armazenam não apenas objetos únicos (número, sequência, etc.), mas também objetos plurais. A variedade mais simples dessas variáveis ​​são matrizes. Uma matriz pode consistir em vários elementos, um elemento ou estar vazio, ou seja, não contém elementos. Para declarar, use o operador @ (), necessário no próximo artigo - é muito importante adicionar outras matrizes à matriz (criando matrizes multidimensionais), passando matrizes para funções como argumentos e tarefas semelhantes:

$test_array = @() #  

Quando a matriz é inicializada, seus valores são listados com uma vírgula (operador especial):

$test_array = @(1, 2, 3, 4) #      

Na maioria dos casos, o operador @ () pode ser omitido:

$test_array = 1, 2, 3, 4

Nesse caso, uma matriz de um elemento é inicializada da seguinte maneira

$test_array = , 1

Para acessar elementos da matriz, são utilizados um índice inteiro começando de zero e um operador de índice (colchetes):

$test_array[0] = 1

Você pode especificar vários índices, separados por vírgulas, incluindo duplicado:

$test_array = "", "", "", ""
$test_array[0,1,2,3]
$test_array[1,1,3,3,0]

imagem

O operador ..(dois pontos - o operador de intervalo) retorna uma matriz de números inteiros em um segmento definido pelos limites superior e inferior. Por exemplo, a expressão 1..4 exibe uma matriz de quatro elementos @ (1, 2, 3, 4) e a expressão 8..5 exibe uma matriz de @ (8, 7, 6, 5).

imagem

Usando o operador range, você pode inicializar uma matriz ($ test_array = 1..4) ou obter uma fatia, ou seja, uma sequência de elementos em uma matriz com índices de outra. Nesse caso, um número negativo -1 indica o último elemento da matriz, -2 - o penúltimo, etc.

$test_array = "", "", "", ""
$test_array[0..2]
$test_array[2..0]
$test_array[-1..0]
$test_array[-2..1]

Observe que os valores da matriz inteira podem ser maiores que o valor máximo do índice da matriz de dados. Nesse caso, todos os valores são retornados para o último:

$test_array[0..100]

Se você tentar acessar um único elemento de matriz inexistente, será retornado $ null.

imagem

No PowerShell, as matrizes podem conter elementos de tipos diferentes ou ser fortemente tipadas:

$test_array = 1, 2, "", 3, 4
for ([int]$i = 0; $i -lt $test_array.count; $i++)
{
          Write-Host $test_array[$i]
}

Onde a propriedade $ test_array.count é o número de elementos na matriz.

Um exemplo de criação de uma matriz fortemente tipada:

[int[]]$test_array = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Tabelas de hash


Outro tipo básico de variável no PowerShell são as tabelas de hash, também chamadas de matrizes associativas. Hashtable são semelhantes ao objeto JSON e são construídos com base no valor-chave. Diferentemente de matrizes comuns, o acesso a seus elementos é realizado usando chaves nomeadas, que são propriedades de objetos (você também pode usar o operador de índice - colchetes).

Uma tabela de hash vazia é declarada usando o símbolo de serviço @ e colchetes do operador:

$test_hashtable = @{}

Ao declarar, você pode criar imediatamente chaves e atribuir valores a elas:

$test_hashtable = @{one=""; two=""; three=""; "some key"="some value"}

Para adicionar um item à tabela de hash, você deve atribuir uma chave que ainda não existe ou usar o método Add (). Se a atribuição for feita com uma chave existente, seu valor será alterado. Para remover um item de uma tabela de hash, use o método Remove ().

$test_hashtable."some key"
$test_hashtable["some key"]
$test_hashtable.Add("four", "")
$test_hashtable.five = ""
$test_hashtable['five'] = " "
$test_hashtable.Remove("one")

imagem

Variáveis ​​desse tipo podem ser passadas como argumentos para funções e cmdlets - no próximo artigo, aprenderemos como fazer isso e também consideraremos outro tipo semelhante - PSCustomObject.

Funções


O PowerShell possui todos os elementos necessários para a programação procedural, incluindo funções. A palavra da função Function é usada para descrevê-los, após o qual é necessário indicar o nome da função e o corpo entre colchetes do operador. Se necessário, passe argumentos para a função, você pode especificá-los imediatamente após o nome entre parênteses.

function - (1, ..., N) 
{ 
        - 
} 

Uma função sempre retorna um resultado - essa é uma matriz dos resultados de todas as suas instruções, se houver mais de uma. Se houver uma instrução, um único valor do tipo correspondente será retornado. A construção return $ value adiciona um elemento com o valor $ value à matriz de resultados e anula a lista de instruções, e uma função vazia retorna $ null.

Por exemplo, crie uma função para quadrilhar um número:

function sqr ($number)
{
      return $number * $number
}

Observe que no corpo da função você pode usar qualquer variável declarada antes da chamada, e as funções de chamada no PowerShell podem parecer incomuns: argumentos (se houver) não estão entre parênteses e são separados por espaços.

sqr 2

ou então:

sqr -number 2

Devido à maneira como os argumentos são passados, a função em si às vezes deve estar entre colchetes:

function test_func ($n) {}
test_func -eq $null     #   
(test_func) -eq $null   #   — $true

imagem

Ao descrever uma função, você pode atribuir valores padrão aos argumentos:

function func ($arg = value) {
         # 
}

Há outra sintaxe para descrever argumentos de função; além disso, os parâmetros podem ser lidos no pipeline - tudo isso será útil no próximo artigo quando considerarmos os módulos exportados e criarmos seus próprios cmdlets.

Erro no processamento


O PowerShell possui um mecanismo Try ... Catch ... Finalmente para lidar com exceções. O bloco Try contém um código no qual um erro pode ocorrer e o bloco Catch contém seu manipulador. Se não houver erro, ele não será executado. O bloco Finalmente é executado após o bloco Try, independentemente da ocorrência de um erro, e pode haver vários blocos Catch para exceções de vários tipos. A exceção em si é gravada na variável de não declaração padrão ($ _) e pode ser facilmente recuperada. No exemplo abaixo, implementamos proteção contra a inserção de um valor incorreto:

try {

        [int]$test = Read-Host " "
        100 / $test

} catch {

         Write-Warning " "
         Write-Host $_

}

imagem

É aí que estão os conceitos básicos de programação do PowerShell. Nos artigos a seguir, estudaremos mais detalhadamente o trabalho com variáveis ​​de vários tipos, coleções, expressões regulares, criação de funções, módulos e cmdlets personalizados, além de programação orientada a objetos.

Parte 1: os principais recursos do Windows PowerShell
Parte 3: passando parâmetros para scripts e funções, criando cmdlets
Parte 4: Trabalhando com objetos, classes personalizadas



All Articles