Mike Wilcock - WebHelp
PowerShell Device Report
Example Code > PowerShell Scripts > PowerShell Device Report

The following PowerShell script generates a PowerShell device report which lists various details of the machine on which it is executed. These details include information such as installed drives, printers, RAM and software. The code also allows you to optionally export the device report as an .xml file.

The .ps1 code is presented below; The code has been tested and works on Windows 10/11.

#----------------------------------------------------------------------------#
# Program Copyright    : Mike Wilcock.
# Program Name         : device-report.ps1.
#----------------------------------------------------------------------------#
# Program Created      : 3rd July 2021.
# Program Code Type    : PowerShell Script (version 5.1.19041.1023).
# Author               : Michael Wilcock, IT Technician.
# Version              : 1.01
#----------------------------------------------------------------------------#
# Purpose              : Generate a device report and optionally export to xml.
#----------------------------------------------------------------------------#

clear screen

# Promt user?
$user_conf = read-host "Run Device Report - [Y/N]"

# User bailed! :-(
if($user_conf -ne "Y")
{
    clear screen
    break
}

clear screen

write-host "Getting Computer Information - Please Wait."

# Get computer infomation object.
$oCompInf = Get-ComputerInfo

write-host "Getting Disk Information - Please Wait."

# Get physical disk information object
$oPhyDisks = Get-PhysicalDisk

write-host "Getting Printer Information - Please Wait."

# Get installed printers object.
$oPrinters = Get-Printer

write-host "Getting Installed Software Information - Please Wait."

# Get installed software object.
$oInstalledCode = Get-WmiObject -Class Win32_Product | Sort-Object Name, Version

#----------------------------------------------------------------------------#
# Machine overview.
#----------------------------------------------------------------------------#

# Store required data in memory.
$cHostname = ($oCompInf).CsDNSHostName
$cManufacturer = ($oCompInf).CsManufacturer
$cModel = ($oCompInf).CsModel
$cDomain = ($oCompInf).CsDomain
$nTotMem = ($oCompInf).OsTotalVisibleMemorySize / (1024 * 1024) # kilobytes to gigabytes conversion.
$nInstMem = ($oCompInf).CsPhyicallyInstalledMemory / (1024 * 1024) # kilobytes to gigabytes conversion.
$cProdName = ($oCompInf).WindowsProductName
$cWinVer = ($oCompInf).WindowsVersion
$cOSVer = ($oCompInf).OsVersion
$cOSArch = ($oCompInf).OsArchitecture
$cOSInstDate = ($oCompInf).OsInstallDate
$cOSBootDev = ($oCompInf).OsBootDevice
$cBIOSMan = ($oCompInf).BiosManufacturer
$cBIOSName = ($oCompInf).BiosName
$cBIOSVer = ($oCompInf).BiosVersion
$cBIOSDate = ($oCompInf).BiosReleaseDate
$lMemWarning = $false
$lDriveWarning = $false
$cNl = "`r`n"

# Device installed memory is <= 4GB!
if($nInstMem -le 4)
{
    $lMemWarning = $true
}

clear screen

write-host "---------------------------------------------------------"
write-host "Device Report"
write-host "---------------------------------------------------------"
write-host ""
write-host "---------------------------------------------------------"
write-host "MACHINE OVERVIEW"
write-host "---------------------------------------------------------"
write-host ""
write-host "Host Name             : " $cHostname
write-host "Domain                : " $cDomain
write-host ""
write-host "Device Manufacturer   : " $cManufacturer
write-host "Device Model          : " $cModel
write-host "Visible Memory        : " $nTotMem "GB"

# RAM needs upgrading.
if($lMemWarning)
{
    write-host "Installed Memory      : " $nInstMem "GB - WARNING!"
}
# Ok.
else
{
    write-host "Installed Memory      : " $nInstMem "GB"
}

write-host "Windows Product Name  : " $cProdName
write-host "Windows Version       : " $cWinVer
write-host "OS Version            : " $cOSVer
write-host "OS Architecture       : " $cOsArch
write-host "OS Install Date       : " $cOSInstDate
write-host "OS Boot Device        : " $cOSBootDev
write-host ""
write-host "BIOS Manufacturer     : " $cBIOSMan
write-host "BIOS Name             : " $cBIOSName
write-host "BIOS Version          : " $cBIOSVer
write-host "BIOS Release Date     : " $cBIOSDate

#----------------------------------------------------------------------------#
# Installed disk drives.
#----------------------------------------------------------------------------#

write-host ""
write-host "---------------------------------------------------------"
write-host "INSTALLED DRIVES"
write-host "---------------------------------------------------------"
write-host ""
write-host " ID Type Name                                           Size Message"
write-host "--- ---- ------------------------------- ------------------- --------"

# Loop through each installed disk drive.
ForEach ($n in $oPhyDisks)
{
    $dID = [string]($n).DeviceId
    $dType = [string]($n).MediaType
    $dAllocSize = [string]($n).AllocatedSize
    $dFName = [string]($n).FriendlyName

    # Device is a Hard Drive.
    if($dType -eq "HDD")
    {
        $dMessage = "WARNING!"
       
        # update boolean variable.
        $lDriveWarning = $true
    }
    # SSD.
    else
    {
        $dMessage = "Ok"
    }

    # Output to console.
    write-host $dID.PadLeft(3, " ") $dType.PadRight(4, " ") $dFName.PadRight(30, " ") $dAllocSize.PadLeft(20, " ") $dMessage
}

#----------------------------------------------------------------------------#
# Installed printers.
#----------------------------------------------------------------------------#

write-host ""
write-host "---------------------------------------------------------"
write-host "INSTALLED PRINTERS"
write-host "---------------------------------------------------------"
write-host ""
write-host "Name                           Type       Driver Name                   "
write-host "------------------------------ ---------- ------------------------------"

# Loop through each installed printer.
ForEach ($n in $oPrinters)
{
    $pName = [string]($n).Name
    $pDriverName = [string]($n).DriverName
    $pType = [string]($n).Type
    $pPort = [string]($n).PortName

    # Output to console.
    write-host $pName.PadRight(30, " ") $pType.PadRight(10, " ") $pDriverName
}

#----------------------------------------------------------------------------#
# Installed software.
#----------------------------------------------------------------------------#

write-host ""
write-host "---------------------------------------------------------"
write-host "INSTALLED SOFTWARE"
write-host "---------------------------------------------------------"
write-host ""
write-host "Name                                          Vendor                         Version              Install Date"
write-host "--------------------------------------------- ------------------------------ -------------------- ------------"

# Loop through each installed application.
ForEach ($n in $oInstalledCode)
{
    $sName = [string]($n).Name
    $sVendor = [string]($n).Vendor
    $sVersion = [string]($n).Version
    $sInstDate = [string]($n).InstallDate

    # Output to console.
    write-host "$sName $(" " * 45)".Substring(0,45) "$sVendor $(" " * 30)".Substring(0,30) "$sVersion $(" " * 20)".Substring(0,20) $sInstDate
}

write-host ""
write-host "---------------------------------------------------------"
write-host "Script Completed Successfully"
write-host "---------------------------------------------------------"
write-host ""

# Installed memory <= 4GB!
if($lMemWarning)
{
    write-host "WARNING - Device Has 4GB Of Memory Or Less."
}

# At least 1 HDD Installed!
if($lDriveWarning)
{
    write-host "WARNING - Device Has At Least One HDD Installed."
}

# Line Space.  Keep things tidy!
if($lMemWarning -Or $lDriveWarning)
{
    write-host ""
}

# Promt user?
$user_conf = read-host "Output Device Report As An XML File? - [Y/N]"

# Generate xml document.
if($user_conf -eq "Y")
{
    $cDateTime = Get-Date -Format "dd-MM-yyyy-HH-mm-ss"

    # Initialise XML string.
    $cOutFile = '<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>'

    # Start append.
    $cOutFile += ("<" + $cHostname + ">" + $cNl)
    $cOutFile += ("    <device_overview>" + $cNl)
    $cOutFile += ("        <hostname>" + $cHostname + "</hostname>" + $cNl)
    $cOutFile += ("        <domain>" + $cDomain + "</domain>" + $cNl)
    $cOutFile += ("        <device_manufacturer>" + $cManufacturer + "</device_manufacturer>" + $cNl)
    $cOutFile += ("        <device_model>" + $cModel + "</device_model>" + $cNl)
    $cOutFile += ("        <visible_memory>" + $nTotMem + "</visible_memory>" + $cNl)
    $cOutFile += ("        <installed_memory>" + $nInstMem + "</installed_memory>" + $cNl)
    $cOutFile += ("        <windows_product_name>" + $cProdname + "</windows_product_name>" + $cNl)
    $cOutFile += ("        <windows_version>" + $cWinVer + "</windows_version>" + $cNl)
    $cOutFile += ("        <os_version>" + $cOSVer + "</os_version>" + $cNl)
    $cOutFile += ("        <os_architecture>" + $cOSArch + "</os_architecture>" + $cNl)
    $cOutFile += ("        <os_install_date>" + $cOSInstDate + "</os_install_date>" + $cNl)
    $cOutFile += ("        <os_boot_device>" + $cOSBootDev + "</os_boot_device>" + $cNl)
    $cOutFile += ("        <bios_manufacturer>" + $cBIOSMan + "</bios_manufacturer>" + $cNl)
    $cOutFile += ("        <bios_name>" + $cBIOSNAme + "</bios_name>" + $cNl)
    $cOutFile += ("        <bios_version>" + $cBIOSVer + "</bios_version>" + $cNl)
    $cOutFile += ("        <bios_release_date>" + $cBIOSDate + "</bios_release_date>" + $cNl)
    $cOutFile += ("    </device_overview>" + $cNl)
   
    # Installed disk drives.
    $cOutFile += ("    <installed_drives>" + $cNl)
   
    # Loop counter.
    $nCount = 0

    # Loop through each installed disk drive.
    ForEach ($n in $oPhyDisks)
    {
        $dID = [string]($n).DeviceId
        $dType = [string]($n).MediaType
        $dAllocSize = [string]($n).AllocatedSize
        $dFName = [string]($n).FriendlyName

        # Device is a Hard Drive.
        if($dType -eq "HDD")
        {
            $dMessage = "WARNING!"
        }
        # SSD.
        else
        {
            $dMessage = "Ok"
        }

        $cOutFile += ("        <drive" + $nCount + ">" + $cNl)
        $cOutFile += ("            <drive_id>" + $dID + "</drive_id>" + $cNl)
        $cOutFile += ("            <drive_type>" + $dType + "</drive_type>" + $cNl)
        $cOutFile += ("            <drive_size>" + $dAllocSize + "</drive_size>" + $cNl)
        $cOutFile += ("            <drive_name>" + $dFName + "</drive_name>" + $cNl)
        $cOutFile += ("        </drive" + $nCount + ">" + $cNl)
       
        # Increment loop counter.
        $nCount++
    }

    $cOutFile += ("    </installed_drives>" + $cNl)

    # Installed printers.
    $cOutFile += ("    <installed_printers>" + $cNl)

    # Loop counter.
    $nCount = 0

    # Loop through each installed printer.
    ForEach ($n in $oPrinters)
    {
        $pName = [string]($n).Name
        $pDriverName = [string]($n).DriverName
        $pType = [string]($n).Type
        $pPort = [string]($n).PortName

        # XML does not like the & sign.  This is an extremely "industrial" way of getting around this problem.
        $pName = $pName.Replace("&", "&amp;")
        $pDriverName = $pDriverName.Replace("&", "&amp;")

        $cOutFile += ("        <printer" + $nCount + ">" + $cNl)
        $cOutFile += ("            <printer_name>" + $pName + "</printer_name>" + $cNl)
        $cOutFile += ("            <printer_driver_name>" + $pDriverName + "</printer_driver_name>" + $cNl)
        $cOutFile += ("            <printer_type>" + $pType + "</printer_type>" + $cNl)
        $cOutFile += ("            <printer_port>" + $pPort + "</printer_port>" + $cNl)
        $cOutFile += ("        </printer" + $nCount + ">" + $cNl)

        # Increment loop counter.
        $nCount++
    }

    $cOutFile += ("    </installed_printers>" + $cNl)

    # Installed software.
    $cOutFile += ("    <installed_software>" + $cNl)

    # Loop counter.
    $nCount = 0

    # Loop through each installed application.
    ForEach ($n in $oInstalledCode)
    {
        $sName = [string]($n).Name
        $sVendor = [string]($n).Vendor
        $sVersion = [string]($n).Version
        $sInstDate = [string]($n).InstallDate

        # XML does not like the & sign.  This is an extremely "industrial" way of getting around this problem.
        $sName = $sName.Replace("&", "&amp;")
        $sVendor = $sVendor.Replace("&", "&amp;")

        $cOutFile += ("        <application" + $nCount + ">" + $cNl)
        $cOutFile += ("            <application_name>" + $sName + "</application_name>" + $cNl)
        $cOutFile += ("            <application_vendor>" + $sVendor + "</application_vendor>" + $cNl)
        $cOutFile += ("            <application_version>" + $sVersion + "</application_version>" + $cNl)
        $cOutFile += ("            <application_install_date>" + $sInstDate + "</application_install_date>" + $cNl)
        $cOutFile += ("        </application" + $nCount + ">" + $cNl)

        # Increment loop counter.
        $nCount++
    }

    $cOutFile += ("    </installed_software>" + $cNl)
   
    # EOF :-).
    $cOutFile += ("</" + $cHostname + ">")

    # Write XML data to disk.
    Set-Content -Path ($PSScriptRoot + "\" + $cHostname + " - " + $cDateTime + ".xml") -Value $cOutFile
}
See Also