How to build a PowerShell inventory script for Windows Servers

With the help of a little PowerShell script, you can easily create an inventory of your Windows machines. In this post I demonstrate how you can remotely retrieve available memory, disk space, and computer names of all the Windows servers in your network.

Prerequisites ^

You're going to need a few prerequisites before we get started:

  • PowerShell Remoting enabled and available to you on all Windows Servers
  • Intermediate level PowerShell knowledge

Scaffolding ^

A server inventory script like this can get massive and unwieldy if not properly planned out. I do this via script scaffolding.

Scaffolding is a term used to refer to writing out the framework of a script. I'm not actually writing functional code just yet; I'm just building the "container" to fit it in.

First, I'll need a source where I can pull the server names from. One possibility is to pull the names from an Active Directory, although this isn't necessarily required. Below you can see I'm using the Get-AdComputer to find all servers in the Servers OU.

Once I have the server names, I can then begin to scaffold out the code querying the name, operating system, memory, and free disk space of multiple servers. A rough framework of how this will happen is shown below. Notice that I've already built a foreach loop and will be creating an object for each server with four properties.

Finding the operating system ^

Now I can begin filling in the values for the $output hashtable I've defined in my script scaffold. The first task is getting the operating system of each server. The best way to do that is to use CIM. I know I can pull the operating system name via Get-CimInstance like this:

Knowing how to find the operating system for a single server, I can add that code and replace the ComputerName value with the variable our server will have in our foreach loop.

Finding free disk space ^

The next value we need to come up with is the amount of free disk space on one server. We'll then expand that out to our script when we're done.

Again, we can use CIM to handle this, querying the Win32_LogicalDisk class this time.

Free disk space

Free disk space

This works, but we have a problem. When this report is run, we're going to have a single server per row, and a server can have more than one disk on it. If we leave this as-is, it's going to look bad when the reports runs.

Let's sum up all of the disk space and round it to the nearest GB so we have a birds-eye view of all disks.

We can now pull the sum of free space from all disks on a single server. Let's use the same tactic as before and insert this code into our inventory script.

Finding total memory ^

The next attribute to add to the script is total memory. We can, thankfully, use CIM again to grab this!

CIM memory

CIM memory

We have the same problem as last time. The query to find total memory returns objects with properties. We just need a single string value. We can find the actual memory amount via the Capacity property. Once we have this, we can sum up the capacities from each object that's returned.

Notice above that the 3758096384 sure is a big number! That’s because the number that comes out of CIM is in bytes. We need to convert this to gigabytes to get a better representation.

We can now plug this code into the inventory script.

When the above code runs, you will see an output like below. I just have a single machine to query but when you run this in a larger environment, you will see one server per row with each property populated.



We can now add a parameter to dynamically send it server names and finish off this script!

If I save the above code as Get-SrvInv.ps1, I could then execute the script passing in a list of server names retrieved from Active Directory or another data source.

Notice below I'm using a text file of server names as an example.

Summary ^

Once you have the basics down of building an inventory report like this, you can start to plug in various code snippets to pull the information you need.

If you'd like a deeper look into building a script like this, I encourage you to check out the Building a Tool mini-course that covers these concepts and goes into a lot more detail.

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!

  1. Steven 11 months ago

    I would recommend a few adjustments for anyone looking to use this in production: 

    • Use a script block to pass to each server verses opening and closing that many ciminstances
    • Use invoke-command on a array of server names to run this in parallel across multiple servers. 
    • Add error checking for unresponsive servers 
    • Add the option to export as CSV.

    The last code sample has two param blocks.


  2. The final block of code should be more like the following. 

    Users might need to enable PSRemotting and have admin credentials to connect to the server/workstation.


Leave a reply

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


© 4sysops 2006 - 2020


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account