Nesta aula, vamos explorar como o PowerShell pode ser usado para obter informações detalhadas sobre o sistema, desde o hardware até a rede. Essas informações são fundamentais para administradores de sistemas, scripts de automação e auditorias de infraestrutura. Você aprenderá a consultar o sistema operacional, hardware, discos, memória e configurações de rede, além de como combinar essas informações em um inventário completo.

O PowerShell oferece acesso direto ao WMI (Windows Management Instrumentation) e ao CIM (Common Information Model), que fornecem uma riqueza de dados sobre o sistema. Também usaremos cmdlets nativos que simplificam a extração dessas informações. Ao final, você terá um repertório de comandos para diagnosticar e documentar qualquer máquina Windows.

Hardware e SO

Para obter informações sobre o hardware e o sistema operacional, utilizamos principalmente o cmdlet Get-CimInstance (ou Get-WmiObject em versões mais antigas). Esses cmdlets consultam classes WMI/CIM que representam componentes do sistema. A classe Win32_ComputerSystem fornece dados sobre o fabricante, modelo, processador e memória total. A classe Win32_OperatingSystem traz versão, build, arquitetura e diretório do sistema.

Exemplo prático: vamos obter o fabricante, modelo e número de série da máquina, além da versão do sistema operacional.

# Informações do hardware
Get-CimInstance -ClassName Win32_ComputerSystem |
    Select-Object Manufacturer, Model, SystemFamily, TotalPhysicalMemory

# Informações do sistema operacional
Get-CimInstance -ClassName Win32_OperatingSystem |
    Select-Object Caption, Version, BuildNumber, OSArchitecture, InstallDate

Você pode combinar essas informações em um único objeto para facilitar a leitura. Por exemplo, para exibir uma visão consolidada do sistema:

$computer = Get-CimInstance -ClassName Win32_ComputerSystem
$os = Get-CimInstance -ClassName Win32_OperatingSystem

[PSCustomObject]@{
    Computador = $computer.Name
    Fabricante = $computer.Manufacturer
    Modelo = $computer.Model
    SO = $os.Caption
    Versao = $os.Version
    Arquitetura = $os.OSArchitecture
    MemoriaFisica = [math]::Round($computer.TotalPhysicalMemory / 1GB, 2).ToString() + ' GB'
}

Essas informações são essenciais para identificar uma máquina em um inventário, verificar requisitos de software ou diagnosticar problemas de compatibilidade.

Disco e memória

O monitoramento de discos e memória é crucial para avaliar o desempenho e a capacidade do sistema. Para discos, usamos a classe Win32_LogicalDisk para discos lógicos (partições) e Win32_DiskDrive para discos físicos. Para memória, temos Win32_PhysicalMemory (módulos físicos) e Win32_OperatingSystem para memória total e livre.

Vamos listar as partições lógicas com espaço livre e total:

Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID, VolumeName, @{N='Tamanho(GB)';E={[math]::Round($_.Size/1GB,2)}},
        @{N='Livre(GB)';E={[math]::Round($_.FreeSpace/1GB,2)}},
        @{N='PercentualLivre';E={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}}

Para memória física, podemos obter a capacidade de cada módulo e a velocidade:

Get-CimInstance -ClassName Win32_PhysicalMemory |
    Select-Object BankLabel, DeviceLocator, Capacity, Speed, Manufacturer

Além disso, podemos usar o cmdlet Get-Volume (do módulo Storage) para obter informações mais detalhadas sobre volumes, como tipo de arquivo e health status. Exemplo:

Get-Volume | Where-Object DriveLetter | Select-Object DriveLetter, FileSystemLabel, FileSystem, HealthStatus, SizeRemaining, Size

Essas informações ajudam a identificar discos cheios, planejar expansões de memória e monitorar a saúde geral do armazenamento.

Rede

As informações de rede incluem endereços IP, máscaras, gateways, DNS e adaptadores físicos. O PowerShell oferece o cmdlet Get-NetIPConfiguration e Get-NetAdapter para essas tarefas. Também podemos usar Get-CimInstance com a classe Win32_NetworkAdapterConfiguration para obter dados mais detalhados.

Exemplo de obtenção de configuração de IP de todas as interfaces:

Get-NetIPConfiguration |
    Where-Object { $_.IPv4Address } |
    Select-Object InterfaceAlias, @{N='IPv4';E={$_.IPv4Address.IPAddress}},
        @{N='Gateway';E={$_.IPv4DefaultGateway.NextHop}},
        @{N='DNS';E={$_.DNSServer.ServerAddresses -join ', '}}

Para listar adaptadores de rede e seus status:

Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, MacAddress, LinkSpeed

Se você precisar de informações mais detalhadas, como DHCP habilitado ou endereços DNS, pode usar a classe WMI:

Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True" |
    Select-Object Description, @{N='IP';E={$_.IPAddress}}, @{N='Gateway';E={$_.DefaultIPGateway}},
        @{N='DNS';E={$_.DNSServerSearchOrder}} -First 5

Essas informações são essenciais para diagnosticar problemas de conectividade, configurar redes e documentar a topologia.

Coletando inventário

Inventariar sistemas é uma tarefa comum em ambientes corporativos. O PowerShell permite consolidar todas as informações acima em um relatório ou objeto estruturado. Podemos criar um script que coleta dados de vários computadores (remotamente) e os exporta para CSV ou JSON.

Exemplo de função que coleta um inventário básico de uma máquina local:

function Get-SystemInventory {
    $computer = Get-CimInstance -ClassName Win32_ComputerSystem
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3"
    $network = Get-NetIPConfiguration | Where-Object { $_.IPv4Address }

    [PSCustomObject]@{
        Computador = $computer.Name
        Fabricante = $computer.Manufacturer
        Modelo = $computer.Model
        SerialNumber = $computer.SerialNumber
        SO = $os.Caption
        Versao = $os.Version
        Arquitetura = $os.OSArchitecture
        MemoriaTotalGB = [math]::Round($computer.TotalPhysicalMemory / 1GB, 2)
        Discos = ($disks | ForEach-Object { "$($_.DeviceID) $([math]::Round($_.Size/1GB,2))GB" }) -join '; '
        IP = ($network | ForEach-Object { $_.IPv4Address.IPAddress }) -join ', '
        Gateway = ($network | ForEach-Object { $_.IPv4DefaultGateway.NextHop }) -join ', '
    }
}

Get-SystemInventory

Para inventariar vários computadores, você pode usar Invoke-Command ou Get-CimInstance com o parâmetro -ComputerName. Por exemplo:

$computadores = 'PC01', 'PC02', 'PC03'
$inventario = foreach ($pc in $computadores) {
    Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $pc |
        Select-Object @{N='Computador';E={$_.Name}}, Manufacturer, Model, TotalPhysicalMemory
}
$inventario | Export-Csv -Path 'inventario.csv' -NoTypeInformation

Essa abordagem pode ser estendida para incluir outros dados, como software instalado, serviços, etc. Lembre-se de que para acesso remoto, é necessário ter permissões adequadas e o WinRM habilitado.

Boas práticas e observações

Ao trabalhar com informações do sistema, considere as seguintes boas práticas: use Get-CimInstance em vez de Get-WmiObject (mais moderno e compatível com PowerShell Core); filtre o máximo possível no servidor para reduzir o tráfego de rede; e formate a saída para facilitar a leitura. Além disso, sempre teste seus scripts em um ambiente de desenvolvimento antes de executá-los em produção.

Exercícios

  1. Escreva um comando que exiba o nome do computador, fabricante e modelo usando Get-CimInstance.

    ✓ Resposta:
    Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Name, Manufacturer, Model
  2. Obtenha o espaço livre e total (em GB) de todas as unidades lógicas fixas (DriveType=3) e exiba o percentual de espaço livre.

    ✓ Resposta:
    Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" |
        Select-Object DeviceID, @{N='Tamanho(GB)';E={[math]::Round($_.Size/1GB,2)}},
            @{N='Livre(GB)';E={[math]::Round($_.FreeSpace/1GB,2)}},
            @{N='PercentualLivre';E={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}}
  3. Liste todos os adaptadores de rede com seu endereço IP, máscara e gateway.

    ✓ Resposta:
    Get-NetIPConfiguration | Where-Object { $_.IPv4Address } |
        Select-Object InterfaceAlias, @{N='IPv4';E={$_.IPv4Address.IPAddress}},
            @{N='Mascara';E={$_.IPv4Address.PrefixLength}},
            @{N='Gateway';E={$_.IPv4DefaultGateway.NextHop}}
  4. Crie um script que colete o nome do computador, SO, memória total e IP em um único objeto.

    ✓ Resposta:
    $cs = Get-CimInstance -ClassName Win32_ComputerSystem
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $net = Get-NetIPConfiguration | Where-Object { $_.IPv4Address } | Select-Object -First 1
    
    [PSCustomObject]@{
        Computador = $cs.Name
        SO = $os.Caption
        MemoriaTotalGB = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
        IP = $net.IPv4Address.IPAddress
    }
  5. Exporte um inventário simples (nome do computador, fabricante, modelo, SO, espaço livre em disco) para um arquivo CSV.

    ✓ Resposta:
    $cs = Get-CimInstance -ClassName Win32_ComputerSystem
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $disk = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | Select-Object -First 1
    
    $inventario = [PSCustomObject]@{
        Computador = $cs.Name
        Fabricante = $cs.Manufacturer
        Modelo = $cs.Model
        SO = $os.Caption
        EspacoLivreGB = [math]::Round($disk.FreeSpace/1GB,2)
    }
    $inventario | Export-Csv -Path 'inventario.csv' -NoTypeInformation

Referências