PowerShell Hardware Inventory Script – Part 2
Scenario:
PowerShell Hardware Inventory Script – Part 2.
In Part 1, we saw how we are able to create a simple inventory of our computers based on Active Directory. In this part we will go through the minor additional features of the script that in my opinion will help you out. I will give a brief summary for those who have not read part 1 on what the script is doing.
The script will scan your Active Directory and collect all computer objects. It will save them in an array and then it will process them to get the information needed. It will first test the connection to the computer and if everything is OK it will try to get the information that we need. After everything available has been collected the results will be exported to a CSV file.
[adinserter name=”In Article”]
Current Version
Now let’s see what has been added in this version of the script.
The features that I have included in this version are listed below:
- WMI objects replaced with CIM
- Serial Number information
- Sound Device information
- Video Controller information
- Email report
CIM Classes
As WMI cmdlets have been deprecated and are no longer recommended, I have replace them in the script with CIM cmdlets. CIM has been introduced in PowerShell 3.0.
Serial Number
The script now collects the serial number of the computer object based on what BIOS provides. In order to get the serial number we are using Win32_Bios
class and SerialNumber
property. The full command that we need to use is the below:
$ComputerSerial = (Get-CimInstance Win32_Bios -ComputerName $ComputerName).SerialNumber
Sound Devices
Sound device information has been added also in the computer objects information that we collect. In the report only the name of sound devices is included. If there are multiple devices, all devices’ names will be included. You might need to fix a bit the presentation of them. In a future update I will try to fix them. The command that is used to get sound devices information is the below:
$ComputerSoundDevices = (Get-CimInstance -Class Win32_SoundDevice).Name
Video Controller
Video controller information has been added. For the video controller, the script will collect only Name and AdapterRAM. As you will see below we are using an expression to convert the value provided for the adapter RAM into GB in order to be easier to read. The command that will collect the information and convert RAM in GM is below:
$ComputerGraphics = Get-CimInstance -Class Win32_VideoController | select Name,@{Expression={$_.AdapterRAM / 1GB};Label="GraphicsRAM"}
[adinserter name=”In Article”]
Email Report
A new feature has been added also in the script. Now when you run the script you are able to specify if you want to send the CSV file as an email attachment. If you will choose to send the report also in an email, the report will still be exported at the same location as without email report. In order to set the script to send the report, you need to use both parameters. The command that you have to use is:
Get-Inventory.ps1 -Email -Recipients user1@domain.com,user2@domain.com
Currently the script is setup to use Office365 to send emails. You can change the settings according to your setup in order to send the emails property. As you can see above, the script accepts also multiple recipients if there is a need to send the report to many users. As you as you run the script with the email option, the script will ask you to enter the email credentials of the user that will be used to send the email. The interface that you will see is the below:
Please note that the script run time depends on the number of computer objects that you have in your Active Directory. Also in order to be able to run the CIM cmdlets you need to have PowerShell 3.0 and above. for the rest of permissions you need please check part 1.
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 Hardware Inventory Script
- 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
- Get-CimInstance (CimCmdlets) | Microsoft Docs
[adinserter name=”In Article”]
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 Cim. The information includes Manufacturer, Model,Serial Number, CPU, RAM, Disks, Operating System, Sound Deivces and Graphics Card Controller. .RELATED LINKSHome.NOTES Version 1.1 Updated: 01-06-2018 - Replaced Get-WmiObject cmdlet with Get-CimInstance - Added Serial Number Information - Added Sound Device Information - Added Video Controller Information - Added option to send CSV file through email - Added parameters to enable email function option Release Date: 10-02-2018 Author: Stephanos Constantinou .EXAMPLES Get-Inventory.ps1 Find the output under C:\Scripts_Output Get-Inventory.ps1 -Email -Recipients user1@domain.com Find the output under C:\Scripts_Output and an email will be sent also to user1@domain.com Get-Inventory.ps1 -Email -Recipients user1@domain.com,user2@domain.com Find the output under C:\Scripts+Output and an email will be sent also to user1@domain.com and user2@domain.com #> Param( [switch]$Email = $false, [string]$Recipients = $nulll ) $Inventory = New-Object System.Collections.ArrayList if ($Email -eq $true){ $EmailCredentials = $host.ui.PromptForCredential("Need email credentials", "Provide the user that will be used to send the email.", "", "") $To = @(($Recipients) -split ',') $Attachement = "C:\Scripts_Output\Inventory.csv" $From = $EmailCredentials.UserName $EmailParameters = @{ To = $To Subject = "Inventory" Body = "Please find attached the inventory that you have requested." Attachments = $Attachement UseSsl = $True Port = "587" SmtpServer = "smtp.office365.com" Credential = $EmailCredentials From = $From} } $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-CimInstance -Class Win32_ComputerSystem -ComputerName $ComputerName | select Manufacturer, Model, NumberOfProcessors, @{Expression={$_.TotalPhysicalMemory / 1GB};Label="TotalPhysicalMemoryGB"} $ComputerCPU = Get-CimInstance win32_processor -ComputerName $ComputerName | select DeviceID, Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors $ComputerDisks = Get-CimInstance -Class Win32_LogicalDisk -Filter "DriveType=3" -ComputerName $ComputerName | select DeviceID, VolumeName, @{Expression={$_.Size / 1GB};Label="SizeGB"} $ComputerSerial = (Get-CimInstance Win32_Bios -ComputerName $ComputerName).SerialNumber $ComputerGraphics = Get-CimInstance -Class Win32_VideoController | select Name, @{Expression={$_.AdapterRAM / 1GB};Label="GraphicsRAM"} $ComputerSoundDevices = (Get-CimInstance -Class Win32_SoundDevice).Name $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 $ComputerInfoGraphicsName = $ComputerGraphics.Name $ComputerInfoGraphicsRAM = $ComputerGraphics.GraphicsRAM $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 "Serial" -Value "$ComputerSerial" -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 $ComputerInfo | Add-Member -MemberType NoteProperty -Name "Graphics" -Value "$ComputerInfoGraphicsName"-Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "GraphicsRAM" -Value "$ComputerInfoGraphicsRAM"-Force $ComputerInfo | Add-Member -MemberType NoteProperty -Name "SoundDevices" -Value "$ComputerSoundDevices"-Force } $Inventory.Add($ComputerInfo) | Out-Null $ComputerHW = "" $ComputerCPU = "" $ComputerDisks = "" $ComputerSerial = "" $ComputerGraphics = "" $ComputerSoundDevices = "" } $Inventory | Export-Csv C:\Scripts_Output\Inventory.csv if ($Email -eq $true){send-mailmessage @EmailParameters}
[adinserter name=”Matched-Content”]


A tip to filter out disabled computer accounts, as well as cluster objects and potential linux-AD-members is to use an LDAPFilter for get-adcomputer:
Get-ADComputer -LDAPFilter “(&(objectCategory=computer)(operatingSystem=Windows*)(!serviceprincipalname=*MSClusterVirtualServer*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))”
Hello Jakob,
Thank you for your comment. More will come in the new version and I will have in mind your recommendation.
Thank you
Stephanos
I use a single cim session for each node to query all the cim instances I need.
This speeds things up and allows to target those nasty boxes running posh 2.0 via DCOM.
Hey I am wanting to run a small inventory for my boss. Our Active Directory has many different campuses and I would like to filter those out. How would I modify the script just to scan our campus instead of the entire system. Would it be in this line that I need to make changes?
$AllComputers = Get-ADComputer -Filter * -Properties Name
Hello Jordan,
Yes this is the line that you need to modify.
You have to use the parameter
-SearchBase
.After that you need to specify the Organizational Unit by its Distinguished Name.
Example:
$AllComputers = Get-ADComputer -Filter * -Properties Name -SearchBase "OU=Campus Name,DC=domain,DC=COM"
If you have any problem let me know.
Thanks
Stephanos
Stephanos,
I just wanted to let you know your solution worked perfectly. Thank you so much for your response. It is so easy. Enable WinRM and designate the OU and boom a perfect excel file. Have a great day.
-Jordan
Dear Jordan,
Thank you for your feedback. I really appreciate it. I’m glad that my script helped you perform your tasks easily.
Thank you
Stephanos
Sir, do you know facebook script hack? please reply, thank you.
Hello Geffen,
This is not a site for hacking tools. In this site you can find PowerShell related information to help system administrators.
Thank you
Stephanos
Hi Stephanos,
I was able to run the Get Inventory script but it only yields the AD info and not the computer objects. Any suggestions? I’m a novice with PowerShell.
Thank you,
Ray
Hi Ray,
There are 2 reason that do not allow you to get the information from the remote computers.
1. The account you are running the script does not have access to remote computers
2. WinRM is not enabled on remote computers.
Hi Stephanos,
thank you for sharing the information through this blog. It is very useful indeed.
I have customized this script and added hard drive model and serial number fields. However, there are few computers which has two or more hard disks and the script insert a space between them in the output. I would like to have a new line or carriage return character.
See the following picture for better understanding: https://prnt.sc/pJXOUyVnJjG1
Thank you in advance!