• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Stephanos Constantinou Blog

PowerShell Scripting

  • Home
  • Blogs
    • PowerShell Tutorials
    • PowerShell Scripts
    • PowerShell Modules
      • Modules Cmdlets
    • Software Reviews
  • About
  • Contact
You are here: Home / PowerShell Scripts / PowerShell Hardware Inventory Script

PowerShell Hardware Inventory Script

13/02/2018 by Stephanos 8 Comments

PowerShell Hardware Inventory Script

Scenario:

PowerShell hardware Inventory Script.

Have you ever wanted to have an inventory without the hassle of going to each finding the information needed to fill the information for your inventory? It is important to keep your inventory up to date. Every time there is a change you will need to update also your inventory. As much information you have in your inventory the easiest will be when you will need this information. I came up with the below script just for a basic inventory with information to be taken automatically. In general the script will connect to all computers in the network and gather the information needed.

Lets see in more detail

The first part of the script is only the description and help information of the script that can be retrieved by using Get-Help command. Then, the script starts doing the actual work. An empty array list is created that we will fill it through the process. After the array will be created the script will connect to Active Directory and get all computer names to create the list that will be used to retrieve the information for each one. When we will have the list then we will go through a loop to gather the information. The first step is to check if there is a connection to the computer. If the connection is OK the script with will connect to the computer for the information. Before connecting to the computer, we are creating an object to keep the information and then we will add the values to the array list.

Operating System and Service Pack, are retrieved from Active Directory so there is no problem whether we have a connection to the computer or not. So before we start the process and after the creation of the object we get the information for Operating System and Service Pack. We keep them in variables to be used later and the moving forwarding to get the rest of the information if the connection test was successful.

Loop through the list

As you can see on the first command the we will get the manufacturer of the computer, model, number of processors and RAM. Ad you will noticed for RAM we have a small expression. This expression will get process the information of RAM as it is retried in Bytes and converts it in GB. Using the second command we will get the information about CPU. Actually we keep the CPU ID, manufacturer of CPU, name of CPU, number of cores and number of logical processors. The third command will retrieve the information about disks. We will save their Drive Letter, Name (if it exists) and size. As you can see again, an expression is used to convert the size of the drive in GB. Now we have finished with the collection of the information we need for this computer and we will proceed to add those values in our object that we have created before. 

Before we will add the information to the object, we save each property on a different variable so it will be easier for to be used on the next commands. So as you will see a block of commands is only about saving the property values to variables. After that we use those variables and we fill the object with those properties. When the object is ready, the object is added in the array list so we will be able to continue with the next computer. As you can see also, after adding the object to the array, we set three variable to null. The reason we are doing this is to be ready for the next computer. If the next computer is not reachable, or we are not able to connect due to issue with WMI, then we do not want the property values of the previous computer to be added in this one. With this way we ensure that the variables are always empty.

Reporting

After the loop has been completed and processed all computer names in the list, we array list is filled with the values / properties of each one. Then we are exporting this array list to a csv file. As this a basic script with basic functionality, there are some minor things that you need to know for the values. We aim is to create a basic inventory and not a fully functional inventory. There are some values that you might consider to edit, so our inventory will be more readable. One of the values are the drive letters, if there are more that one drive in the computer. All drive letters are under the same cell in Microsoft Excel. There are some of you that you might want to add more columns and separate them. The second value that you need notice is RAM. You will see that RAM value has a lot of decimal places. You need to change the format of this column, so the numbers will not have any decimal places.

The last value that you need to check is the size of the drive. We have a combination of the 2 previous cases. All sizes appear in the same cell in Microsoft Excel but in the same order as the drive letters. The numbers have a lot of decimal places again so you will need to removed change the format of the cells so that they will not contain any decimal places. In the case that the are 2 size values in the same cell, then you have to separate the 2 values, so the removal of decimal places will work.

Permissions

Last thing that I have to mention so this script will work. The user that will run the script, needs to have at least read permission on Computer Objects in Active Directory for the Name, OperatingSystem, OperatingSystemServicePack attributes. Now in relation to the permissions needed for computers, the user needs WMI permissions on each computer so it will run smoothly. If the user does not have permission for Active Directory then the script will not be able to retrieve the computer names. If the user does not have WMI permissions on a computer then the script will throw errors for each computer that the users does not have permissions.

You can download the script here or copy it from below.

Hope you like it. If you have any questions or anything else please let me know in the comments below.

Related Links:

  • PowerShell script to get computer information
  • How to get remote system information – Part 3
  • PowerShell Hardware Inventory Script – Part 2
  • New-Object – Microsoft Docs
  • Test-Connection – Microsoft Docs
  • Get-ADComputer – Microsoft Docs
  • Add-Member – Microsoft Docs
  • Get-WmiObject – Microsoft Docs
  • Out-Null – Microsoft Docs
  • Export-Csv – Microsoft Docs
  • Get-Help – Microsoft Docs

Solution / Script:

<#
.SYNOPSIS
  Name: Get-Inventory.ps1
  The purpose of this script is to create a simple inventory.
.DESCRIPTION
  This is a simple script to retrieve all computer objects in Active Directory and then connect
  to each one and gather basic hardware information using WMI. The information includes Manufacturer,
  Model, CPU, RAM, Disks and Operating System.
.RELATED LINKS
  
Home
.NOTES Release Date: 10-02-2018 Author: Stephanos Constantinou .EXAMPLE Get-Inventory.ps1 Find the output under C:\Scripts_Output #> $Inventory = New-Object System.Collections.ArrayList $AllComputers = Get-ADComputer -Filter * -Properties Name $AllComputersNames = $AllComputers.Name Foreach ($ComputerName in $AllComputersNames) { $Connection = Test-Connection $ComputerName -Count 1 -Quiet $ComputerInfo = New-Object System.Object $ComputerOS = Get-ADComputer $ComputerName -Properties OperatingSystem,OperatingSystemServicePack $ComputerInfoOperatingSystem = $ComputerOS.OperatingSystem $ComputerInfoOperatingSystemServicePack = $ComputerOS.OperatingSystemServicePack $ComputerInfo | Add-Member -MemberType NoteProperty -Name "Name" -Value "$ComputerName" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "OperatingSystem" -Value $ComputerInfoOperatingSystem $ComputerInfo | Add-Member -MemberType NoteProperty -Name "ServicePack" -Value $ComputerInfoOperatingSystemServicePack if ($Connection -eq "True"){ $ComputerHW = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $ComputerName | select Manufacturer,Model,NumberOfProcessors,@{Expression={$_.TotalPhysicalMemory / 1GB};Label="TotalPhysicalMemoryGB"} $ComputerCPU = Get-WmiObject win32_processor -ComputerName $ComputerName | select DeviceID,Name,Manufacturer,NumberOfCores,NumberOfLogicalProcessors $ComputerDisks = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" -ComputerName $ComputerName | select DeviceID,VolumeName,@{Expression={$_.Size / 1GB};Label="SizeGB"} $ComputerInfoManufacturer = $ComputerHW.Manufacturer $ComputerInfoModel = $ComputerHW.Model $ComputerInfoNumberOfProcessors = $ComputerHW.NumberOfProcessors $ComputerInfoProcessorID = $ComputerCPU.DeviceID $ComputerInfoProcessorManufacturer = $ComputerCPU.Manufacturer $ComputerInfoProcessorName = $ComputerCPU.Name $ComputerInfoNumberOfCores = $ComputerCPU.NumberOfCores $ComputerInfoNumberOfLogicalProcessors = $ComputerCPU.NumberOfLogicalProcessors $ComputerInfoRAM = $ComputerHW.TotalPhysicalMemoryGB $ComputerInfoDiskDrive = $ComputerDisks.DeviceID $ComputerInfoDriveName = $ComputerDisks.VolumeName $ComputerInfoSize = $ComputerDisks.SizeGB $ComputerInfo | Add-Member -MemberType NoteProperty -Name "Manufacturer" -Value "$ComputerInfoManufacturer" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "Model" -Value "$ComputerInfoModel" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "NumberOfProcessors" -Value "$ComputerInfoNumberOfProcessors" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "ProcessorID" -Value "$ComputerInfoProcessorID" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "ProcessorManufacturer" -Value "$ComputerInfoProcessorManufacturer" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "ProcessorName" -Value "$ComputerInfoProcessorName" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "NumberOfCores" -Value "$ComputerInfoNumberOfCores" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "NumberOfLogicalProcessors" -Value "$ComputerInfoNumberOfLogicalProcessors" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "RAM" -Value "$ComputerInfoRAM" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "DiskDrive" -Value "$ComputerInfoDiskDrive" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "DriveName" -Value "$ComputerInfoDriveName" -Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "Size" -Value "$ComputerInfoSize"-Force } $Inventory.Add($ComputerInfo) | Out-Null $ComputerHW = "" $ComputerCPU = "" $ComputerDisks = "" } $Inventory | Export-Csv C:\Scripts_Output\Inventory.csv

Filed Under: PowerShell Scripts Tagged With: Add-Member, Export-Csv, Get-ADComputer, Get-Help, Get-WmiObject, New-Object, Out-Null, Test-Connection, Win32_ComputerSystem, Win32_LogicalDisk, Win32_Processor

Reader Interactions

Comments

  1. Maciej says

    10/05/2018 at 15:30

    Thanks for posting PS, will get a good use out of it.

    I’d probably add below to also grab bios info which is mostly useless but contains the serial number of the machine which can be good for lease tracking etc.

    $ComputerBios = get-ciminstance win32_bios -ComputerName $ComputerName | select SMBIOSBIOSVersion,Manufacturer,Name,SerialNumber,Version,PSComputerName

    $ComputerInfo | Add-Member -MemberType NoteProperty -Name “SMBios Version” -Value “$ComputerInfoBiosSMBIOSBIOSVersion”-Force
    $ComputerInfo | Add-Member -MemberType NoteProperty -Name “Bios Manufacturer” -Value “$ComputerInfoBiosManufacturer”-Force
    $ComputerInfo | Add-Member -MemberType NoteProperty -Name “Bios Name” -Value “$ComputerInfoBiosName”-Force
    $ComputerInfo | Add-Member -MemberType NoteProperty -Name “Bios Version” -Value “$ComputerInfoBiosVersion”-Force
    $ComputerInfo | Add-Member -MemberType NoteProperty -Name “Bios PSComputerName” -Value “$ComputerInfoBiosPSComputerName”-Force

    Reply
    • Stephanos says

      14/05/2018 at 11:19

      Dear Maciej,

      Thank you for your comments. I am looking into this script to add more features and information. I will post accordingly.

      Thanks
      Stephanos

      Reply
  2. Roberto Sitzia says

    30/05/2018 at 18:58

    Hi Stephanos,

    I really appreciate your work, well done!
    Just a question: I ran the script on my domain controller running Windows Server 2012 64 bit but for every PC (15 Windows 7 Professional 64 bit and 3 Windows 10 Professional 64 bit) I got same 3 errors

    Get-WmiObject : Server RPC non disponibile. (Eccezione da HRESULT: 0x800706BA)
    In C:\demo\Get-Inventory.ps1:46 car:21
    + $ComputerHW = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Com …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Get-WmiObject : Server RPC non disponibile. (Eccezione da HRESULT: 0x800706BA)
    In C:\demo\Get-Inventory.ps1:47 car:22
    + $ComputerCPU = Get-WmiObject win32_processor -ComputerName $ComputerName | …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Get-WmiObject : Server RPC non disponibile. (Eccezione da HRESULT: 0x800706BA)
    In C:\demo\Get-Inventory.ps1:48 car:24
    + $ComputerDisks = Get-WmiObject -Class Win32_LogicalDisk -Filter “DriveType …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Could be so kind to help me solving this issue?

    Thank you in advance
    Roberto

    Reply
    • Stephanos says

      31/05/2018 at 12:14

      Hi Roberto,

      Have you checked WMI is enabled on every PC? In order to establish a connection with the remote PCs you need to enable WinRM. You can run the below command to see if the service is running and if not enable it and try again.

      Get-Service winrm

      Thanks
      Stephanos

      Reply
  3. Yair Millenbach says

    17/10/2018 at 11:37

    Hi Stephanos,

    Great script and thanks very much for posting it.
    A question though. When trying it out I keep getting an error on getting the computer name in $Connection = Test-Connection $ComputerName -Count 1 -Quiet because the argument is null or empty
    and thus also in $ComputerOS = Get-ADComputer $ComputerName -Properties OperatingSystem,OperatingSystemServicePack because the argument is null.

    Running from the DC, and trying each line as stand alone, I get a result.

    Any ideas?

    Thanks!

    Reply
  4. Stephanos says

    18/10/2018 at 19:03

    Hi Yair,

    Have you tried to get the list of computers from AD on the PC that you have the problem?

    Thanks
    Stephanos

    Reply
  5. Jakub says

    17/09/2020 at 13:15

    Hi Stephanos,
    It’s great script, helps a lot.
    I was wondering if this could query two domains ?

    Reply

Trackbacks

  1. PowerShell Hardware Inventory Script - How to Code .NET says:
    13/02/2018 at 19:01

    […] on February 12, 2018 submitted by /u/SConstantinou [link] [comments] Leave a […]

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Footer

Recent Posts

  • ICS Cube Product Review 26/04/2019
  • PowerShell Module SysInfo v1.2.0 15/03/2019
  • PowerShell Module SysInfo v1.1.2 13/11/2018
  • PowerShell Module SysInfo 24/10/2018
  • Get-VoltageProbe 24/10/2018
  • Get-VideoController 24/10/2018
  • Get-USBController 24/10/2018
  • Get-TrackPoint 24/10/2018
  • Get-TrackBall 24/10/2018
  • Get-TouchScreen 24/10/2018
Planet PowerShell

Categories

  • Modules Cmdlets (57)
  • PowerShell Modules (5)
  • PowerShell Scripts (38)
  • PowerShell Tutorials (35)
  • Software Reviews (2)

Archives

  • April 2019 (1)
  • March 2019 (1)
  • November 2018 (1)
  • October 2018 (56)
  • September 2018 (13)
  • August 2018 (9)
  • July 2018 (6)
  • June 2018 (8)
  • May 2018 (7)
  • April 2018 (9)
  • March 2018 (4)
  • February 2018 (6)
  • January 2018 (12)
  • December 2017 (4)
Top 10 PowerShell 2018

Blogroll

  • Planet PowerShell
  • Reddit – PowerShell
  • PowerShell Magazine
  • PowerShell.org
  • PowerShell Team Blog
  • Hey, Scripting Guy! Blog
  • Mike F Robbins
  • PowerShell Explained with Kevin Marquette
  • Mike Kanakos – Network Admin
  • The Lonely Administrator
  • AskME4Tech
PowerShell Blogs Sysadmin Blogs Banners for Top 20 Programming Blogs

© 2023 · Stephanos Constantinou Blog

  • Home
  • Blogs
  • About
  • Contact