Feat: PS1 Añadido - Fix: Eliminación de Equipos

This commit is contained in:
2025-10-08 13:51:27 -03:00
parent 268c1c2bf9
commit afd378712c
4 changed files with 264 additions and 6 deletions

View File

@@ -189,15 +189,13 @@ namespace Inventario.API.Controllers
[HttpDelete("{id}")] [HttpDelete("{id}")]
public async Task<IActionResult> Borrar(int id) public async Task<IActionResult> Borrar(int id)
{ {
var query = "DELETE FROM dbo.equipos WHERE Id = @Id AND Origen = 'manual';"; var query = "DELETE FROM dbo.equipos WHERE Id = @Id;";
using (var connection = _context.CreateConnection()) using (var connection = _context.CreateConnection())
{ {
var filasAfectadas = await connection.ExecuteAsync(query, new { Id = id }); var filasAfectadas = await connection.ExecuteAsync(query, new { Id = id });
if (filasAfectadas == 0) if (filasAfectadas == 0)
{ {
// Puede que no se haya borrado porque no existe o porque es automático. return NotFound("Equipo no encontrado.");
// Damos un mensaje de error genérico pero informativo.
return NotFound("Equipo no encontrado o no se puede eliminar porque fue generado automáticamente.");
} }
return NoContent(); return NoContent();
} }

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Inventario.API")] [assembly: System.Reflection.AssemblyCompanyAttribute("Inventario.API")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+177ad5596221b094cc62c04b38044cc9f09a107e")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+268c1c2bf99b66ab7fb5c6dd1a2d1134d636839e")]
[assembly: System.Reflection.AssemblyProductAttribute("Inventario.API")] [assembly: System.Reflection.AssemblyProductAttribute("Inventario.API")]
[assembly: System.Reflection.AssemblyTitleAttribute("Inventario.API")] [assembly: System.Reflection.AssemblyTitleAttribute("Inventario.API")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -226,7 +226,19 @@ const ModalDetallesEquipo: React.FC<ModalDetallesEquipoProps> = ({
</Tooltip> </Tooltip>
</div> </div>
<div className={styles.detailItem}><strong className={styles.detailLabel}>Eliminar Equipo:</strong><button onClick={handleDeleteClick} className={styles.deleteButton} disabled={equipo.origen !== 'manual'} style={{ cursor: equipo.origen !== 'manual' ? 'not-allowed' : 'pointer' }} data-tooltip-id="modal-delete-tooltip">🗑 Eliminar</button><Tooltip id="modal-delete-tooltip" place="top">{equipo.origen === 'manual' ? 'Eliminar equipo permanentemente' : 'No se puede eliminar un equipo cargado automáticamente'}</Tooltip></div> <div className={styles.detailItem}>
<strong className={styles.detailLabel}>Eliminar Equipo:</strong>
<button
onClick={handleDeleteClick}
className={styles.deleteButton}
data-tooltip-id="modal-delete-tooltip"
>
🗑 Eliminar
</button>
<Tooltip id="modal-delete-tooltip" place="top">
Eliminar este equipo permanentemente del inventario
</Tooltip>
</div>
</div> </div>
</div> </div>
</div> </div>

248
getDatosPost.ps1 Normal file
View File

@@ -0,0 +1,248 @@
# =================================================================================
# SCRIPT DE INVENTARIO AUTOMÁTICO PARA INVENTARIO-IT
#
# Descripción:
# Este script recopila información de hardware y software del equipo y la envía
# a la API del sistema de inventario. Es compatible con Windows 7 y versiones
# superiores (Windows 10, 11, Server 2012+).
# =================================================================================
# --- CONFIGURACIÓN ---
# Host/IP del servidor de API.
$baseUrl = "http://equipos.eldia.net"
# ---------------------
# --- DETECCIÓN DE VERSIÓN DE WINDOWS Y FUNCIONES AUXILIARES ---
$osInfo = Get-WmiObject Win32_OperatingSystem
$isWindows7 = [version]$osInfo.Version -lt [version]"6.2"
if ($isWindows7) {
Write-Host "Ejecutando en modo de compatibilidad para Windows 7 (PowerShell 2.0)..."
# Función de conversión a JSON para PowerShell 2.0
function ConvertTo-BasicJson {
param($InputObject)
if ($null -eq $InputObject) { return "null" }
if ($InputObject -is [array]) {
$json = @()
foreach ($item in $InputObject) { $json += ConvertTo-BasicJson -InputObject $item }
return "[$($json -join ',')]"
}
elseif ($InputObject -is [System.Collections.IDictionary]) {
$props = @()
foreach ($key in $InputObject.Keys) { $props += "`"$key`":$(ConvertTo-BasicJson -InputObject $InputObject[$key])" }
return "{$($props -join ',')}"
}
elseif ($InputObject -is [string]) {
return "`"$($InputObject.ToString().Replace('\', '\\').Replace('"', '\"'))`""
}
elseif ($InputObject -is [bool]) {
return $InputObject.ToString().ToLower()
}
else { # Números y otros tipos
return $InputObject.ToString()
}
}
# Función de envío de datos para PowerShell 2.0
function Send-Data {
param($Url, $Method, $Body)
try {
$webClient = New-Object System.Net.WebClient
$webClient.Headers.Add("Content-Type", "application/json")
return $webClient.UploadString($Url, $Method, $Body)
} catch {
Write-Host "Error en el envío a $Url: $($_.Exception.Message)"
return $null
}
}
} else {
Write-Host "Ejecutando en modo estándar (PowerShell 5+)..."
}
# --- RECOPILACIÓN DE DATOS ---
Write-Host "Recopilando información del sistema..."
if ($isWindows7) {
# --- Lógica para Windows 7 ---
$hostname = $env:COMPUTERNAME
$username = $env:USERNAME
$activeInterface = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -eq $true -and $_.DefaultIPGateway -ne $null } | Sort-Object InterfaceIndex | Select-Object -First 1
$ip = if ($activeInterface) { $activeInterface.IPAddress[0] } else { "N/A" }
$mac = if ($activeInterface) { $activeInterface.MACAddress } else { "N/A" }
$cpu = (Get-WmiObject Win32_Processor).Name
$motherboard = (Get-WmiObject Win32_BaseBoard).Product
$ramSlots = (Get-WmiObject Win32_PhysicalMemoryArray).MemoryDevices
$osName = $osInfo.Caption
$osArchitecture = $osInfo.OSArchitecture
# Discos (WMI)
$disks = @(Get-WmiObject Win32_DiskDrive | Where-Object { $_.MediaType -like "*hard disk*" } | ForEach-Object {
[PSCustomObject]@{
mediatype = if ((Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($_.DeviceID)'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" | Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($_.DeviceID)'} WHERE AssocClass=Win32_LogicalDiskToPartition" | Select-Object -First 1).Description -like "*SSD*") { "SSD" } else { "HDD" }
size = [math]::Round($_.Size / 1GB, 0)
}
})
# Módulos de RAM (WMI) - ¡NUEVO!
$ramModules = @(Get-WmiObject Win32_PhysicalMemory | ForEach-Object {
[PSCustomObject]@{
partNumber = $_.PartNumber.Trim()
fabricante = $_.Manufacturer.Trim()
tamano = [math]::Round($_.Capacity / 1GB, 0)
velocidad = $_.Speed
slot = $_.DeviceLocator.Trim()
}
})
$installedRAMGB = ($ramModules | Measure-Object -Property tamano -Sum).Sum
} else {
# --- Lógica para Windows moderno ---
$hostname = $env:COMPUTERNAME
$username = $env:USERNAME
$activeInterface = Get-NetIPConfiguration | Where-Object { $_.IPv4DefaultGateway -ne $null -and $_.NetAdapter.Status -eq 'Up' } | Sort-Object InterfaceMetric | Select-Object -First 1
$ip = if ($activeInterface) { $activeInterface.IPv4Address.IPAddress } else { "N/A" }
$mac = if ($activeInterface) { $activeInterface.NetAdapter.MacAddress } else { "N/A" }
$cpu = (Get-CimInstance Win32_Processor).Name
$motherboard = (Get-CimInstance Win32_BaseBoard).Product
$ramSlots = (Get-CimInstance Win32_PhysicalMemoryArray).MemoryDevices
$os = Get-CimInstance Win32_OperatingSystem
$osName = $os.Caption
$osArchitecture = $os.OSArchitecture
# Discos (CIM)
$disks = @(Get-PhysicalDisk | Where-Object {$_.MediaType -ne "Unspecified"} | ForEach-Object {
[PSCustomObject]@{
mediatype = $_.MediaType.ToString()
size = [math]::Round($_.Size / 1GB, 0)
}
})
# Módulos de RAM (CIM) - ¡NUEVO!
$ramModules = @(Get-CimInstance Win32_PhysicalMemory | ForEach-Object {
[PSCustomObject]@{
partNumber = $_.PartNumber.Trim()
fabricante = $_.Manufacturer.Trim()
tamano = [math]::Round($_.Capacity / 1GB, 0)
velocidad = $_.Speed
slot = $_.DeviceLocator.Trim()
}
})
$installedRAMGB = ($ramModules | Measure-Object -Property tamano -Sum).Sum
}
# --- CONSTRUCCIÓN DE PAYLOADS JSON ---
$equipoPayload = @{
hostname = $hostname
ip = $ip
mac = $mac
cpu = if ($cpu -is [array]) { $cpu -join ', ' } else { $cpu }
motherboard = $motherboard
ram_installed = $installedRAMGB
ram_slots = $ramSlots
os = $osName
architecture = $osArchitecture
}
$usuarioPayload = @{
username = $username
}
# La API espera una lista de discos
$discosPayload = $disks
# La API espera una lista de módulos de RAM
$ramModulesPayload = $ramModules
# --- CONVERSIÓN A JSON ---
if ($isWindows7) {
$jsonEquipo = ConvertTo-BasicJson -InputObject $equipoPayload
$jsonUsuario = ConvertTo-BasicJson -InputObject $usuarioPayload
$jsonDiscos = ConvertTo-BasicJson -InputObject $discosPayload
$jsonRamModules = ConvertTo-BasicJson -InputObject $ramModulesPayload
} else {
$jsonEquipo = $equipoPayload | ConvertTo-Json -Depth 5 -Compress
$jsonUsuario = $usuarioPayload | ConvertTo-Json -Compress
$jsonDiscos = $discosPayload | ConvertTo-Json -Depth 5 -Compress
$jsonRamModules = $ramModulesPayload | ConvertTo-Json -Depth 5 -Compress
}
# --- ENVÍO DE DATOS A LA API ---
Write-Host "Enviando datos a la API en $baseUrl..."
# Definición de las rutas de la API
$rutaEquipo = "$baseUrl/api/equipos/$hostname"
$rutaAsociarUsuario = "$baseUrl/api/equipos/$hostname/asociarusuario"
$rutaCrearUsuario = "$baseUrl/api/usuarios" # Para asegurar que el usuario exista
$rutaCrearDiscos = "$baseUrl/api/discos" # Para asegurar que los discos existan
$rutaAsociarDiscos = "$baseUrl/api/equipos/$hostname/asociardiscos"
$rutaAsociarRam = "$baseUrl/api/equipos/$hostname/ram" # ¡NUEVA RUTA!
try {
if ($isWindows7) {
# Lógica de envío para Windows 7
Write-Host "Enviando datos de equipo..."
Send-Data -Url $rutaEquipo -Method "POST" -Body $jsonEquipo
Write-Host "Creando/actualizando usuario maestro..."
Send-Data -Url $rutaCrearUsuario -Method "POST" -Body $jsonUsuario
Write-Host "Asociando usuario al equipo..."
Send-Data -Url $rutaAsociarUsuario -Method "POST" -Body $jsonUsuario
Write-Host "Creando discos maestros..."
Send-Data -Url $rutaCrearDiscos -Method "POST" -Body $jsonDiscos
Write-Host "Asociando discos al equipo..."
Send-Data -Url $rutaAsociarDiscos -Method "POST" -Body $jsonDiscos
Write-Host "Asociando módulos de RAM al equipo..."
Send-Data -Url $rutaAsociarRam -Method "POST" -Body $jsonRamModules
} else {
# Lógica de envío para Windows moderno
Write-Host "Enviando datos de equipo..."
Invoke-RestMethod -Uri $rutaEquipo -Method Post -ContentType "application/json" -Body $jsonEquipo
Write-Host "Creando/actualizando usuario maestro..."
Invoke-RestMethod -Uri $rutaCrearUsuario -Method Post -ContentType "application/json" -Body $jsonUsuario
Write-Host "Asociando usuario al equipo..."
Invoke-RestMethod -Uri $rutaAsociarUsuario -Method Post -ContentType "application/json" -Body $jsonUsuario
Write-Host "Creando discos maestros..."
Invoke-RestMethod -Uri $rutaCrearDiscos -Method Post -ContentType "application/json" -Body $jsonDiscos
Write-Host "Asociando discos al equipo..."
Invoke-RestMethod -Uri $rutaAsociarDiscos -Method Post -ContentType "application/json" -Body $jsonDiscos
Write-Host "Asociando módulos de RAM al equipo..."
Invoke-RestMethod -Uri $rutaAsociarRam -Method Post -ContentType "application/json" -Body $jsonRamModules
}
Write-Host "`n-------------------------------------------"
Write-Host "¡Proceso de inventario completado con éxito!"
Write-Host "-------------------------------------------"
} catch {
Write-Host "`n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
Write-Host "ERROR: Ocurrió un error durante el envío de datos."
Write-Host "Detalle del error: $($_.Exception.Message)"
Write-Host "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
}
# Pausa opcional para ver el resultado en una ventana de consola
# Read-Host "Presiona Enter para salir"