#region Configuración inicial
$eventMap = @{
6005 = "System"; 6006 = "System"; 6008 = "System"; 41 = "System"
1001 = "System"; 7000 = "Application"; 7001 = "Application"
129 = "Application"; 7 = @("Application","Security"); 5 = "Security"
}
$vmList = @("Q2CRTEWS06")
$startDate = (Get-Date).AddDays(-7)
$cred = Get-Credential
#endregion
#region Recolección distribuida
$resumenGlobal = @()
# Lanzar un job por cada VM
$jobs = foreach ($vm in $vmList) {
Start-Job -ArgumentList $vm, $eventMap, $startDate, $cred -ScriptBlock {
param($vm, $eventMap, $startDate, $cred)
$resLocal = @()
# 1. Eventos
foreach ($eventID in $eventMap.Keys) {
$logs = @($eventMap[$eventID])
foreach ($log in $logs) {
try {
$cnt = (Get-WinEvent -ComputerName $vm -Credential $cred -FilterHashtable @{ LogName = $log; ID = $eventID; StartTime = $startDate } -ErrorAction Stop).Count
$resLocal += [PSCustomObject]@{
VM = $vm
Tipo = 'Evento'
Recurso = $log
ID = $eventID
Valor = $cnt
}
}
catch {
$resLocal += [PSCustomObject]@{
VM = $vm
Tipo = 'Evento'
Recurso = $log
ID = $eventID
Valor = "Error: $($_.Exception.Message)"
}
}
}
}
# 2. Métricas de CPU y RAM vía Invoke-Command
try {
$remoteMetrics = Invoke-Command -ComputerName $vm -Credential $cred -ScriptBlock {
$cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples[0].CookedValue
$os = Get-CimInstance Win32_OperatingSystem
[PSCustomObject]@{
CPU = $cpu
TotalMem = $os.TotalVisibleMemorySize
FreeMem = $os.FreePhysicalMemory
}
}
$cpuPercent = [math]::Round($remoteMetrics.CPU,2)
$ramPercent = [math]::Round((($remoteMetrics.TotalMem - $remoteMetrics.FreeMem) / $remoteMetrics.TotalMem) * 100,2)
$totalMemMB = [math]::Round($remoteMetrics.TotalMem / 1KB,2)
$freeMemMB = [math]::Round($remoteMetrics.FreeMem / 1KB,2)
$resLocal += [PSCustomObject]@{
VM = $vm
Tipo = 'Métrica'
Recurso = 'CPU'
Valor = $cpuPercent
TotalMemMB = $null
FreeMemMB = $null
}
$resLocal += [PSCustomObject]@{
VM = $vm
Tipo = 'Métrica'
Recurso = 'RAM'
Valor = $ramPercent
TotalMemMB = $totalMemMB
FreeMemMB = $freeMemMB
}
}
catch {
Write-Warning "No se pudo obtener métricas de CPU/RAM para ${vm}: $($_.Exception.Message)"
}
# 3. Estado de discos C, D, E, F vía Invoke-Command
try {
$remoteDisks = Invoke-Command -ComputerName $vm -Credential $cred -ScriptBlock {
Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3' |
Select-Object DeviceID,Size,FreeSpace
}
foreach ($d in $remoteDisks) {
if ($d.DeviceID -match '^[CDEF]:$') {
$usedPct = [math]::Round((($d.Size - $d.FreeSpace) / $d.Size) * 100,2)
$usedGB = [math]::Round(($d.Size - $d.FreeSpace) / 1GB,2)
$freeGB = [math]::Round($d.FreeSpace / 1GB,2)
$sizeGB = [math]::Round($d.Size / 1GB,2)
$resLocal += [PSCustomObject]@{
VM = $vm
Tipo = 'Disco'
Recurso = $d.DeviceID
Valor = $usedPct
TamañoGB = $sizeGB
UsadoGB = $usedGB
LibreGB = $freeGB
}
}
}
}
catch {
Write-Warning "No se pudo obtener estado de discos para ${vm}: $($_.Exception.Message)"
}
return $resLocal
}
}
# Esperar a que todos los jobs completen
Wait-Job -Job $jobs
# Recoger resultados y eliminar jobs
foreach ($j in $jobs) {
$resumenGlobal += Receive-Job -Job $j
Remove-Job -Job $j
}
#endregion
#region Salida y exportación por VM
# Agrupar resultados por VM y exportar individualmente
$resumenGlobal |
Group-Object -Property VM | ForEach-Object {
$computer = $_.Name
$salida = $_.Group |
Select-Object VM, Tipo, Recurso, ID, Valor, TotalMemMB, FreeMemMB, TamañoGB, UsadoGB, LibreGB |
Sort-Object Tipo, Recurso, ID
# Definir ruta de salida usando la variable $computer
$outputPath = "D:\temp\chek_List_VM\Gen_${computer}.csv"
$folder = Split-Path $outputPath
if (-not (Test-Path $folder)) {
New-Item -Path $folder -ItemType Directory -Force | Out-Null
}
# Mostrar en consola
Write-Host "`n-- Resultados para $computer --"
$salida | Format-Table -AutoSize
# Exportar CSV
$salida | Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8
Write-Host "📊 Resumen para $computer exportado: $outputPath"
}
#endregion