http://qs321.pair.com?node_id=320634
Category: Win32 Stuff
Author/Contact Info Mark Anderson maa
Description:

I have often seen the wuation "how do I start a remote process on windows using Perl?" posted here. Personally, I use PSExec with a perl wrapper around it but that's not suitable for everyone.

This script is does the job (simply) using Win32::OLE and the native WMI (see MSDN for info).

For use in a corporate environment you should probably use Win32::EventLog to record what you did!

#!C:/ActivePerl/bin/perl.exe
use strict;
use warnings;
use Win32::OLE qw/in/;
use Getopt::Long;
#
#How to run a process on a remote workstation (NT/2K)
#
my ($remote_computer, $command_path, $help);
GetOptions ('r:s'=>\$remote_computer,
            'c:s'=>\$command_path,
            'h'  =>\$help )
            or warn("Couldn't read arguments.\n");

help_and_exit() if ($help);            
help_and_exit() if (!defined($remote_computer) || !defined($command_pa
+th) );

my $wmihandle    = Win32::OLE->GetObject( "winmgmts:{impersonationLeve
+l=impersonate,(security)}//$remote_computer\\root\\cimv2");
my $wmiprocesses = Win32::OLE->GetObject( "winmgmts:{impersonationLeve
+l=impersonate,(security)}//$remote_computer\\root\\cimv2:Win32_Proces
+s");

#Is the process running already?
unless ( cmd_is_running($wmihandle,$command_path) ) {
   print "$command_path is not already running.\n";   
}

#This doesn't seem to be necessary but it's in the docs!
#http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmis
+dk/wmi/create_method_in_class_win32_process.asp
my $Startup_Class = $wmihandle->Get("Win32_ProcessStartup");
my $Startup_Config = $Startup_Class->SpawnInstance_ ;

my ($error, $pid, $startup_folder);
$startup_folder="\\\\cntr035533\\c\$\\TEMP\\";

#The Create() method returns 0 on success
if (0 == $wmiprocesses->Create($command_path) ) {

   $pid = $wmiprocesses->{'ProcessID'};
   if (! $pid) { 
      $pid = " [PID not available from Win32_Process.ProcessID]"; 
   }
   print "Successfully started command with pid $pid\n";   

}else{

   print "Failed to create process with Win32_Process.Create(cmd)\n";
   print "Trying Win32_Process.Create(cmdpath, startup, Win32_ProcessS
+tartup, processid)\n";
   $error = $wmiprocesses->Create($command_path,$startup_folder,$Start
+up_Config,$pid);

   #Error codes are 'explained' at the msdn link above.
   if ($error) {
      print "$command_path failed to start with WMI err: $error\n";   
+   
   }else{
      print "Started $command_path at 2nd attempt.\n";
   }
}

#Check to see that the process is running.
unless ( cmd_is_running($wmihandle,$command_path) ) {
   print "$command_path doesn't appear to be running.\n";   
}
  

#--- SUBS ---         
         
sub cmd_is_running{
   my ($wmi,$cmd) = @_;
   return undef if not defined($wmi);
   return undef if not defined($cmd);
   my $cmdname;
   if ( $cmd=~ /(?:\\|\/)*([^\\\/]+)$/ ) {
      $cmdname=uc($1);
   }else{
      print "Failed to get command name from $cmd\n";
      return 0;
   }      
   
   my $message = '';
   #Ask the WMI Class for a list of Processes
   foreach my $process (in($wmihandle->InstancesOf("Win32_Process"))) 
+{
      if (uc($process->{'Name'}) eq $cmdname ) {
         $message .= "$cmdname is running with PID = " . $process->{'P
+rocessID'} . "\n";   
      }
   }
   if ($message) {
      print $message
      return 1;
   }
   return 0;
}        

sub help_and_exit {
   print <<EOF;
$0

Syntax:
   -r <remote computername>
   -c <command> [Remember to use quotes if there are spaces!]
   -h print this and exit.
EOF

   exit(1);   
}   

__END__
  • Comment on How to Start a Process in a Remote Win32 Machine using Perl and WMI
  • Download Code
Replies are listed 'Best First'.
Re: How to Start a Process in a Remote Win32 Machine using Perl and WMI
by fio (Initiate) on Mar 05, 2014 at 17:07 UTC

    Hi, can you please explain this code? It's awesome, thanks.

      Hi, can you please explain this code?

      Hi, maa was last here five years ago

      Also, have you read perlintro? What is it exactly that needs explanation, and why?

        Hi since I posted i've done some research and things are starting to clear up I guess.

        At this point i'm just kind of stuck on winmgmt objects and how to create these with different parameters and what they all mean. Also, he seemed to initialize the objects with one statement opposed to the other way I've saw it done.

        my $obj = Win32::OLE->GetObject( 'winmgmts{impersonateLevel=impersonat +e}' ); foreach $process( in $obj->InstaceOf("Win32_Process")){ #iterate through the list of LOCAL processes }

        But he has added ...

        .. , (security)}//$remote_computer\\root\\cimv2");

        So idk at the moment winmgmt objects are confusing me and I don't know what documentation will clear this up or what to look at to find a parameter list and things for the meaning of cimv2. Also how he has constructed the objects for the remote servers is beyond me at this point and seems pretty slick. What do you think?I am trying to delve deeper into these windows objects I suppose. I am going to keep hacking away at it