04 / Automação e sistemas Windows

Comandos úteis.
PowerShell.

Uma biblioteca de scripts para consultar, adaptar e usar no dia a dia. Explore o código, copie um comando ou baixe o arquivo completo.

03Scripts disponíveis
Windows / PowerShell

3 arquivos encontrados

RedesPowerShell / .ps1

Verificar conectividade de IPs

Teste uma lista de endereços com duas tentativas de ping por IP. UP indica resposta; DOWN indica ausência de resposta ao ping, sem confirmar que o equipamento esteja desligado. Edite a lista $ips para consultar seus equipamentos.

verificar-conectividade.ps1Somente consulta
$ips = "172.215.3.4","172.215.3.10"

$ips | ForEach-Object {
    if (Test-Connection $_ -Count 2 -Quiet) {
        "{0,-15} [UP]" -f $_
    }
    else {
        "{0,-15} [DOWN]" -f $_
    }
}

Exemplo de execução

.\verificar-conectividade.ps1
RedesPowerShell / .ps1

Diagnóstico de rede

Mapeie a rede CFTV 172.215.1.0/24, consulte ping, MAC e hostname e exporte um relatório CSV para a Área de Trabalho. Ausência de resposta não garante que o IP esteja livre; a consulta de MAC depende da rede local.

diagnostico-rede.ps1Somente consulta
# Ajuste o prefixo abaixo para a rede que deseja consultar.
$rede = "172.215.1"
$resultados = @()

Write-Host "Iniciando varredura da rede $rede.0/24..." -ForegroundColor Cyan

1..254 | ForEach-Object {
    $ip = "$rede.$_"

    Write-Progress -Activity "Mapeando rede CFTV" -Status "Verificando $ip" -PercentComplete (($_ / 254) * 100)

    $ping = Test-Connection -ComputerName $ip -Count 1 -Quiet -ErrorAction SilentlyContinue
    Start-Sleep -Milliseconds 30

    $vizinho = Get-NetNeighbor -IPAddress $ip -ErrorAction SilentlyContinue |
        Where-Object {
            $_.LinkLayerAddress -and
            $_.LinkLayerAddress -ne "00-00-00-00-00-00"
        } |
        Select-Object -First 1

    $mac = if ($vizinho) { $vizinho.LinkLayerAddress } else { "" }

    try {
        $hostname = [System.Net.Dns]::GetHostEntry($ip).HostName
    }
    catch {
        $hostname = ""
    }

    # Ausência de resposta não confirma que o endereço esteja disponível.
    $status = if ($ping -or $mac) { "OCUPADO" } else { "SEM RESPOSTA" }

    $resultados += [PSCustomObject]@{
        IP       = $ip
        MAC      = $mac
        Ping     = $ping
        Hostname = $hostname
        Status   = $status
    }
}

Write-Progress -Activity "Mapeando rede CFTV" -Completed

$caminho = Join-Path ([Environment]::GetFolderPath("Desktop")) "Mapeamento_CFTV.csv"

$resultados | Export-Csv -Path $caminho -NoTypeInformation -Encoding UTF8 -Delimiter ";"

Write-Host ""
Write-Host "Varredura concluída." -ForegroundColor Green
Write-Host "Arquivo salvo em:"
Write-Host $caminho -ForegroundColor Yellow

$ocupados = @($resultados | Where-Object Status -eq "OCUPADO").Count
$semResposta = @($resultados | Where-Object Status -eq "SEM RESPOSTA").Count

Write-Host ""
Write-Host "===== RESUMO =====" -ForegroundColor Cyan
Write-Host "IPs ocupados: $ocupados"
Write-Host "IPs sem resposta: $semResposta"

Exemplo de execução

.\diagnostico-rede.ps1
SistemaPowerShell / .ps1

Consultar serviços do Windows

Monitor de desempenho Windows v2.0: identifica o hardware e permite escolher um processo ou serviço para acompanhar CPU, RAM e GPU. Coleta a cada 15 segundos e salva médias e picos em CSV a cada 10 minutos em C:\Temp\Monitoramento. Interrompa com Ctrl + C; o período em andamento pode não ser salvo.

consultar-servicos.ps1Gera relatórios CSV
# =====================================================================
# MONITOR DE DESEMPENHO - WINDOWS
# Versao 2.0
#
# Recursos:
# - Detecta hardware automaticamente
# - CPU / RAM / GPU / discos
# - Permite escolher Processo ou Servico Windows
# - Coleta a cada 15 segundos
# - Salva resumo a cada 10 minutos
# - Media + pico
# - Nao grava no disco a cada amostra
# =====================================================================


# =====================================================================
# CONFIGURACAO
# =====================================================================

$IntervaloColeta = 15
$IntervaloSalvamento = 600

$Pasta = "C:\Temp\Monitoramento"

if (!(Test-Path $Pasta)) {

    New-Item `
        -Path $Pasta `
        -ItemType Directory `
        -Force |
        Out-Null
}


# =====================================================================
# FUNCAO - TIPO DA MEMORIA RAM
# =====================================================================

function Get-RamTypeName {

    param(
        [int]$Type
    )

    switch ($Type) {

        20 { return "DDR" }
        21 { return "DDR2" }
        22 { return "DDR2 FB-DIMM" }
        24 { return "DDR3" }
        26 { return "DDR4" }
        27 { return "LPDDR" }
        28 { return "LPDDR2" }
        29 { return "LPDDR3" }
        30 { return "LPDDR4" }
        34 { return "DDR5" }
        35 { return "LPDDR5" }

        default {

            if ($Type -eq 0) {
                return "Nao identificado"
            }

            return "Tipo $Type"
        }
    }
}


# =====================================================================
# FUNCAO - CPU DA MAQUINA
# POSSUI FALLBACK PARA MAQUINAS ONDE O PRIMEIRO METODO NAO FUNCIONA
# =====================================================================

function Get-SystemCPU {

    try {

        $CPUInfo = Get-CimInstance `
            Win32_PerfFormattedData_PerfOS_Processor `
            -Filter "Name='_Total'" `
            -ErrorAction Stop

        if (
            $null -ne $CPUInfo -and
            $null -ne $CPUInfo.PercentProcessorTime
        ) {

            return [double]$CPUInfo.PercentProcessorTime
        }
    }
    catch {
    }


    # -----------------------------------------------------------------
    # METODO ALTERNATIVO
    # -----------------------------------------------------------------

    try {

        $CPUAlt = Get-CimInstance `
            Win32_Processor `
            -ErrorAction Stop |
            Measure-Object `
                -Property LoadPercentage `
                -Average

        if ($null -ne $CPUAlt.Average) {

            return [double]$CPUAlt.Average
        }
    }
    catch {
    }


    return 0
}


# =====================================================================
# FUNCAO - RAM DA MAQUINA
# =====================================================================

function Get-SystemRAM {

    try {

        $OS = Get-CimInstance `
            Win32_OperatingSystem `
            -ErrorAction Stop

        $TotalKB = [double]$OS.TotalVisibleMemorySize

        $LivreKB = [double]$OS.FreePhysicalMemory

        $UsadaKB = (
            $TotalKB -
            $LivreKB
        )

        $Percent = (
            $UsadaKB /
            $TotalKB
        ) * 100


        return [PSCustomObject]@{

            Percent = $Percent

            UsedGB = (
                $UsadaKB /
                1MB
            )

            TotalGB = (
                $TotalKB /
                1MB
            )
        }
    }
    catch {

        return [PSCustomObject]@{

            Percent = 0

            UsedGB = 0

            TotalGB = 0
        }
    }
}


# =====================================================================
# FUNCAO - CONTADORES DA GPU
# =====================================================================

function Get-GPUSamples {

    try {

        return @(
            (
                Get-Counter `
                    '\GPU Engine(*)\Utilization Percentage' `
                    -ErrorAction Stop
            ).CounterSamples
        )
    }
    catch {

        return @()
    }
}


# =====================================================================
# FUNCAO - RESUMO MEDIA / MAXIMO
# =====================================================================

function Get-Summary {

    param(
        $Values
    )

    if (
        $null -eq $Values -or
        $Values.Count -eq 0
    ) {

        return [PSCustomObject]@{

            Average = $null

            Maximum = $null
        }
    }


    $Resumo = (
        $Values |
        Measure-Object `
            -Average `
            -Maximum
    )


    return [PSCustomObject]@{

        Average = $Resumo.Average

        Maximum = $Resumo.Maximum
    }
}


# =====================================================================
# IDENTIFICACAO AUTOMATICA DO HARDWARE
# =====================================================================

Clear-Host

Write-Host "================================================================="
Write-Host "             MONITOR DE DESEMPENHO - WINDOWS"
Write-Host "================================================================="
Write-Host ""
Write-Host "Identificando hardware da maquina..."
Write-Host ""


# ---------------------------------------------------------------------
# SISTEMA
# ---------------------------------------------------------------------

$ComputerSystem = Get-CimInstance Win32_ComputerSystem

$OSInfo = Get-CimInstance Win32_OperatingSystem


$ComputerName = $env:COMPUTERNAME

$FabricantePC = $ComputerSystem.Manufacturer

$ModeloPC = $ComputerSystem.Model

$WindowsName = $OSInfo.Caption

$WindowsVersion = $OSInfo.Version

$WindowsBuild = $OSInfo.BuildNumber


# ---------------------------------------------------------------------
# CPU
# ---------------------------------------------------------------------

$CPUList = @(
    Get-CimInstance Win32_Processor
)

$CPUModel = (
    $CPUList |
    ForEach-Object {
        $_.Name.Trim()
    } |
    Select-Object -Unique
) -join " + "


$CPUCores = (
    $CPUList |
    Measure-Object `
        -Property NumberOfCores `
        -Sum
).Sum


$CPUThreads = (
    $CPUList |
    Measure-Object `
        -Property NumberOfLogicalProcessors `
        -Sum
).Sum


if (
    $null -eq $CPUThreads -or
    $CPUThreads -le 0
) {

    $CPUThreads = 1
}


# ---------------------------------------------------------------------
# RAM
# ---------------------------------------------------------------------

$RAMTotalGB = [math]::Round(
    $ComputerSystem.TotalPhysicalMemory /
    1GB,
    2
)


$RAMModules = @(
    Get-CimInstance Win32_PhysicalMemory
)


$RAMTypes = @()

foreach ($Modulo in $RAMModules) {

    $RAMTypes += (
        Get-RamTypeName `
            -Type $Modulo.SMBIOSMemoryType
    )
}


$RAMType = (
    $RAMTypes |
    Select-Object -Unique
) -join " / "


$RAMSpeed = (
    $RAMModules |
    ForEach-Object {

        if ($_.ConfiguredClockSpeed) {

            "$($_.ConfiguredClockSpeed) MHz"
        }
        elseif ($_.Speed) {

            "$($_.Speed) MHz"
        }

    } |
    Select-Object -Unique
) -join " / "


$RAMModuleDescription = (
    $RAMModules |
    ForEach-Object {

        $GB = [math]::Round(
            $_.Capacity /
            1GB,
            0
        )

        "$GB GB"
    }
) -join " + "


# ---------------------------------------------------------------------
# GPU
# ---------------------------------------------------------------------

$GPUList = @(
    Get-CimInstance Win32_VideoController |
    Where-Object {

        $_.Name -notmatch "Microsoft Basic"
    }
)


$GPUModel = (
    $GPUList |
    ForEach-Object {
        $_.Name
    } |
    Select-Object -Unique
) -join " + "


$GPUDriver = (
    $GPUList |
    ForEach-Object {
        $_.DriverVersion
    } |
    Select-Object -Unique
) -join " / "


$GPUVRAM = @()


foreach ($GPU in $GPUList) {

    if ($GPU.AdapterRAM) {

        $GB = [math]::Round(
            $GPU.AdapterRAM /
            1GB,
            2
        )

        $GPUVRAM += "$GB GB"
    }
}


$GPUVRAMText = (
    $GPUVRAM |
    Select-Object -Unique
) -join " / "


# ---------------------------------------------------------------------
# NVIDIA - VRAM MAIS PRECISA
# ---------------------------------------------------------------------

$NvidiaSMI = Get-Command `
    nvidia-smi `
    -ErrorAction SilentlyContinue


if ($NvidiaSMI) {

    try {

        $NvidiaData = @(
            nvidia-smi `
                --query-gpu=name,memory.total,driver_version `
                --format=csv,noheader,nounits
        )


        if ($NvidiaData.Count -gt 0) {

            $NvidiaNames = @()

            $NvidiaMemory = @()

            $NvidiaDrivers = @()


            foreach ($Linha in $NvidiaData) {

                $Parts = $Linha.Split(",")


                if ($Parts.Count -ge 3) {

                    $NvidiaNames += (
                        $Parts[0].Trim()
                    )


                    $VRAMMB = [double](
                        $Parts[1].Trim()
                    )


                    $NvidiaMemory += (
                        "{0:N2} GB" -f (
                            $VRAMMB /
                            1024
                        )
                    )


                    $NvidiaDrivers += (
                        $Parts[2].Trim()
                    )
                }
            }


            if ($NvidiaNames.Count -gt 0) {

                $GPUModel = (
                    $NvidiaNames |
                    Select-Object -Unique
                ) -join " + "
            }


            if ($NvidiaMemory.Count -gt 0) {

                $GPUVRAMText = (
                    $NvidiaMemory |
                    Select-Object -Unique
                ) -join " / "
            }


            if ($NvidiaDrivers.Count -gt 0) {

                $GPUDriver = (
                    $NvidiaDrivers |
                    Select-Object -Unique
                ) -join " / "
            }
        }
    }
    catch {
    }
}


# ---------------------------------------------------------------------
# DISCOS
# ---------------------------------------------------------------------

$DiskDescription = @()


try {

    $PhysicalDisks = @(
        Get-PhysicalDisk `
            -ErrorAction Stop
    )


    foreach ($Disk in $PhysicalDisks) {

        $DiskGB = [math]::Round(
            $Disk.Size /
            1GB,
            0
        )


        $DiskDescription += (
            "$($Disk.FriendlyName) | " +
            "$($Disk.MediaType) | " +
            "$($Disk.BusType) | " +
            "$DiskGB GB"
        )
    }
}
catch {

    $DiskDrives = @(
        Get-CimInstance Win32_DiskDrive
    )


    foreach ($Disk in $DiskDrives) {

        $DiskGB = [math]::Round(
            $Disk.Size /
            1GB,
            0
        )


        $DiskDescription += (
            "$($Disk.Model) | " +
            "$($Disk.InterfaceType) | " +
            "$DiskGB GB"
        )
    }
}


$DiskText = (
    $DiskDescription
) -join " ; "


# =====================================================================
# MOSTRAR HARDWARE
# =====================================================================

Clear-Host

Write-Host "================================================================="
Write-Host "                 HARDWARE IDENTIFICADO"
Write-Host "================================================================="
Write-Host ""

Write-Host "Computador : $ComputerName"
Write-Host "Fabricante : $FabricantePC"
Write-Host "Modelo     : $ModeloPC"

Write-Host ""

Write-Host "Windows    : $WindowsName"
Write-Host "Versao     : $WindowsVersion"
Write-Host "Build      : $WindowsBuild"

Write-Host ""

Write-Host "---------------- PROCESSADOR ----------------"

Write-Host ""

Write-Host "CPU        : $CPUModel"
Write-Host "Nucleos    : $CPUCores"
Write-Host "Threads    : $CPUThreads"

Write-Host ""

Write-Host "---------------- MEMORIA RAM ----------------"

Write-Host ""

Write-Host "Total      : $RAMTotalGB GB"
Write-Host "Modulos    : $RAMModuleDescription"
Write-Host "Tipo       : $RAMType"
Write-Host "Velocidade : $RAMSpeed"

Write-Host ""

Write-Host "-------------------- GPU --------------------"

Write-Host ""

Write-Host "GPU        : $GPUModel"
Write-Host "VRAM       : $GPUVRAMText"
Write-Host "Driver     : $GPUDriver"

Write-Host ""

Write-Host "------------------- DISCOS ------------------"

Write-Host ""

foreach ($DiskLine in $DiskDescription) {

    Write-Host $DiskLine
}

Write-Host ""

Write-Host "================================================================="


# =====================================================================
# SALVAR INVENTARIO DO HARDWARE
# =====================================================================

$HardwareFile = (
    "$Pasta\Hardware_$ComputerName.txt"
)


$HardwareReport = @"

=================================================================
RELATORIO DE HARDWARE
=================================================================

Data:
$(Get-Date -Format "dd/MM/yyyy HH:mm:ss")

Computador:
$ComputerName

Fabricante:
$FabricantePC

Modelo:
$ModeloPC

Windows:
$WindowsName

Versao:
$WindowsVersion

Build:
$WindowsBuild


PROCESSADOR
-----------------------------------------------------------------

Modelo:
$CPUModel

Nucleos:
$CPUCores

Threads:
$CPUThreads


MEMORIA RAM
-----------------------------------------------------------------

Total:
$RAMTotalGB GB

Modulos:
$RAMModuleDescription

Tipo:
$RAMType

Velocidade:
$RAMSpeed


GPU
-----------------------------------------------------------------

Modelo:
$GPUModel

VRAM:
$GPUVRAMText

Driver:
$GPUDriver


DISCOS
-----------------------------------------------------------------

$DiskText

=================================================================
"@


$HardwareReport |
Out-File `
    -FilePath $HardwareFile `
    -Encoding UTF8


# =====================================================================
# EXPLICACAO DO MONITORAMENTO
# =====================================================================

Write-Host ""
Write-Host "================================================================="
Write-Host "                O QUE VOCE DESEJA MONITORAR?"
Write-Host "================================================================="
Write-Host ""

Write-Host "Este programa monitora a maquina inteira e um alvo especifico."
Write-Host ""

Write-Host "[1] PROCESSO / APLICATIVO"
Write-Host ""
Write-Host "Use esta opcao para programas executados no Windows."
Write-Host ""
Write-Host "Exemplos:"
Write-Host "  HikCentralControlClient"
Write-Host "  chrome"
Write-Host "  notepad"
Write-Host ""

Write-Host "[2] SERVICO WINDOWS"
Write-Host ""
Write-Host "Use esta opcao para servicos encontrados no services.msc."
Write-Host ""
Write-Host "Exemplos:"
Write-Host "  Spooler"
Write-Host "  W32Time"
Write-Host "  MSSQLSERVER"
Write-Host ""

Write-Host "[3] SAIR"
Write-Host ""


# =====================================================================
# ESCOLHER TIPO
# =====================================================================

do {

    $Opcao = Read-Host "Escolha 1, 2 ou 3"

}
while (
    $Opcao -notin @(
        "1",
        "2",
        "3"
    )
)


if ($Opcao -eq "3") {

    Write-Host ""
    Write-Host "Monitoramento cancelado."

    return
}


# =====================================================================
# SELECAO DE PROCESSO
# =====================================================================

if ($Opcao -eq "1") {

    $TargetType = "Processo"

    Write-Host ""
    Write-Host "---------------------------------------------------------"
    Write-Host " PROCESSO / APLICATIVO"
    Write-Host "---------------------------------------------------------"
    Write-Host ""

    $TargetName = Read-Host `
        "Digite o nome do processo (ex.: HikCentralControlClient)"


    $TargetName = (
        $TargetName.Trim()
    )


    if (
        $TargetName.ToLower().EndsWith(
            ".exe"
        )
    ) {

        $TargetName = (
            $TargetName.Substring(
                0,
                $TargetName.Length - 4
            )
        )
    }


    $TargetDisplayName = $TargetName


    $TesteProcesso = @(
        Get-Process `
            -Name $TargetName `
            -ErrorAction SilentlyContinue
    )


    if ($TesteProcesso.Count -gt 0) {

        Write-Host ""
        Write-Host "Processo localizado."
        Write-Host ""

        Write-Host (
            "Quantidade de processos: {0}" -f `
            $TesteProcesso.Count
        )

    }
    else {

        Write-Host ""
        Write-Host "ATENCAO:"
        Write-Host ""
        Write-Host "O processo nao esta em execucao neste momento."
        Write-Host "O monitor continuara aguardando ele iniciar."
    }
}


# =====================================================================
# SELECAO DE SERVICO
# =====================================================================

if ($Opcao -eq "2") {

    $TargetType = "Servico"

    Write-Host ""
    Write-Host "---------------------------------------------------------"
    Write-Host " SERVICO WINDOWS"
    Write-Host "---------------------------------------------------------"
    Write-Host ""

    $PesquisaServico = Read-Host `
        "Digite parte do nome do servico"


    $ServicosEncontrados = @(
        Get-Service |
        Where-Object {

            $_.Name -like "*$PesquisaServico*" -or
            $_.DisplayName -like "*$PesquisaServico*"
        }
    )


    if ($ServicosEncontrados.Count -eq 0) {

        Write-Host ""
        Write-Host "Nenhum servico encontrado."

        return
    }


    if ($ServicosEncontrados.Count -eq 1) {

        $ServicoSelecionado = (
            $ServicosEncontrados[0]
        )
    }
    else {

        Write-Host ""
        Write-Host "Servicos encontrados:"
        Write-Host ""


        for (
            $i = 0;
            $i -lt $ServicosEncontrados.Count;
            $i++
        ) {

            Write-Host (
                "[{0}] {1} | {2} | {3}" -f `
                ($i + 1),
                $ServicosEncontrados[$i].Name,
                $ServicosEncontrados[$i].DisplayName,
                $ServicosEncontrados[$i].Status
            )
        }


        Write-Host ""


        $NumeroServico = Read-Host `
            "Digite o numero do servico"


        $IndiceServico = (
            [int]$NumeroServico -
            1
        )


        if (
            $IndiceServico -lt 0 -or
            $IndiceServico -ge
            $ServicosEncontrados.Count
        ) {

            Write-Host "Opcao invalida."

            return
        }


        $ServicoSelecionado = (
            $ServicosEncontrados[
                $IndiceServico
            ]
        )
    }


    $TargetName = (
        $ServicoSelecionado.Name
    )

    $TargetDisplayName = (
        $ServicoSelecionado.DisplayName
    )


    Write-Host ""
    Write-Host "Servico selecionado:"
    Write-Host ""
    Write-Host "Nome        : $TargetName"
    Write-Host "Descricao   : $TargetDisplayName"
    Write-Host "Status      : $($ServicoSelecionado.Status)"
}


# =====================================================================
# CONFIRMACAO
# =====================================================================

Write-Host ""
Write-Host "================================================================="
Write-Host "                  CONFIGURACAO DO MONITOR"
Write-Host "================================================================="
Write-Host ""

Write-Host "Computador       : $ComputerName"
Write-Host "Tipo monitorado  : $TargetType"
Write-Host "Alvo             : $TargetDisplayName"
Write-Host "Nome tecnico     : $TargetName"
Write-Host ""

Write-Host "Coleta           : a cada $IntervaloColeta segundos"
Write-Host "Gravacao         : a cada 10 minutos"
Write-Host ""

Write-Host "O monitor registra:"
Write-Host ""
Write-Host "- CPU da maquina"
Write-Host "- RAM da maquina"
Write-Host "- GPU da maquina"
Write-Host "- CPU do alvo"
Write-Host "- RAM do alvo"
Write-Host "- GPU do alvo"
Write-Host "- quantidade de processos do alvo"
Write-Host "- status do alvo"
Write-Host "- media e pico de cada periodo"
Write-Host ""

$Confirmar = Read-Host `
    "Pressione ENTER para iniciar ou digite N para cancelar"


if (
    $Confirmar.ToUpper() -eq "N"
) {

    return
}


# =====================================================================
# NOME DO ARQUIVO
# =====================================================================

$SafeTarget = (
    $TargetName -replace `
    '[^\w\.-]',
    '_'
)


$ArquivoCSV = (
    "$Pasta\Monitoramento_" +
    "$SafeTarget" +
    "_" +
    "$ComputerName" +
    ".csv"
)


# =====================================================================
# ARRAYS
# =====================================================================

$CPU_Maquina = @()

$RAM_Maquina = @()

$GPU_Maquina = @()


$CPU_Alvo = @()

$RAM_Alvo = @()

$GPU_Alvo = @()

$Qtd_Processos = @()


$AmostrasEncontrado = 0

$AmostrasNaoEncontrado = 0


# =====================================================================
# CPU ANTERIOR DOS PROCESSOS
# =====================================================================

$PrevCPU = @{}


$UltimoSalvamento = Get-Date


# =====================================================================
# LOOP PRINCIPAL
# =====================================================================

while ($true) {

    $InicioCiclo = Get-Date


    # =================================================================
    # MAQUINA
    # =================================================================

    $CPU_Total = Get-SystemCPU


    $RAMInfo = Get-SystemRAM

    $RAMPercent = $RAMInfo.Percent

    $RAMUsedGB = $RAMInfo.UsedGB

    $RAMTotalCurrentGB = $RAMInfo.TotalGB


    # =================================================================
    # GPU
    # =================================================================

    $GPUSamples = Get-GPUSamples


    if ($GPUSamples.Count -gt 0) {

        $GPUTotal = (
            $GPUSamples |
            Measure-Object `
                -Property CookedValue `
                -Maximum
        ).Maximum

    }
    else {

        $GPUTotal = $null
    }


    # =================================================================
    # LOCALIZAR O ALVO
    # =================================================================

    $TargetProcesses = @()

    $TargetStatus = "Nao encontrado"


    if ($TargetType -eq "Processo") {

        $TargetProcesses = @(
            Get-Process `
                -Name $TargetName `
                -ErrorAction SilentlyContinue
        )


        if ($TargetProcesses.Count -gt 0) {

            $TargetStatus = "Em execucao"
        }
    }


    # =================================================================
    # SERVICO
    # =================================================================

    if ($TargetType -eq "Servico") {

        $ServiceInfo = Get-Service `
            -Name $TargetName `
            -ErrorAction SilentlyContinue


        if ($ServiceInfo) {

            $TargetStatus = (
                $ServiceInfo.Status.ToString()
            )


            if (
                $ServiceInfo.Status -eq "Running"
            ) {

                $EscapedServiceName = (
                    $TargetName.Replace(
                        "'",
                        "''"
                    )
                )


                $ServiceCIM = Get-CimInstance `
                    Win32_Service `
                    -Filter "Name='$EscapedServiceName'" `
                    -ErrorAction SilentlyContinue


                if (
                    $ServiceCIM -and
                    $ServiceCIM.ProcessId -gt 0
                ) {

                    $ProcServico = Get-Process `
                        -Id $ServiceCIM.ProcessId `
                        -ErrorAction SilentlyContinue


                    if ($ProcServico) {

                        $TargetProcesses = @(
                            $ProcServico
                        )
                    }
                }
            }
        }
    }


    # =================================================================
    # MEDICAO DO ALVO
    # =================================================================

    $TargetCPU = 0

    $TargetRAM = 0

    $TargetGPU = 0


    $AgoraCPU = Get-Date

    $NovoPrevCPU = @{}


    if ($TargetProcesses.Count -gt 0) {

        $AmostrasEncontrado++


        foreach ($Proc in $TargetProcesses) {

            # ----------------------------------------------------------
            # RAM
            # ----------------------------------------------------------

            $TargetRAM += (
                [double]$Proc.WorkingSet64 /
                1MB
            )


            # ----------------------------------------------------------
            # CPU
            # ----------------------------------------------------------

            $CPUAtual = [double]$Proc.CPU


            $KeyPID = (
                $Proc.Id.ToString()
            )


            if ($PrevCPU.ContainsKey($KeyPID)) {

                $Old = (
                    $PrevCPU[$KeyPID]
                )


                $Elapsed = (
                    $AgoraCPU -
                    $Old.Time
                ).TotalSeconds


                if ($Elapsed -gt 0) {

                    $DeltaCPU = (
                        $CPUAtual -
                        $Old.CPU
                    )


                    if ($DeltaCPU -ge 0) {

                        $TargetCPU += (
                            (
                                $DeltaCPU /
                                $Elapsed
                            ) *
                            100 /
                            $CPUThreads
                        )
                    }
                }
            }


            $NovoPrevCPU[$KeyPID] = [PSCustomObject]@{

                CPU = $CPUAtual

                Time = $AgoraCPU
            }
        }


        # --------------------------------------------------------------
        # GPU DO ALVO
        # --------------------------------------------------------------

        if ($GPUSamples.Count -gt 0) {

            $TargetGPUSamples = @()


            foreach ($Proc in $TargetProcesses) {

                $PIDPattern = (
                    "pid_{0}_" -f `
                    $Proc.Id
                )


                $TargetGPUSamples += @(
                    $GPUSamples |
                    Where-Object {

                        $_.InstanceName -match `
                        $PIDPattern
                    }
                )
            }


            if (
                $TargetGPUSamples.Count -gt 0
            ) {

                $TargetGPU = (
                    $TargetGPUSamples |
                    Measure-Object `
                        -Property CookedValue `
                        -Maximum
                ).Maximum
            }
        }
    }
    else {

        $AmostrasNaoEncontrado++
    }


    $PrevCPU = $NovoPrevCPU


    if ($TargetCPU -lt 0) {

        $TargetCPU = 0
    }


    if ($TargetCPU -gt 100) {

        $TargetCPU = 100
    }


    # =================================================================
    # GUARDAR AMOSTRAS NA RAM
    # =================================================================

    $CPU_Maquina += [double]$CPU_Total

    $RAM_Maquina += [double]$RAMPercent


    if ($null -ne $GPUTotal) {

        $GPU_Maquina += [double]$GPUTotal
    }


    if ($TargetProcesses.Count -gt 0) {

        $CPU_Alvo += [double]$TargetCPU

        $RAM_Alvo += [double]$TargetRAM

        $GPU_Alvo += [double]$TargetGPU

        $Qtd_Processos += (
            [double]$TargetProcesses.Count
        )
    }


    # =================================================================
    # TELA
    # =================================================================

    $Agora = Get-Date


    $TempoDesdeSalvar = (
        $Agora -
        $UltimoSalvamento
    ).TotalSeconds


    $Restante = (
        $IntervaloSalvamento -
        $TempoDesdeSalvar
    )


    if ($Restante -lt 0) {

        $Restante = 0
    }


    $MinRestante = [math]::Floor(
        $Restante /
        60
    )


    $SegRestante = [math]::Floor(
        $Restante %
        60
    )


    Clear-Host


    Write-Host "================================================================="
    Write-Host "                 MONITOR DE DESEMPENHO"
    Write-Host "================================================================="
    Write-Host ""

    Write-Host (
        "Horario : {0}" -f `
        $Agora.ToString(
            "dd/MM/yyyy HH:mm:ss"
        )
    )

    Write-Host ""
    Write-Host "-------------------- HARDWARE --------------------"
    Write-Host ""

    Write-Host "CPU : $CPUModel"
    Write-Host "RAM : $RAMTotalGB GB | $RAMType"
    Write-Host "GPU : $GPUModel"
    Write-Host "Disco: $DiskText"

    Write-Host ""
    Write-Host "-------------------- MAQUINA ---------------------"
    Write-Host ""

    Write-Host (
        "CPU : {0:N2} %" -f `
        $CPU_Total
    )


    Write-Host (
        "RAM : {0:N2} % ({1:N2} GB / {2:N2} GB)" -f `
        $RAMPercent,
        $RAMUsedGB,
        $RAMTotalCurrentGB
    )


    if ($null -ne $GPUTotal) {

        Write-Host (
            "GPU : {0:N2} %" -f `
            $GPUTotal
        )

    }
    else {

        Write-Host "GPU : contador indisponivel"
    }


    Write-Host ""
    Write-Host "---------------------- ALVO ----------------------"
    Write-Host ""

    Write-Host "Tipo   : $TargetType"
    Write-Host "Nome   : $TargetDisplayName"
    Write-Host "Status : $TargetStatus"

    Write-Host ""

    Write-Host (
        "Processos : {0}" -f `
        $TargetProcesses.Count
    )


    Write-Host (
        "CPU       : {0:N2} %" -f `
        $TargetCPU
    )


    Write-Host (
        "RAM       : {0:N2} MB" -f `
        $TargetRAM
    )


    Write-Host (
        "GPU       : {0:N2} %" -f `
        $TargetGPU
    )


    Write-Host ""
    Write-Host "--------------------------------------------------"

    Write-Host (
        "Amostras           : {0}" -f `
        $CPU_Maquina.Count
    )


    Write-Host (
        "Proximo salvamento : {0:00}:{1:00}" -f `
        $MinRestante,
        $SegRestante
    )


    Write-Host ""
    Write-Host "Arquivo:"
    Write-Host $ArquivoCSV

    Write-Host ""
    Write-Host "CTRL + C para encerrar"


    # =================================================================
    # SALVAMENTO DE 10 MINUTOS
    # =================================================================

    if (
        $TempoDesdeSalvar -ge
        $IntervaloSalvamento
    ) {

        # --------------------------------------------------------------
        # RESUMOS
        # --------------------------------------------------------------

        $ResumoCPUMaq = Get-Summary `
            $CPU_Maquina

        $ResumoRAMMaq = Get-Summary `
            $RAM_Maquina

        $ResumoGPUMaq = Get-Summary `
            $GPU_Maquina


        $ResumoCPUAlvo = Get-Summary `
            $CPU_Alvo

        $ResumoRAMAlvo = Get-Summary `
            $RAM_Alvo

        $ResumoGPUAlvo = Get-Summary `
            $GPU_Alvo

        $ResumoQtdAlvo = Get-Summary `
            $Qtd_Processos


        $FimPeriodo = Get-Date


        # --------------------------------------------------------------
        # REGISTRO
        # --------------------------------------------------------------

        $Registro = [PSCustomObject]@{

            Computador =
                $ComputerName

            Fabricante =
                $FabricantePC

            Modelo_Computador =
                $ModeloPC

            Windows =
                $WindowsName

            CPU_Modelo =
                $CPUModel

            CPU_Nucleos =
                $CPUCores

            CPU_Threads =
                $CPUThreads

            RAM_Total_GB =
                $RAMTotalGB

            RAM_Tipo =
                $RAMType

            RAM_Velocidade =
                $RAMSpeed

            GPU_Modelo =
                $GPUModel

            GPU_VRAM =
                $GPUVRAMText

            GPU_Driver =
                $GPUDriver

            Discos =
                $DiskText

            Tipo_Alvo =
                $TargetType

            Nome_Alvo =
                $TargetName

            Descricao_Alvo =
                $TargetDisplayName

            Inicio_Periodo =
                $UltimoSalvamento.ToString(
                    "dd/MM/yyyy HH:mm:ss"
                )

            Fim_Periodo =
                $FimPeriodo.ToString(
                    "dd/MM/yyyy HH:mm:ss"
                )

            Amostras_Maquina =
                $CPU_Maquina.Count

            Alvo_Encontrado =
                $AmostrasEncontrado

            Alvo_Nao_Encontrado =
                $AmostrasNaoEncontrado

            CPU_Maquina_Media_Percent =
                if (
                    $null -ne
                    $ResumoCPUMaq.Average
                ) {
                    [math]::Round(
                        $ResumoCPUMaq.Average,
                        2
                    )
                }
                else {
                    $null
                }

            CPU_Maquina_Pico_Percent =
                if (
                    $null -ne
                    $ResumoCPUMaq.Maximum
                ) {
                    [math]::Round(
                        $ResumoCPUMaq.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            RAM_Maquina_Media_Percent =
                if (
                    $null -ne
                    $ResumoRAMMaq.Average
                ) {
                    [math]::Round(
                        $ResumoRAMMaq.Average,
                        2
                    )
                }
                else {
                    $null
                }

            RAM_Maquina_Pico_Percent =
                if (
                    $null -ne
                    $ResumoRAMMaq.Maximum
                ) {
                    [math]::Round(
                        $ResumoRAMMaq.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            GPU_Maquina_Media_Percent =
                if (
                    $null -ne
                    $ResumoGPUMaq.Average
                ) {
                    [math]::Round(
                        $ResumoGPUMaq.Average,
                        2
                    )
                }
                else {
                    $null
                }

            GPU_Maquina_Pico_Percent =
                if (
                    $null -ne
                    $ResumoGPUMaq.Maximum
                ) {
                    [math]::Round(
                        $ResumoGPUMaq.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_Processos_Media =
                if (
                    $null -ne
                    $ResumoQtdAlvo.Average
                ) {
                    [math]::Round(
                        $ResumoQtdAlvo.Average,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_Processos_Pico =
                if (
                    $null -ne
                    $ResumoQtdAlvo.Maximum
                ) {
                    [math]::Round(
                        $ResumoQtdAlvo.Maximum,
                        0
                    )
                }
                else {
                    $null
                }

            Alvo_CPU_Media_Percent =
                if (
                    $null -ne
                    $ResumoCPUAlvo.Average
                ) {
                    [math]::Round(
                        $ResumoCPUAlvo.Average,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_CPU_Pico_Percent =
                if (
                    $null -ne
                    $ResumoCPUAlvo.Maximum
                ) {
                    [math]::Round(
                        $ResumoCPUAlvo.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_RAM_Media_MB =
                if (
                    $null -ne
                    $ResumoRAMAlvo.Average
                ) {
                    [math]::Round(
                        $ResumoRAMAlvo.Average,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_RAM_Pico_MB =
                if (
                    $null -ne
                    $ResumoRAMAlvo.Maximum
                ) {
                    [math]::Round(
                        $ResumoRAMAlvo.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_GPU_Media_Percent =
                if (
                    $null -ne
                    $ResumoGPUAlvo.Average
                ) {
                    [math]::Round(
                        $ResumoGPUAlvo.Average,
                        2
                    )
                }
                else {
                    $null
                }

            Alvo_GPU_Pico_Percent =
                if (
                    $null -ne
                    $ResumoGPUAlvo.Maximum
                ) {
                    [math]::Round(
                        $ResumoGPUAlvo.Maximum,
                        2
                    )
                }
                else {
                    $null
                }

            Status_Final_Alvo =
                $TargetStatus
        }


        # --------------------------------------------------------------
        # CSV
        # --------------------------------------------------------------

        if (Test-Path $ArquivoCSV) {

            $Registro |
            Export-Csv `
                -Path $ArquivoCSV `
                -Delimiter ";" `
                -NoTypeInformation `
                -Encoding UTF8 `
                -Append

        }
        else {

            $Registro |
            Export-Csv `
                -Path $ArquivoCSV `
                -Delimiter ";" `
                -NoTypeInformation `
                -Encoding UTF8
        }


        # --------------------------------------------------------------
        # LIMPAR AMOSTRAS DO PERIODO
        # --------------------------------------------------------------

        $CPU_Maquina = @()

        $RAM_Maquina = @()

        $GPU_Maquina = @()


        $CPU_Alvo = @()

        $RAM_Alvo = @()

        $GPU_Alvo = @()

        $Qtd_Processos = @()


        $AmostrasEncontrado = 0

        $AmostrasNaoEncontrado = 0


        $UltimoSalvamento = Get-Date


        Write-Host ""
        Write-Host "================================================================="
        Write-Host "       PERIODO DE 10 MINUTOS SALVO COM SUCESSO"
        Write-Host "================================================================="

        Start-Sleep -Seconds 2
    }


    # =================================================================
    # GARANTIR CICLO DE 15 SEGUNDOS
    # =================================================================

    $TempoCiclo = (
        (Get-Date) -
        $InicioCiclo
    ).TotalSeconds


    $Espera = (
        $IntervaloColeta -
        $TempoCiclo
    )


    if ($Espera -gt 0) {

        Start-Sleep `
            -Milliseconds (
                [int](
                    $Espera *
                    1000
                )
            )
    }
}

Exemplo de execução

.\consultar-servicos.ps1