This isnt so much a tutorial, as it is just a script, but I added a ton of comments for ya, let me know how ya like it.
*NOTE* Unfortunately, the company I work for is mostly windows, thus, this only works on a windows machine, and can only monitor a windows machine, which you have access to and have permissions to specific WMI Namespaces. But you can try it on Localhost if you wish.
use Win32::OLE qw( in );
use Win32::Service;
use Win32::Process;
use POSIX qw/floor/;
use Switch;
# READY! CLEAR!
system("cls");
###################################
# CATCHING CTRL + C
$SIG{INT} = \&CTRLC;
sub CTRLC
{
&SVR_START;
}
###################################
# SUB SUB_HELP: DISP HELP
sub SUB_HELP
{
print "\nJust type 'watch localhost'\n\n";
&SVR_START;
}
# START THE PROGRAM! Every sub goes to SVR_START, Its how we make the loop.
&SVR_START;
###################################
# SUB SVR_START: MONITOR THE SERVER
sub SVR_START
{
print "Input> ";
chomp($input = <>);
@args = split(" ", $input);
$do = $args[0];
switch ($do)
{
#########################################
# CASE EXIT
#########################################
case "exit"
{
die();
}
#########################################
# CASE WATCH
#########################################
case "watch"
{
print "\n";
if($args[1]){
#SETTING THE VARIABLES
# What to watch, this will be watch $server
$server = $args[1];
# CPU Limit, I set it as 90%
$cpu_limit = 90;
# MEM Limit, I like it at 80%
$mem_limit = 80;
# Check every x amount of seconds. NOTE: This is 2 seconds between each run, dosnt include how long it takes to run it.
$sleep = 2;
} else {
&SUB_HELP;
}
print "ctrl+c to stop watching..\n\n";
# Not going to lie, Im not 100% sure what the following is for, I googled the sh*t out of it, couldnt find much
# But its required for all WMI Objects
use constant wbemFlagReturnImmediately => 0x10;
use constant wbemFlagForwardOnly => 0x20;
# This is almost a sin! Im using a GOTO statement... Reason why is because I couldnt get it to display resunts within a sub routine
WATCH_START:
# Create the WMI Service Object, calling from the CIMV2 namespace
$objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$server\\root\\CIMV2") or $error = 1;
#Did the computer refuse us?
if($error eq 1){
print "\nWMI connection failed to $computer.\n";
&SVR_START;
}
# Run the WMI Query (Windows Query Language format), throw the results in a var. This is for the Processor Info
$colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_Processor", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
foreach $objItem (in $colItems) {
# Clear the CMD window for each refresh
system ("cls");
# Is the CPU limit over the load limit?
if($objItem->{LoadPercentage} > $cpu_limit){
# yes it is, BEEP!
print "\a"
}
print "CPU: LoadPercentage: ". $objItem->{LoadPercentage} ."%\n";
}
# New query! Lets get the memory info..
$colItems = $objWMIService->ExecQuery("Select * from Win32_OperatingSystem");
print "MEM: ";
foreach my $objItem ( in $colItems ) {
$total_physical = $objItem->{TotalVisibleMemorySize};
$free_physical = $objItem->{FreePhysicalMemory};
$total_virtual = $objItem->{TotalVirtualMemorySize};
$free_virtual = $objItem->{FreeVirtualMemory};
$used_mem = $total_physical - $free_physical;
$mem_percent = $used_mem / $total_physical * 100;
if($mem_percent > $mem_limit){
print "\a";
}
$mem_percent = floor($mem_percent);
# Printf .. lets make it look pretty
printf("%-5s %-20s %-25s %-25s\n", $mem_percent."%,", $total_physical . " Total,", $free_physical . " Free Physical,", $free_virtual . " Free Virtual");
}
# SHOW TOP 10 PROGRAMS USING MEMORY over 20000000
# NOTE: Only reason the WMI query selects working sets over > 20000000, is because they
# Dont support the "order by" clause, hence I cant just order by WOrkingSetSize, and
# Return the first 10 results. So this only shows the first 10 results if they are over
# 20000000 k
print "\n\tTop 10 memory usage programs\n";
use constant wbemFlagReturnImmediately => 0x10;
use constant wbemFlagForwardOnly => 0x20;
$colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_Process WHERE WorkingSetSize > 20000000", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
# START AN EMPTY ARRAY FOR TE PROCESSES
$aa = ();
# LOOP THROUGH PROCESS RESULTS
foreach my $objItem (in $colItems) {
# Change $memory to something more readable
$memory = $objItem->{WorkingSetSize}/1024;
# Push results into an array
push @aa, [$objItem->{ProcessId}, $objItem->{ParentProcessId}, $objItem->{KernelModeTime}, $memory, $objItem->{Caption}];
}
# Sort the array by $aa[3] (The memory, highest on top)
@aa = sort{$b->[3] <=> $a->[3]} @aa;
$current = 0;
$list = 10;
print "\n";
printf("%-6s %-6s %-15s %-10s %-15s %-10s\n", "PID", "PPID", "Time", "Mem (K)", "Name");
print "\n";
while ($current < $list){
printf("%-6s %-6s %-15s %-10s %-15s %-10s\n", $aa[$current][0], $aa[$current][1], $aa[$current][2], $aa[$current][3], $aa[$current][4]);
$current++;
}
sleep($sleep);
undef @aa;
goto WATCH_START;
}
else
{
&SUB_HELP;
}
}
}


Sign In
Create Account


Back to top









