I wrote this PowerShell script to query a remote computer and gather a wide gamut of data that is helpful in troubleshooting situations. Most of the data is gathered using WMI but not all. You’ll need to be an administrator on the computer being queried in order to run this script.

An Example of Stats.ps1 Running...

The script currently pulls the following information:

  • IP Address
  • Ping Reply Time
  • Verifies the computer name currently being queried (In case of possible DNS issues)
  • Computer Manufacturer
  • Computer Model
  • Computer Serial Number
  • BIOS Version
  • Operating System
  • Operating System Service Pack level
  • Computer Description
  • Current Up-time (Time since it was last booted)
  • Remote Time in UTC and local (Helpful for troubleshooting time & timezone related issues)
  • Compares to local computer time to see if there is a time sync problem
  • Checks all hard drive sizes.
  • Checks the amount of free space available on all hard drives.
  • Checks for the currently signed on user name
  • Pulls the user name’s Full Name from Active Directory for easy ID of user.

The script takes an optional command line argument, the computer name. If a computer name is not provided the script will ask for the name before running.

#  Script name:    Stats.ps1
#  Created on:     2009-11-05
#  Author:         Gregory Strike
#  Purpose:        Probes a computer for common Administrative information.
#  Requirements:   This script requires Administrative privileges to the computer requested.

$Error.Clear();

$HeadingWidth = 14;

#Pings a Computer
function Ping{
	param($Computer)

	$Ping = New-Object System.Net.NetworkInformation.Ping;
	$Reply = $Ping.Send($Computer);

	if ($Reply.Status -eq "Success"){
		Return $Reply;
	} else {
		Return $False;
	}
}

CLS;
$Computer = $args[0];
if ($args[1] -ne "-debug"){
	$ErrorActionPreference = "SilentlyContinue";
}

if ($Computer -eq $Null){
	#Write-Host ("Error in Syntax");
	#Write-Host ("./Stats.ps1 Computer [-debug]");
	$Computer = Read-Host("Please enter a computer name")
	CLS;
}
Write-Host("{0,$HeadingWidth} {1,-11}" -f "Computer:", $Computer);
#Write-Host("Stats on " + $Computer + "...");
Write-Host("");

if ($Reply = Ping($Computer)) {

	#Display Ping Results
	Write-Host("{0,$HeadingWidth} {1,-11}" -f "IP:", $Reply.Address);
	$strRoundTrip = [System.String]$Reply.RoundTripTime + "ms"
	Write-Host("{0,$HeadingWidth} {1,-11}" -f "Reply Time:", $strRoundTrip);
	Write-Host("");

	#Display Computer Hardware Information
	$WMI = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $Computer;

	if ($Computer.ToUpper() -Ne $WMI.Caption.ToUpper()) {
		Write-Host("{0, $HeadingWidth} {1, -11} <--- May be incorrect computer!" -f "Computer Name:", $WMI.Caption , "May be incorrect computer!") -Fore Red;
	} else {
		Write-Host("{0, $HeadingWidth} {1, -11}" -f "Computer Name:", $WMI.Caption);
	}

	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Manufacturer:", $WMI.Manufacturer);
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Model:", $WMI.Model);
	$WMI = Get-WMIObject -Class Win32_ComputerSystemProduct -ComputerName $Computer;
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Serial Number:", $WMI.IdentifyingNumber);
	$WMI = Get-WMIObject -Class Win32_BIOS -ComputerName $Computer;
	$strBIOSVersion = [System.String]$WMI.BIOSVersion
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "BIOS Version:", $strBIOSVersion);
	Write-Host("");

	#Display OS Information
	$WMI = Get-WmiObject -Class Win32_OperatingSystem -computer $Computer

	Write-Host("{0, $HeadingWidth} {1, -11}" -f "OS:", $WMI.Caption);
    $OSVersion = $WMI.Version;
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Service Pack:", $WMI.CSDVersion);
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Description:", $WMI.Description);

	Write-Host("");

    #Display Uptime
    $LBTime = $WMI.ConvertToDateTime($WMI.LastBootupTime)
	[TimeSpan]$UPTime = New-TimeSpan $LBTime $(Get-Date)
	$strUpTime = [System.String]$UPTime.Days + " Days ” + $UPTime.Hours + “ Hours ” + $UPTime.Minutes + “ Minutes ” + $UPTime.Seconds + “ Seconds ”;
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Up Time:", $strUpTime);

    #Display Remote Time
    $WMI = Get-WmiObject -Class Win32_LocalTime -Computer $Computer

    $LocalTime = [System.DateTime]::Now
    $strRemoteDateTime = "{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}" -f $WMI.Month, $WMI.Day, $WMI.Year, $WMI.Hour, $WMI.Minute, $WMI.Second
    $RemoteDateTime = [Convert]::ToDateTime($strRemoteDateTime)

    $WMI = Get-WmiObject -Class Win32_TimeZone -Computer $Computer
    $RemoteUTC = $RemoteDateTime.AddMinutes(($WMI.Bias * -1) + ($WMI.DaylightBias) + ($WMI.StandardBias))

    Write-Host("");
    Write-Host("{0, $HeadingWidth} {1, -11}" -f "Remote Time:", $RemoteDateTime);
    Write-Host("{0, $HeadingWidth} {1, -11}" -f "Local Time:", $LocalTime);
    Write-Host("");
    Write-Host("{0, $HeadingWidth} {1, -11}" -f "Remote UTC:", $RemoteUTC);
    Write-Host("{0, $HeadingWidth} {1, -11}" -f "Local UTC:", $LocalTime.ToUniversalTime());
    Write-Host("");

	#Display HardDrive Space
	#$Query = "SELECT * FROM WIN32_LogicalDisk WHERE DeviceID='" + $Server.Drive + "'"
	$WMI = Get-WMIObject -Class Win32_LogicalDisk -ComputerName $Computer
	foreach ($Drive in $WMI) {
		if ($Drive.DriveType -eq 3) {  #Only process drives that are hard drives
			$DriveIDSize = "Disk " + $Drive.DeviceID + " Size:";
			$DriveIDFree = "Disk " + $Drive.DeviceID + " Free:";

			Write-Host("{0, $HeadingWidth} {1, 16} bytes" -f $DriveIDSize, [System.String]::Format("{0:#,#}", $Drive.Size));
			if ($Drive.FreeSpace / $Drive.Size -lt .05) {
				Write-Host("{0, $HeadingWidth} {1, 16} bytes <--- Less than 5% of disk space!" -f $DriveIDFree, [System.String]::Format("{0:#,#}", $Drive.FreeSpace)) -Fore Red;
			} else {
				Write-Host("{0, $HeadingWidth} {1, 16} bytes" -f $DriveIDFree, [System.String]::Format("{0:#,#}", $Drive.FreeSpace));
			}
		}
	}
	Write-Host("");

	#Display User Information
	$WMI = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $Computer;
	if ($WMI.UserName -Ne $Null){
		$strUsername = [System.String]$WMI.UserName;
		$UserName = $strUsername.Split("\");

		#$Domain = New-Object DirectoryServices.DirectoryEntry;
		$Search = [System.DirectoryServices.DirectorySearcher]$UserName[0];
		$Search.Filter = "(&(objectClass=user)(sAMAccountname=" + $UserName[1] + "))";
		$User = $Search.FindOne().GetDirectoryEntry();
		$strFullName = [System.String]$User.Name;
	} else {
		$strUsername = "Not logged in"
		$strFullName = "Not logged in"
	}

	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Console User:", $strUserName);
	Write-Host("{0, $HeadingWidth} {1, -11}" -f "Full Name:", $strFullName);

} else { #Could not ping computer
	Write-Host("The host, " + $Computer + ", did not reply...");
};

Write-Host("");
Write-Host "Completed: Press any key to continue..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")


Gregory Strike

Husband, father, IT dude & blogger wrapped up into one good looking package.