Free Ebook cover Windows PowerShell for Beginners: Everyday Automation and System Insights

Windows PowerShell for Beginners: Everyday Automation and System Insights

New course

10 pages

System Insights with PowerShell: Hardware, OS, Network, and Logs

Capítulo 7

Estimated reading time: 8 minutes

+ Exercise

What “system insights” means in PowerShell

System insights are small, repeatable checks you can run to answer common troubleshooting and inventory questions: What OS is this? How long has it been running? How much disk and memory is available? What IP settings are active? Are there relevant errors in the logs? In this chapter you’ll use read-only cmdlets to collect that information consistently, and you’ll build a simple “system snapshot” you can share with someone else.

Modern sources of system data: cmdlets vs. CIM/WMI

PowerShell can read system information from multiple sources:

  • Purpose-built cmdlets (for example Get-ComputerInfo, Get-NetIPConfiguration, Get-WinEvent) are usually the simplest and most readable.
  • CIM (Common Information Model) via Get-CimInstance reads standardized classes (often the same underlying data that older WMI tools exposed). CIM is useful when there is no dedicated cmdlet, or when you want consistent data across many Windows versions.

Beginner rule of thumb: use a dedicated cmdlet when it exists; use Get-CimInstance when you need hardware/OS inventory details that aren’t exposed by a single friendly cmdlet. In this chapter, all examples are safe, read-only queries.

Recipe set 1: OS details

Quick OS summary with Get-ComputerInfo

Get-ComputerInfo returns a large object with many properties. For a quick OS-focused view, select only what you need:

Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer, OsBuildNumber, OsArchitecture

Step-by-step:

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

  • Run the command as-is to see a compact summary.
  • If you need more OS-related fields, run Get-ComputerInfo alone and look for properties starting with Os or Windows.

OS details via CIM (works well for inventory)

Win32_OperatingSystem is a common CIM class for OS inventory. It’s handy when you want install date, last boot time, and version info in one place.

Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, InstallDate, LastBootUpTime

Tip: CIM date/time values may display in a long format; they are still real date objects you can compare and format later.

Recipe set 2: Computer name and uptime

Computer name

For a quick check:

$env:COMPUTERNAME

Or, if you want it as part of a richer system object:

Get-ComputerInfo | Select-Object CsName

Uptime (how long since last boot)

A reliable approach is to read the last boot time from CIM and subtract it from the current time.

$os = Get-CimInstance -ClassName Win32_OperatingSystem $uptime = (Get-Date) - $os.LastBootUpTime $uptime

If you want a cleaner display:

[pscustomobject]@{ LastBoot = $os.LastBootUpTime; UptimeDays = [math]::Round($uptime.TotalDays, 2) }

Recipe set 3: Disk and memory info

Disk space (logical disks)

Use CIM to query logical disks and calculate free/used space. This is a classic inventory check.

Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, VolumeName, @{n='SizeGB';e={[math]::Round($_.Size/1GB,2)}}, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}}, @{n='FreePct';e={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}}

Step-by-step:

  • DriveType=3 limits results to local fixed disks (not CD/DVD or removable).
  • The calculated properties convert bytes to GB and compute a percentage.

Physical memory (RAM)

To see total installed memory:

Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object Name, @{n='TotalMemoryGB';e={[math]::Round($_.TotalPhysicalMemory/1GB,2)}}

To see each memory module (useful for hardware inventory):

Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object BankLabel, Manufacturer, Capacity, Speed

If you want capacity in GB per module:

Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object BankLabel, Manufacturer, @{n='CapacityGB';e={[math]::Round($_.Capacity/1GB,2)}}, Speed

Recipe set 4: Network configuration

High-level network view (recommended starting point)

Get-NetIPConfiguration provides a friendly summary of adapters, IP addresses, gateways, and DNS settings.

Get-NetIPConfiguration

To keep it concise:

Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer

IP addresses only (quick check)

Get-NetIPAddress | Where-Object AddressFamily -eq IPv4 | Select-Object InterfaceAlias, IPAddress, PrefixLength

DNS client configuration

Get-DnsClientServerAddress | Select-Object InterfaceAlias, AddressFamily, ServerAddresses

Network adapter status

Get-NetAdapter | Select-Object Name, Status, LinkSpeed, MacAddress

Beginner note: if you see multiple adapters (Wi-Fi, Ethernet, virtual adapters), focus on the one that is Up and has a default gateway.

Recipe set 5: Event log queries (modern and fast)

Why Get-WinEvent (and when to use it)

Get-WinEvent is the modern cmdlet for reading Windows event logs. It supports filtering efficiently (especially with -FilterHashtable), which is important because logs can be large.

Get the newest errors from the System log

Get-WinEvent -LogName System -MaxEvents 20 | Where-Object LevelDisplayName -eq 'Error' | Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

If you want the newest 20 events regardless of level, remove the Where-Object filter.

Filter by time range (last 24 hours)

-FilterHashtable is a good habit for performance because it filters at the source.

$start = (Get-Date).AddHours(-24) Get-WinEvent -FilterHashtable @{ LogName='System'; StartTime=$start } | Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

Filter by Event ID (example: unexpected shutdowns)

Event ID 6008 in the System log often indicates an unexpected shutdown. Querying it can help explain reboots.

Get-WinEvent -FilterHashtable @{ LogName='System'; Id=6008 } -MaxEvents 10 | Select-Object TimeCreated, Id, Message

Application crashes (example pattern)

Application Error events commonly use ID 1000 in the Application log. This is a useful starting point when an app “just closes.”

Get-WinEvent -FilterHashtable @{ LogName='Application'; Id=1000 } -MaxEvents 10 | Select-Object TimeCreated, ProviderName, Message

Safety reminder: these commands only read logs. They do not clear or modify them.

Build a repeatable “system snapshot” for sharing

The goal is a concise, readable snapshot you can run on demand and export to a file. Keep it read-only and avoid collecting sensitive data unnecessarily. The following example gathers: OS summary, uptime, disk free space, memory total, basic network config, and a small slice of recent errors.

Step-by-step: create a snapshot object

Run this in PowerShell to build a single object that contains multiple sections:

$os = Get-CimInstance -ClassName Win32_OperatingSystem $cs = Get-CimInstance -ClassName Win32_ComputerSystem $uptime = (Get-Date) - $os.LastBootUpTime $disks = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{n='SizeGB';e={[math]::Round($_.Size/1GB,2)}}, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}}, @{n='FreePct';e={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}} $net = Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer $start = (Get-Date).AddDays(-1) $recentSystemErrors = Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=$start} -ErrorAction SilentlyContinue | Where-Object LevelDisplayName -eq 'Error' | Select-Object -First 10 TimeCreated, ProviderName, Id, Message $snapshot = [pscustomobject]@{ ComputerName = $cs.Name OS = $os.Caption OSVersion = $os.Version BuildNumber = $os.BuildNumber LastBoot = $os.LastBootUpTime UptimeDays = [math]::Round($uptime.TotalDays,2) TotalMemoryGB = [math]::Round($cs.TotalPhysicalMemory/1GB,2) Disks = $disks Network = $net RecentSystemErrors = $recentSystemErrors } $snapshot

What to look for:

  • UptimeDays helps correlate issues with recent reboots.
  • FreePct highlights low disk space quickly.
  • Network shows whether the machine has an IP and default gateway.
  • RecentSystemErrors gives a small, relevant slice of log data without dumping everything.

Export the snapshot to a shareable file

Because the snapshot contains nested sections (disks, network, events), choose an export format that preserves structure.

Option A: JSON (good for structure and re-importing)

$path = "$env:USERPROFILE\Desktop\SystemSnapshot.json" $snapshot | ConvertTo-Json -Depth 5 | Set-Content -Path $path -Encoding UTF8

Option B: Text report (easy to read in email/tickets)

$path = "$env:USERPROFILE\Desktop\SystemSnapshot.txt" $snapshot | Out-String | Set-Content -Path $path -Encoding UTF8

Tip: JSON is better for preserving nested data; text is better for quick human reading.

Exercises (safe, read-only)

Exercise 1: OS + uptime mini-report

  • Create variables for OS info and uptime using Win32_OperatingSystem.
  • Output a [pscustomobject] with: computer name, OS caption, version, last boot time, uptime in hours.
$os = Get-CimInstance Win32_OperatingSystem $uptime = (Get-Date) - $os.LastBootUpTime [pscustomobject]@{ ComputerName = $env:COMPUTERNAME OS = $os.Caption Version = $os.Version LastBoot = $os.LastBootUpTime UptimeHours = [math]::Round($uptime.TotalHours,1) }

Exercise 2: Disk “low space” check

  • Query fixed disks.
  • Show only disks with less than 15% free space.
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Where-Object { $_.Size -gt 0 -and (($_.FreeSpace/$_.Size)*100) -lt 15 } | Select-Object DeviceID, @{n='FreePct';e={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}}, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}}

Exercise 3: Network snapshot for the active adapter

  • List adapters that are up.
  • For each, show IP and default gateway.
Get-NetAdapter | Where-Object Status -eq 'Up' | ForEach-Object { Get-NetIPConfiguration -InterfaceIndex $_.ifIndex } | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer

Exercise 4: Last day of System errors exported to a file

  • Query System log errors from the last 24 hours.
  • Export to a text file on the Desktop.
$start = (Get-Date).AddHours(-24) $events = Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=$start} | Where-Object LevelDisplayName -eq 'Error' | Select-Object TimeCreated, ProviderName, Id, Message $path = "$env:USERPROFILE\Desktop\SystemErrors_Last24Hours.txt" $events | Format-Table -AutoSize | Out-String | Set-Content -Path $path -Encoding UTF8

Exercise 5: One-command snapshot you can rerun

Create a single script block that generates the snapshot and writes it to JSON. Run it, then open the JSON file to confirm it contains disks, network, and recent errors.

$path = "$env:USERPROFILE\Desktop\SystemSnapshot.json" & { $os = Get-CimInstance Win32_OperatingSystem $cs = Get-CimInstance Win32_ComputerSystem $uptime = (Get-Date) - $os.LastBootUpTime [pscustomobject]@{ ComputerName = $cs.Name OS = $os.Caption Version = $os.Version Build = $os.BuildNumber LastBoot = $os.LastBootUpTime UptimeDays = [math]::Round($uptime.TotalDays,2) TotalMemoryGB = [math]::Round($cs.TotalPhysicalMemory/1GB,2) Disks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{n='SizeGB';e={[math]::Round($_.Size/1GB,2)}}, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}}, @{n='FreePct';e={[math]::Round(($_.FreeSpace/$_.Size)*100,1)}} Network = Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer RecentSystemErrors = (Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=(Get-Date).AddDays(-1)} | Where-Object LevelDisplayName -eq 'Error' | Select-Object -First 10 TimeCreated, ProviderName, Id, Message) } } | ConvertTo-Json -Depth 5 | Set-Content -Path $path -Encoding UTF8

Now answer the exercise about the content:

When exporting a PowerShell system snapshot that contains nested sections (like disks, network, and recent errors), which export format is best for preserving the structure and allowing re-importing later?

You are right! Congratulations, now go to the next page

You missed! Try again.

When the snapshot includes nested data (disks, network, events), JSON preserves the structure and is suitable for re-importing. Text outputs are easier to read but flatten or format data for humans.

Next chapter

Variables and Simple Logic: Building Blocks for Everyday Automation

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.