Introdução
O PowerShell é basicamente uma “linguagem” de scripting criada pela Microsoft para administradores de sistemas, a sua syntax é um misto de Perl, C++ e C#. O PowerShell é distribuído livremente e tem como grande objectivo a substituição de VBscript e batch scripting. Windows PowerShell é um “ambiente” para cmdlets, funções, filtros, executáveis e aliases.
O PowerShell é baseado na Framework .NET. Assim, tem como principal vantagem a integração quase directa de componentes .NET.
Enquadramento
Este pequeno artigo tem como principal objectivo ilustrar as potencialidades desta “linguagem”. Pessoalmente, já desde 2007 que tento influenciar todos aqueles administradores de sistemas ou helpdesks para usarem esta ferramenta, pois acho que é extremamente poderosa e de enorme valia.
Historicamente, o cmd da Microsoft sempre foi bastante limitado, isto deve-se ao facto da Microsoft definir como “target” do seu sistema operativo, o utilizador comum que acaba por não ser muito dotado tecnicamente. Grande parte dos esforços no desenvolvimento do Windows foram apontados para o interface e a sua usabilidade, em detrimento da criação de um ambiente mais orientado para profissionais. Em suma, o PowerShell veio colmatar a falha que existia na gestão do sistema operativo Windows por linha de comandos.
Instalação
Para instalar o PowerShell, necessitam da Framework 2.0 da Microsoft, e de fazer download do respectivo pacote PowerShell: http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx.
Após a instalação do PowerShell, devem aceder à consola do Windows PowerShell e executar o seguinte comando.
Set-Executionpolicy Unrestricted
Com este comando “vão” retirar todas as restrições de execução de scripts PowerShell na vossa máquina. O PowerShell possui um mecanismo de segurança que assenta em assinaturas de scripts e permissões de execução. Fica aqui um apanhado dos possíveis perfis:
- Restricted
- Não podem ser executadas scripts. O Windows PowerShell só pode ser usado através do PowerShell command mode.
- AllSigned
- Apenas scripts assinadas podem ser executadas
- RemoteSigned
- Downloaded Scripts têm que ser assinados para poderem ser executados.
- Unrestricted
- Sem qualquer restrição de execução.
Let’s Rock
Breve introdução
Façamos uma breve introdução à sintaxe da linguagem…
Variáveis
Têm que começar pelo símbolo $
.
$a=32
Pode ser escrito da seguinte forma para forçar o tipo de dados.
[int]$a=32
Arrays, hash’s
# Isto é um comentário $a= 1,2,3,4,5 # Array $a= @(1,2,3,4,5) # Array $loc = @{"Braga" = "Portugal"; "Madrid" = "Espanha"} #Hash
Comandos Essenciais
Get-Help Get-Service Get-Command
Criação de Instâncias
$d = New-Object -Type System.DateTime 2006,12,25 $d.get_DayOfWeek()
Output para a consola
Write-Host $a –foregroundcolor “green” $a
Capturar input
$a = Read-Host “Nome ?” Write-Host "Olá " $a
Quebra de linha
Get-Process | ` Select-Object ` name, ID Comments
Ciclos, Loops
$a=1 Do {$a; $a++} While ($a –lt 10) $a=1 Do {$a; $a++} Until ($a –gt 10) For ($a=1; $a –le 10; $a++) {$a} Foreach ($i in Get-Childitem c:windows) {$i.name; $i.creationtime}
Controle If-Then-Else
$a = "white" if ($a -eq "red") {"Vermelho"} elseif ($a -eq "white") {"Branco"} else {"nao sei"} $a = "red" switch ($a) { "red" {"vermelho"} "white"{"branco"} default{"nao sei"} }
Programming, Programming …
Ok, vamos lá ver qual a “velocidade que isto dá” ;-).
Nota: O conceito de pipe |
está muito enraizado no uso do PowerShell!
- Imprimir todos os processo da minha máquina.
get-process | ForEach-Object { write-host $_.ProcessName $_.CPU} # Ordenando-os por tempo de CPU get-process |Sort-Object CPU #Guardando o resultado dos primeiros 10 numa variavel $P = get-process | Sort-Object CPU –descending | select-object –first 10 #fazendo DUMP da variavel para um ficheiro $P > c:A4.txt
Façamos uma breve explicação do que foi feito no script anterior.
O cmdlet get-process
retorna todos uma lista de processos em execução. No exemplo anterior, bastou redireccionar a saída (“output”) do comando para um loop foreach para ser possível “trabalhar” o resultado.
A variável interna $_
armazena a saída do |
.
Como é que se sabe quais as propriedades que o objecto $_
possui? simples, usa-se o cmdlet get-member
. Este cmdlet permite retornar todas as propriedades e métodos de um dado objecto.
Experimentem o seguinte:
get-process | select-object -first 1 | get-member
Se desejarem apenas saber quais as propriedades, basta filtrarem pelo -MemberType
.
get-process | select-object -first 1 | get-member -MemberType property
Eis o “dump” do último comando …
Name | MemberType |
---|---|
BasePriority | Property |
Container | Property |
Id | Property |
MachineName | Property |
MainModule | Property |
………. | Property |
………. | Property |
Threads | Property |
TotalProcessorTime | Property |
UserProcessorTime | Property |
VirtualMemorySize | Property |
VirtualMemorySize64 | Property |
WorkingSet | Property |
WorkingSet64 | Property |
- Ver o tamanho do meu event log
"System"
get-eventlog -list | where-object {$_.logdisplayname -eq "System"}
- Listar os últimos 3 eventos
"System"
get-eventlog system -newest 3
- Listar os últimos 3 eventos
"System"
, formatando-os
get-eventlog system -newest 3 | format-list
- Listar todos os ficheiros excepto os temporários, imprimindo o nome e o tamanho
Get-childitem c:* –exclude *.tmp | select-object name, length
- Listar todos os serviços e exportá-los para HTML
get-service | convertto-html #exportá-los para um ficheiro get-service | convertto-html > .a10.html
- Algo mais elaborado… Listar todos os meus serviços, exportá-los para HTML, separando por cores os que estão a correr dos que estão parados.
get-service | ConvertTo-Html -Property Name,Status | ` foreach { if($_ -like "*<td>Running</td>*") {$_ -replace "<td>", "<tr bgcolor=green>"} ` else {$_ -replace "<tr>", "<tr bgcolor=red>"}} >.get-service.html
Com estes pequenos exemplos verificamos as enormes potencialidades desta “linguagem”.
- vamos lá carregar no acelerador :-P
# Todos os ficheiros, recursivamente, cujo tamanho seja maior que 20MB get-childitem -recurse c:temp | where-object {$_.length –gt 2000000} # Todos os ficheiros *.Doc que não sejam readonly get-childitem *.doc | foreach-object {$_.Isreadonly = 0} # Ler um ficheiro $a = Get-Content "c:servers.txt" foreach ($i in $a) {$i} # Criar um ficheiro excel (2003) com os dados de um serviço. $a = new-object -comobject excel.application $a.Visible = $True $b = $a.Workbooks.Add() $c = $b.Worksheets.Item(1) $c.Cells.Item(1,1) = "Nome Serviço" $c.Cells.Item(1,2) = "Estado" $i = 2 get-service | foreach-object{ $c.cells.item($i,1) = $_.name; $c.cells.item($i,2) = $_.status; $i=$i+1} $b.SaveAs("c:Test.xls") $a.Quit() # Who Am I [System.Security.Principal.WindowsIdentity]::GetCurrent().Name