Feat: PS1 Añadido - Fix: Eliminación de Equipos
This commit is contained in:
		| @@ -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(); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -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")] | ||||||
|   | |||||||
| @@ -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
									
								
							
							
						
						
									
										248
									
								
								getDatosPost.ps1
									
									
									
									
									
										Normal 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" | ||||||
		Reference in New Issue
	
	Block a user