A Perl script to list process info through WMI (local / remote)

Posted: June 20, 2006 in Security, Perl Scripts, Codes & Utilities, Programming

A perl script to list all the current running processes / a particular process on an array of systems. Needs Windows Management and
Instrumentation Service Enabled on the remote machine. Tested on Active
Perl 5.6+ and XP. Useful for maintaining inventory information. Usefull to find an instance of say a suspicious process on all ur systems on the network.

use strict;

use Win32::OLE(‘in’);

use constant wbemFlagReturnImmediately => 0×10;
use constant wbemFlagForwardOnly => 0×20;

my @computers = (“localhost”);
foreach my $computer (@computers) {
print “\n”;
print “————————————————————\n”;
print “| Computer: $computer | \n”;
print “————————————————————\n”;

my $objWMIService = Win32::OLE->GetObject(“winmgmts:\\\\$computer\\root\\CIMV2″) or die “WMI connection failed.\n”;
my $colItems = $objWMIService->ExecQuery(“SELECT * FROM Win32_Process”, “WQL”,
wbemFlagReturnImmediately | wbemFlagForwardOnly);

foreach my $objItem (in $colItems) {
print “Caption: $objItem->{Caption}\n”;
print “CommandLine: $objItem->{CommandLine}\n”;
print “CreationClassName: $objItem->{CreationClassName}\n”;
print “CreationDate: $objItem->{CreationDate}\n”;
print “CSCreationClassName: $objItem->{CSCreationClassName}\n”;
print “CSName: $objItem->{CSName}\n”;
print “Description: $objItem->{Description}\n”;
print “ExecutablePath: $objItem->{ExecutablePath}\n”;
print “ExecutionState: $objItem->{ExecutionState}\n”;
print “Handle: $objItem->{Handle}\n”;
print “HandleCount: $objItem->{HandleCount}\n”;
print “InstallDate: $objItem->{InstallDate}\n”;
print “KernelModeTime: $objItem->{KernelModeTime}\n”;
print “MaximumWorkingSetSize: $objItem->{MaximumWorkingSetSize}\n”;
print “MinimumWorkingSetSize: $objItem->{MinimumWorkingSetSize}\n”;
print “Name: $objItem->{Name}\n”;
print “OSCreationClassName: $objItem->{OSCreationClassName}\n”;
print “OSName: $objItem->{OSName}\n”;
print “OtherOperationCount: $objItem->{OtherOperationCount}\n”;
print “OtherTransferCount: $objItem->{OtherTransferCount}\n”;
print “PageFaults: $objItem->{PageFaults}\n”;
print “PageFileUsage: $objItem->{PageFileUsage}\n”;
print “ParentProcessId: $objItem->{ParentProcessId}\n”;
print “PeakPageFileUsage: $objItem->{PeakPageFileUsage}\n”;
print “PeakVirtualSize: $objItem->{PeakVirtualSize}\n”;
print “PeakWorkingSetSize: $objItem->{PeakWorkingSetSize}\n”;
print “Priority: $objItem->{Priority}\n”;
print “PrivatePageCount: $objItem->{PrivatePageCount}\n”;
print “ProcessId: $objItem->{ProcessId}\n”;
print “QuotaNonPagedPoolUsage: $objItem->{QuotaNonPagedPoolUsage}\n”;
print “QuotaPagedPoolUsage: $objItem->{QuotaPagedPoolUsage}\n”;
print “QuotaPeakNonPagedPoolUsage: $objItem->{QuotaPeakNonPagedPoolUsage}\n”;
print “QuotaPeakPagedPoolUsage: $objItem->{QuotaPeakPagedPoolUsage}\n”;
print “ReadOperationCount: $objItem->{ReadOperationCount}\n”;
print “ReadTransferCount: $objItem->{ReadTransferCount}\n”;
print “SessionId: $objItem->{SessionId}\n”;
print “Status: $objItem->{Status}\n”;
print “TerminationDate: $objItem->{TerminationDate}\n”;
print “ThreadCount: $objItem->{ThreadCount}\n”;
print “UserModeTime: $objItem->{UserModeTime}\n”;
print “VirtualSize: $objItem->{VirtualSize}\n”;
print “WindowsVersion: $objItem->{WindowsVersion}\n”;
print “WorkingSetSize: $objItem->{WorkingSetSize}\n”;
print “WriteOperationCount: $objItem->{WriteOperationCount}\n”;
print “WriteTransferCount: $objItem->{WriteTransferCount}\n”;
print “\n”;
}
}

Blogged with Flock

About these ads
Comments
  1. Montgomery Conner says:

    You might find something like the following useful… it abstracts away a lot of the hard-coding so that you can query ANY WMI class — not just the Win32_Process class — and you can query multiple classes in the same script very easily. Useful for tracking hardware, software, server metrics, and a lot more…

    ##################################################
    #! perl\bin\perl -w
    use strict;
    use Win32::OLE(‘in’);

    # supply a list of WMI classes to interrogate
    my @requests = (‘Win32_Process’, );

    # supply a list of computer systems to query
    my @computers = (“$ENV{COMPUTERNAME}”, );

    # Connect to each system’s CimV2 repository in turn.
    for my $computer( @computers ){
    my $wmi_repos = Win32::OLE->GetObject(“winmgmts:{impersonationLevel=impersonate}!\\\\$ENV{COMPUTERNAME}\\root\\CIMV2″)
    or die “WMI connection failed: “.Win32::OLE->LastError().”\n”;

    # Call to each desired Namespace in the current WMI repository.
    for my $request( @requests ){
    my $wmi_collection = $wmi_repos->ExecQuery(“SELECT * FROM $request”, “WQL”, 48 )
    or die “WQL query failed: “.Win32::OLE->LastError().”\n”;

    # For each member of the class, build a data-structure to hold its Methods and Properties.
    for my $item (in $wmi_collection){
    my @methods = join (“, “, map {$_->{Name}}( in $item->{Methods_} ) );
    my %properties = map { $_->{Name} => $_->{Value} }( in $item->{Properties_} );

    # Then format and print the results.
    print “\n$computer :: $request :: $properties{Name}\n”, “\tMethods: @methods\n\tProperties:\n”;
    for my $property( sort keys %properties ){
    ( $properties{$property} )
    ? print “\t\t$property = $properties{$property}\n”
    : print “\t\t$property =\n”;
    } } } }
    ##################################################

    …one of Perl’s main advantages (and main disadvantages) is it’s terse syntax. If you just translate VBScripts to Perl you’ll lose alot of the advantages that have caused people to use Perl to begin with. Hope you find this example helpful!

  2. Montgomery Conner says:

    EDIT: the following is a correction that enables an array of computer names to be used… replace $wmi_repos =…

    Win32::OLE->GetObject(”winmgmts:
    {impersonationLevel=impersonate}!\\\\$computer\\root\\CIMV2″)
    or die “WMI connection failed: “.Win32::OLE->LastError().”\n”;

    i.e. $ENV{COMPUTERNAME} –the local system–
    needs to be replaced with the looping $computer variable in the WQL query portion of the script.

    Sorry for any confusion.

  3. Steve says:

    Doesn’t work for me – I’ve checked that WMI service is running, tried both yours and Montgomery’s scripts (had to substitute non-ASCII characters after copying and pasting the above otherwise script wouldn’t compile).

    No errors returned by the OLE methods (i.e. doesn’t bomb out at the die statements), but the list of processes appears to be empty and length of wmi_collection is -1… and when I try to use “print Dumper $wmi_collection” (after loading Data::Dumper module) I get an OLE exception and unspecified error and the contents of the wmi_collection hash appear as this:

    $VAR1 = bless( {
    ‘Count’ => undef,
    ‘Security_’ => bless( {
    ‘ImpersonationLevel’ => 3,
    ‘AuthenticationLevel’ => 6,
    ‘Privileges’ => bless( {
    ‘Count’ => 0
    }, ‘Win32::OLE’
    )
    }, ‘Win32::OLE’ )
    }, ‘Win32::OLE’ );

    Can someone for who this works post what they get out for:
    print Dumper $wmi_collection;
    so I can compare?

    Thanks

  4. Montgomery Conner says:

    Steve,

    Data::Dumper is going to have problems with full OLE collection objects if you need to peek at any real data. So, you probably need to insert a print statement in the loop-block with the individual member $item, like so:

    for my $item ($wmi_collection){

    print Dumper $item;

    }

    But, I have no idea why these scripts would be failing for you (and silently at that)… good luck.

    BTW, you are running this against your local machine to test it, right? I’ve seen remote connections to WMI fail if ther’s port blocking or something like that…

  5. Montgomery Conner says:

    I really need to learn to proof read before I post… that code should have been:

    for my $item ( in $wmi_collection ){

    The ‘in’ is win32::OLE’s collection magic…

  6. use Win32::OLE qw( in );
    use Win32::OLE::Variant;
    use Win32::IPConfig;
    use Socket ;

    #Purpose to start remote process :Usage: perl filename.pl exe_to_run.exe
    #usage : StartRemoteProcess 4FIL19273 changeSetting.exe IMMIDIATERUN 1

    #RUNAS /profile /user:userName “StartRemoteProcess Workstation ExecutableName.exe Argument1 Argument2 ″ | sanur password

    our $Machine = $ARGV[0];
    our @ARGV = @ARGV[1..$#ARGV] ; #cut the host’s name from the command line
    our $CLASS = “WinMgmts:{impersonationLevel=impersonate}!//$Machine”;
    main();

    sub main
    {
    getIpFromDomainName($Machine);
    my $success = startProc();
    my $counter = 0 ;
    while ( $success == 0 && $counter C:/Temp/TEMP/$Machine.txt” ) or
    die “cannot open $Machine.txt $! \n” ;
    print FH “$Machine failed to execute command :\n” ;

    foreach my $line (@ARGV)
    { chop($_);
    print FH “$_ ” ;
    }
    close FH ;
    }
    }
    sub getIpFromDomainName
    {
    my $host = shift ;
    my $hostIp = () ; #the ip of the host we are going to return
    my $address = gethostbyname(“$host”) ;
    # print gethostbyname($_) , “\n” ;
    print inet_ntoa($address) , “\n” ;
    $hostIp = inet_ntoa($address) ;
    return $hostIp ;
    #eof sub getIpFromDomainName
    }
    sub startProc
    { #todo

    my $hostIp = getIpFromDomainName($Machine);
    $WMI = Win32::OLE-> GetObject( $CLASS ) || die “Unable to connect to
    $Machine:” . Win32::OLE->lastError();

    $PROCESSSTARTUP = $WMI-> Get(“Win32_ProcessStartup”)->SpawnInstance_;

    $PROCESSSTARTUP-> {WinstationDesktop} = “winsta0\\default”;

    $PROCESSSTARTUP-> {ShowWindow} = 1;

    print “$PROCESSSTARTUP-> {WinstationDesktop}\n”;

    $Process = $WMI-> Get( “Win32_Process” ) || die “Unable to get the
    process list:” . Win32::OLE-> LastError();

    $vPid = Variant( VT_I4 | VT_BYREF, 0 );

    if( 0 == $Process-> Create( join( ” “, @ARGV ), undef,
    $PROCESSSTARTUP, $vPid ) ) {
    print “PID $vPid\n”;
    sleep 2 ;

    return 1 ;
    }
    else
    {
    print “Failed .\n”;
    sleep 2 ;
    return 0 ;
    }

    } #eof startProc

  7. This was kind a out of the subject but hei it uses the same Win::OLE magic ..

  8. Oh my god loved reading your article. I added your rss to my google reader.

  9. IS there any way to find what exactly running into the process.
    For example i have opened IE .
    then can i find the url which is being opened using the IE..
    please help me ..
    i want to implement this.
    I want to find the urls currently opened into the IE or other browsers of the remote machine

  10. Lance says:

    An additional issue is that video gaming has become one of the all-time
    most important forms of recreation for people of various age groups.
    Kids engage in video games, and adults do, too.
    The particular XBox 360 is amongst the favorite video games systems for many who love to have hundreds of video games available to them, and who like to learn live with people all over
    the world. Thank you for sharing your thinking.

  11. Hello, this weekend is pleasant in favor of me, for the
    reason that this occasion i am reading this enormous informative post here at my home.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s