PLEASE READ FIRST!

I've now been blogging here since 2007! ...Wow, has it been that long already?! Over the years, I've covered a wide array of subjects from scripting, troubleshooting, to the occasional hobby project. I have literally heard from thousands of you over the years with questions or even just offering me a bit of thanks!

Recently, I quit my full-time job and started work on an IT business, Rhythm IT Solutions, helping other IT departments manage their IT environments. We're offering consulting & professional services (Office 365 Migrations, Network Discovery, Firewall Management, etc...) as well as Endpoint Management (AV, Patch Management EDR, Managed Backup, etc...)



If there is something (on my blog or not) that you could use some additional help with, I would LOVE to hear from you! Please feel free to reach out to me using the contact links here or the contact form on Rhythm's website.

For those wondering, I do plan on continuing my work on the blog. So don't worry! There are plenty of Greg Strike posts yet to come! 😊 Thanks for stopping by!

PLEASE READ FIRST!




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")


PLEASE READ FIRST!

I've now been blogging here since 2007! ...Wow, has it been that long already?! Over the years, I've covered a wide array of subjects from scripting, troubleshooting, to the occasional hobby project. I have literally heard from thousands of you over the years with questions or even just offering me a bit of thanks!

Recently, I quit my full-time job and started work on an IT business, Rhythm IT Solutions, helping other IT departments manage their IT environments. We're offering consulting & professional services (Office 365 Migrations, Network Discovery, Firewall Management, etc...) as well as Endpoint Management (AV, Patch Management EDR, Managed Backup, etc...)



If there is something (on my blog or not) that you could use some additional help with, I would LOVE to hear from you! Please feel free to reach out to me using the contact links here or the contact form on Rhythm's website.

For those wondering, I do plan on continuing my work on the blog. So don't worry! There are plenty of Greg Strike posts yet to come! 😊 Thanks for stopping by!

PLEASE READ FIRST!





Gregory Strike

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