Gathering system information is a crucial aspect of system administration, as it helps you understand the resources and components of your infrastructure. In this article, we will explore how to use PowerShell to gather hardware, software, and operating system details on Windows, macOS, and Linux systems.

In this article, I want to give you a glimpse into using PowerShell for gathering system information, but I also want to show how awesome PowerShell is across various operating systems.

Now, system administrators work with all kinds of environments, and it’s helpful to see some of those differences. As you’ve seen, there are some unique aspects when it comes to using PowerShell on Windows, macOS, and Linux.

My goal is to help you navigate these distinctions and offer practical guidance, tips, and examples to make your PowerShell experience more seamless, no matter the platform you’re working with.

Let’s continue to explore and learn together, leveraging PowerShell’s powerful capabilities to enhance our system administration expertise.

Gathering Operating System Information

The Get-CimInstance cmdlet is a cross-platform tool that allows you to query and retrieve information about your system using CIM classes. Although some CIM classes are Windows-specific, many of them can be used on macOS and Linux as well.

Getting System Information from Get-CimInstance

Here’s an example of how to use the Get-CimInstance cmdlet to retrieve OS information:

$os = Get-CimInstance -ClassName CIM_OperatingSystem
$os | Select-Object Caption, Version, OSArchitecture, BuildNumber

This command retrieves information such as the OS version, architecture, and build number.

Nice, but you have to already know the ClassName, right?

Wrong!

PowerShell provides a way to discover available CIM classes using the Get-CimClass cmdlet. Let me show you real quick how the process of finding the right CIM classes and namespaces to gather system information works.

Listing CIM Classes

You can list all available CIM classes by running the Get-CimClass cmdlet without any parameters:

Get-CimClass

This command will return a long list of CIM classes, so it’s usually better to narrow down your search using wildcards.

Searching CIM Classes with Wildcards

You can use the -ClassName parameter with wildcards to filter the list of CIM classes. For example, to find classes related to disk drives, you can use the following command:

Get-CimClass -ClassName *disk*

This will return a list of CIM classes with “disk” in their names, such as CIM_DiskDrive and CIM_LogicalDisk.

Exploring Specific CIM Classes

Once you’ve found a CIM class of interest, you can further explore its properties and methods using the Get-CimClass cmdlet. For example, to see the properties and methods available for the CIM_Processor class, you can run:

Get-CimClass -ClassName CIM_Processor

Discovering WMI Namespaces

CIM classes are organized in WMI namespaces. To list the available namespaces on your system, you can use the Get-WmiObject cmdlet with the -Namespace parameter and wildcards:

Get-WmiObject -Namespace root\* -Class __Namespace | Select-Object Name

This command will return a list of available namespaces under the “root” namespace.

Searching CIM Classes within a Specific Namespace

You can combine the -Namespace parameter with the Get-CimClass cmdlet to search for CIM classes within a specific namespace. For example, to find classes related to networking in the “root\cimv2” namespace, you can run:

Get-CimClass -Namespace root\cimv2 -ClassName *network*

This will return a list of CIM classes related to networking within the “root\cimv2” namespace.

By leveraging the Get-CimClass and Get-WmiObject cmdlets, you can discover the available CIM classes and namespaces to gather the system information you need. With this knowledge, you can really ramp up your efficiency with being able to specifically target individual components for your system administration tasks from your PowerShell scripts.

Gathering Hardware Information

Alright, now that we have cleared up some of the relationship between CimClass and CimInstance, let’s dig into how we can pull hardware information out of the system.

Using the Get-CimInstance cmdlet, you can also obtain hardware information on Windows, macOS, and Linux systems. Here are some examples:

Processor Information

$processor = Get-CimInstance -ClassName CIM_Processor
$processor | Select-Object Name, MaxClockSpeed

Memory Information

$memory = Get-CimInstance -ClassName CIM_PhysicalMemory
$memory | Select-Object Capacity, Speed

Disk Drives

$diskDrives = Get-CimInstance -ClassName CIM_DiskDrive
$diskDrives | Select-Object Model, MediaType, Size

Logical Disks

$logicalDisks = Get-CimInstance -ClassName CIM_LogicalDisk
$logicalDisks | Select-Object DeviceID, FileSystem, Size, FreeSpace

Network Adapters

$networkAdapters = Get-CimInstance -ClassName CIM_NetworkAdapter
$networkAdapters | Select-Object Name, MACAddress, Speed

BIOS Information

$bios = Get-CimInstance -ClassName CIM_BIOSElement
$bios | Select-Object Manufacturer, Version, ReleaseDate

Battery information (for laptops/tablets)

$battery = Get-CimInstance -ClassName CIM_Battery
$battery | Select-Object EstimatedChargeRemaining, EstimatedRunTime

Graphics card info

$graphics = Get-CimInstance -ClassName CIM_VideoController
$graphics | Select-Object Name, AdapterRAM, DriverVersion

In some cases, you might need to rely on platform-specific commands or tools for macOS and Linux to gather certain system information.

Gathering Software Information

Gathering software installation information from your system can be a little more complicated. That’s because the software details can be accessed from a few different locations.

So here is a little tour of the madness that can be listing all the software installed on a system:

Capturing from Software Package Managers

If you use Chocolatey or Winget for installing software, you’re used to a command line approach and you’re already a leg up on people that are only familiar with the old “next next next” installation style.

You can use those same package managers to list what software is installed on your system.

### Chocolatey List Locally Installed Software

choco list --local-only

### Windows Package Manager (Winget)

winget list

### Packages installed through PowerShell (mostly modules)

Get-Package

Querying WMI

Just like you can use the CIM cmdlets to query WMI to get hardware information, you can use it similarly to get software information.

Get-CimInstance -ClassName Win32_Product | Select-Object Name, Version

However, be aware that using the Win32_Product class can cause performance issues and unintended side effects, such as triggering a reconfiguration of installed software. A safer alternative is to query the registry:

Querying the Registry

In Windows systems, everything is in the registry. I’ve got another article on how to read, set and even (carefully!) delete registry keys. Take a look at that if you’re not familiar with the commands for working with the registry. You can also leverage the PowerShell providers to browse the registry like a folder structure.

Either way, for this case you’re going to want to look at both the 32-bit and 64-bit software sections in the registry to capture a full list of software that’s installed.

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

$installedSoftware = $keys | ForEach-Object { Get-ItemProperty $_ } |
    Where-Object { $_.DisplayName -ne $null } |
    Select-Object DisplayName, DisplayVersion, Publisher

$installedSoftware

Finding Software Information on Mac / Linux

Both Linux and Mac have similar package manager stories as Windows does with Chocolatey & Winget. It’s even a little more straightforward as it’s been used for so long, while it’s relatively new for Windows users.

So you’ll still end up using your package manager commands to list the installed software on PowerShell. However, the great thing about PowerShell is how it works with objects… And the sad thing is that the package managers only output text.

If you want to create a more Object-centric result, you could parse the text that is returned to turn it into an object. That could look something like this:

# macOS example
$softwareList = brew list --formula
$softwareObjects = $softwareList | ForEach-Object {
  [PSCustomObject]{
    Name = $_
    Version = (brew info --formula $_ | Select-String -Pattern "stable\s+(\S+)").Matches.Groups[1].Value
  }
}

# Linux example (Debian-based)
$softwareList = dpkg --list
$softwareObjects = $softwareList | Select-String -Pattern "^(ii\s+)(\S+)(\s+\S+\s+)(\S+)" | ForEach-Object {
  [PSCustomObject]@{
    Name = $.Matches.Groups[2].Value
    Version = $.Matches.Groups[4].Value
  }
}

Hopefully that gives you a fun thing to play with when looking for your software on Linux/Mac. Play with it and let me know how it goes!

Gathering System Information with Custom PowerShell Scripts

You can create custom PowerShell scripts to collect specific system information tailored to your needs. Here’s an example of a script that collects system information and exports it to a CSV file:

$systemInfo = [PSCustomObject]@{
    OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
    Processor = (Get-CimInstance -ClassName CIM_Processor).Name
    Memory = (Get-CimInstance -ClassName CIM_PhysicalMemory).Capacity
    DiskSpace = (Get-CimInstance -ClassName CIM_LogicalDisk).Size
}

$systemInfo | Export-Csv -Path "SystemInfo.csv" -NoTypeInformation

Exporting and Saving System Information

PowerShell provides several cmdlets for exporting and saving system information in different formats, such as Export-Csv, Export-Clixml, and Out-File. Here’s an example of exporting hardware information to a CSV file:

$hardwareInfo = Get-CimInstance -ClassName CIM_ComputerSystem
$hardwareInfo | Export-Csv -Path "HardwareInfo.csv" -NoTypeInformation

Conclusion

We all know that PowerShell is the best language for working with system administration on Windows. But with these cross platform tools and cmdlets, PowerShell is a great tool for working with any Operating System.

By using the Get-Cim* cmdlets instead of the older Get-Wmi* cmdlets, you can take advantage of cross-platform compatibility, improved performance, and more efficient memory usage. Continue practicing and exploring further system information tasks with PowerShell to enhance your skills and better manage your infrastructure.