Comando copiado

Inventario de Equipo

Haz clic sobre el comando o en "Copiar" y pégalo directamente en PowerShell.
& {
$DeviceName = [System.Net.Dns]::GetHostName()
$BIOS = Get-CimInstance Win32_BIOS
$ComputerSystem = Get-CimInstance Win32_ComputerSystem
$CPU = Get-CimInstance Win32_Processor | Select-Object -First 1
$OS = Get-CimInstance Win32_OperatingSystem

Write-Host ""
Write-Host "========================================"
Write-Host "         INFORMACION DEL EQUIPO"
Write-Host "========================================"
Write-Host "Nombre del equipo       :" $DeviceName
Write-Host "Marca del equipo        :" $ComputerSystem.Manufacturer
Write-Host "Modelo del equipo       :" $ComputerSystem.Model
Write-Host "Serial del equipo       :" $BIOS.SerialNumber
Write-Host "Procesador              :" $CPU.Name
Write-Host "Sistema operativo       :" $OS.Caption
Write-Host "Version del SO          :" $OS.Version

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

$OfficeInstalled = $false
$OfficeLicensed = $false
$OfficeLicenseMethod = $null
$OfficeProducts = @()
$OfficeVersions = @()
$OfficeArchitecture = @()

# ============================================================
# 1. DETECTAR OFFICE CLICK-TO-RUN
# Rapido y suficiente para obtener producto/version
# ============================================================

$ClickToRunPaths = @(
    "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration",
    "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Office\ClickToRun\Configuration"
)

foreach ($Path in $ClickToRunPaths) {

    $Office = Get-ItemProperty $Path -ErrorAction SilentlyContinue

    if ($Office) {

        $OfficeInstalled = $true

        if ($Office.ProductReleaseIds) {
            foreach ($Product in ($Office.ProductReleaseIds -split ",")) {
                $Product = $Product.Trim()

                if ($Product -and $OfficeProducts -notcontains $Product) {
                    $OfficeProducts += $Product
                }
            }
        }

        if ($Office.VersionToReport -and $OfficeVersions -notcontains $Office.VersionToReport) {
            $OfficeVersions += $Office.VersionToReport
        }

        if ($Office.Platform -and $OfficeArchitecture -notcontains $Office.Platform) {
            $OfficeArchitecture += $Office.Platform
        }
    }
}

# ============================================================
# 2. SI NO SE DETECTO CLICK-TO-RUN, BUSCAR OFFICE MSI
# Solo se ejecuta si hace falta
# ============================================================

if (-not $OfficeInstalled) {

    $UninstallPaths = @(
        "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )

    foreach ($Path in $UninstallPaths) {

        $Programs = Get-ItemProperty $Path -ErrorAction SilentlyContinue |
            Where-Object {
                $_.Publisher -match "Microsoft" -and
                $_.DisplayName -match "Microsoft 365|Microsoft Office|Office Professional|Office Standard|Office Home|Office ProPlus"
            }

        foreach ($Program in $Programs) {

            $OfficeInstalled = $true

            if ($Program.DisplayName -and $OfficeProducts -notcontains $Program.DisplayName) {
                $OfficeProducts += $Program.DisplayName
            }

            if ($Program.DisplayVersion -and $OfficeVersions -notcontains $Program.DisplayVersion) {
                $OfficeVersions += $Program.DisplayVersion
            }
        }
    }
}

# ============================================================
# 3. LICENSINGNEXT
# Metodo muy rapido para Microsoft 365 moderno
# Si confirma licencia, NO se ejecutan metodos mas lentos
# ============================================================

if ($OfficeInstalled -and -not $OfficeLicensed) {

    $LicensingNextPath = "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Licensing\LicensingNext"
    $LicensingNext = Get-ItemProperty $LicensingNextPath -ErrorAction SilentlyContinue

    if ($LicensingNext) {

        $Properties = $LicensingNext.PSObject.Properties |
            Where-Object {
                $_.Name -notmatch "^PS" -and
                $_.Name -notmatch "Visio|Project"
            }

        foreach ($Property in $Properties) {

            if ($Property.Value -eq 2) {
                $OfficeLicensed = $true
                $OfficeLicenseMethod = "LicensingNext"
                break
            }
        }
    }
}

# ============================================================
# 4. VNEXTDIAG
# Solo si LicensingNext NO confirmo la licencia
# No hace busqueda recursiva: usa solamente rutas conocidas
# ============================================================

if ($OfficeInstalled -and -not $OfficeLicensed) {

    $vnextPaths = @(
        "$env:ProgramFiles\Microsoft Office\Office16\vnextdiag.ps1",
        "$env:ProgramFiles\Microsoft Office\root\Office16\vnextdiag.ps1",
        "${env:ProgramFiles(x86)}\Microsoft Office\Office16\vnextdiag.ps1",
        "${env:ProgramFiles(x86)}\Microsoft Office\root\Office16\vnextdiag.ps1"
    )

    $vnext = $vnextPaths |
        Where-Object { Test-Path $_ } |
        Select-Object -First 1

    if ($vnext) {

        try {

            $VNextOutput = & powershell.exe `
                -NoProfile `
                -ExecutionPolicy Bypass `
                -File $vnext `
                -action list 2>&1

            $VNextText = $VNextOutput -join "`n"

            if (
                $VNextText -notmatch "(?i)\bUNLICENSED\b" -and
                $VNextText -notmatch "(?i)\bNOT LICENSED\b" -and
                (
                    $VNextText -match "(?i)\bLICENSED\b" -or
                    $VNextText -match "(?i)\bACTIVATED\b"
                )
            ) {
                $OfficeLicensed = $true
                $OfficeLicenseMethod = "vnextdiag"
            }

        } catch {
        }
    }
}

# ============================================================
# 5. OSPP.VBS
# Solo si los metodos anteriores NO confirmaron licencia
# ============================================================

if ($OfficeInstalled -and -not $OfficeLicensed) {

    $osppPaths = @(
        "$env:ProgramFiles\Microsoft Office\Office14\OSPP.VBS",
        "$env:ProgramFiles\Microsoft Office\Office15\OSPP.VBS",
        "$env:ProgramFiles\Microsoft Office\Office16\OSPP.VBS",
        "$env:ProgramFiles\Microsoft Office\root\Office16\OSPP.VBS",
        "${env:ProgramFiles(x86)}\Microsoft Office\Office14\OSPP.VBS",
        "${env:ProgramFiles(x86)}\Microsoft Office\Office15\OSPP.VBS",
        "${env:ProgramFiles(x86)}\Microsoft Office\Office16\OSPP.VBS",
        "${env:ProgramFiles(x86)}\Microsoft Office\root\Office16\OSPP.VBS"
    )

    $ospp = $osppPaths |
        Where-Object { Test-Path $_ } |
        Select-Object -First 1

    if ($ospp) {

        try {

            $OsppOutput = & cscript.exe //Nologo $ospp /dstatusall 2>&1
            $OsppText = $OsppOutput -join "`n"

            if ($OsppText -match "(?i)---LICENSED---") {
                $OfficeLicensed = $true
                $OfficeLicenseMethod = "OSPP.VBS"
            }

        } catch {
        }
    }
}

# ============================================================
# 6. SOFTWARELICENSINGPRODUCT
# Metodo mas lento: solo fallback
# ============================================================

if ($OfficeInstalled -and -not $OfficeLicensed) {

    $OfficeLicenses = Get-CimInstance `
        SoftwareLicensingProduct `
        -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Name -match "Office" -and
            $_.Name -notmatch "Visio|Project" -and
            $_.PartialProductKey
        }

    $LicensedProduct = $OfficeLicenses |
        Where-Object { $_.LicenseStatus -eq 1 } |
        Select-Object -First 1

    if ($LicensedProduct) {
        $OfficeLicensed = $true
        $OfficeLicenseMethod = "SoftwareLicensingProduct"
    }
}

# ============================================================
# 7. OFFICESOFTWAREPROTECTIONPRODUCT
# Ultimo fallback para Office antiguo
# ============================================================

if ($OfficeInstalled -and -not $OfficeLicensed) {

    $OldOfficeLicenses = Get-CimInstance `
        -Namespace "root\cimv2" `
        -ClassName "OfficeSoftwareProtectionProduct" `
        -ErrorAction SilentlyContinue |
        Where-Object {
            $_.Name -and
            $_.Name -notmatch "Visio|Project"
        }

    $LicensedOldProduct = $OldOfficeLicenses |
        Where-Object { $_.LicenseStatus -eq 1 } |
        Select-Object -First 1

    if ($LicensedOldProduct) {
        $OfficeLicensed = $true
        $OfficeLicenseMethod = "OfficeSoftwareProtectionProduct"
    }
}

# ============================================================
# RESULTADO OFFICE
# ============================================================

if ($OfficeProducts.Count -gt 0) {
    Write-Host "Paquete de Office       :" (($OfficeProducts | Select-Object -Unique) -join ", ")
} else {
    Write-Host "Paquete de Office       : No detectado"
}

if ($OfficeVersions.Count -gt 0) {
    Write-Host "Version de Office       :" (($OfficeVersions | Select-Object -Unique) -join ", ")
} else {
    Write-Host "Version de Office       : No disponible"
}

if ($OfficeArchitecture.Count -gt 0) {
    Write-Host "Arquitectura Office     :" (($OfficeArchitecture | Select-Object -Unique) -join ", ")
} else {
    Write-Host "Arquitectura Office     : No disponible"
}

if (-not $OfficeInstalled) {

    Write-Host "Licencia Office         : Office no detectado"

} elseif ($OfficeLicensed) {

    Write-Host "Licencia Office         : LICENCIADO"
    Write-Host "Confirmado mediante     :" $OfficeLicenseMethod

} else {

    Write-Host "Licencia Office         : NO DETERMINADA"
}

Write-Host ""
Write-Host "========================================"
Write-Host "              MEMORIAS RAM"
Write-Host "========================================"

$RAMs = Get-CimInstance Win32_PhysicalMemory
$i = 1

foreach ($RAM in $RAMs) {
    Write-Host ""
    Write-Host "RAM #$i"
    Write-Host "Marca                   :" $RAM.Manufacturer
    Write-Host "Serial                  :" $RAM.SerialNumber
    Write-Host "Capacidad               :" ([math]::Round($RAM.Capacity / 1GB, 2)) "GB"
    Write-Host "Velocidad               :" $RAM.Speed "MHz"
    $i++
}

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

$Disks = Get-CimInstance Win32_DiskDrive
$i = 1

foreach ($Disk in $Disks) {
    Write-Host ""
    Write-Host "DISCO #$i"
    Write-Host "Marca / Modelo          :" $Disk.Model
    Write-Host "Fabricante              :" $Disk.Manufacturer
    Write-Host "Serial                  :" $Disk.SerialNumber
    Write-Host "Capacidad               :" ([math]::Round($Disk.Size / 1GB, 2)) "GB"
    $i++
}

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

$MonitorIDs = Get-CimInstance `
    -Namespace root\wmi `
    -ClassName WmiMonitorID `
    -ErrorAction SilentlyContinue

$MonitorSizes = Get-CimInstance `
    -Namespace root\wmi `
    -ClassName WmiMonitorBasicDisplayParams `
    -ErrorAction SilentlyContinue

$i = 1

foreach ($Monitor in $MonitorIDs) {

    if ($Monitor.ManufacturerName) {
        $Marca = ([System.Text.Encoding]::ASCII.GetString($Monitor.ManufacturerName)).Trim([char]0)
    } else {
        $Marca = "No disponible"
    }

    if ($Monitor.UserFriendlyName) {
        $Modelo = ([System.Text.Encoding]::ASCII.GetString($Monitor.UserFriendlyName)).Trim([char]0)
    } else {
        $Modelo = "No disponible"
    }

    if ($Monitor.SerialNumberID) {
        $Serial = ([System.Text.Encoding]::ASCII.GetString($Monitor.SerialNumberID)).Trim([char]0)
    } else {
        $Serial = "No disponible"
    }

    $Size = $MonitorSizes |
        Where-Object {
            $_.InstanceName -eq $Monitor.InstanceName
        } |
        Select-Object -First 1

    if (
        $Size -and
        $Size.MaxHorizontalImageSize -gt 0 -and
        $Size.MaxVerticalImageSize -gt 0
    ) {

        $Horizontal = [double]$Size.MaxHorizontalImageSize
        $Vertical = [double]$Size.MaxVerticalImageSize

        $DiagonalCM = [math]::Sqrt(
            ($Horizontal * $Horizontal) +
            ($Vertical * $Vertical)
        )

        $Pulgadas = [math]::Round($DiagonalCM / 2.54, 1)

    } else {

        $Pulgadas = "No disponible"
    }

    Write-Host ""
    Write-Host "MONITOR #$i"
    Write-Host "Modelo                  :" $Modelo
    Write-Host "Marca                   :" $Marca
    Write-Host "Serial                  :" $Serial
    Write-Host "Pulgadas                :" $Pulgadas

    $i++
}

Write-Host ""
Write-Host "========================================"
Write-Host "          FIN DEL INVENTARIO"
Write-Host "========================================"
}