#!/fellow/monks.pl

I had to execute some batch files on a number of Windoze servers, but unfortunatly, Windoze is not blessed with an rexec process like Unix...

I wipped up this script to do the trick. You need to provide it with the server name, and script name, and optionally, a username and password. It will then authenticate to the box, read the time, and schedule the script to run two minutes later. Within a couple of minutes, your script/program will be executed.

You may need to use the full username (eg. DOMAIN\username). If you don't specify the username, the script will try to logon using your current credentials. This script is for Windows systems only.

#!/usr/bin/perl # 1 = server name (FQDN) # 2 = script name (on remote machine) # 3 = username (if any) # 4 = Password (if you specified a username) if($ARGV[0] eq "") { print <<HELP; $0 Execute programs on remote Windows NT/2k boxes. Usage : $0 [servername] [program name] {username} {password} servername == MANDATORY == Provide the server name (Netbios or FQDN, + or even IP) program name == MANDATORY == Provide the program name to execute, for example "c:\\temp\\runme.bat" {username} == OPTIONAL == Provide the username to use, either DOMAIN\\USERNAME or just USERNAME {password} == OPTIONAL == If you provide a username, you have to give the password Note: If you don't provide a username, a connection will be made using your current logged on credentials. Phillip Massyn Freeware January 2003 http://phillipmassyn.tripod.com HELP ; exit(1); } &execute($ARGV[0],$ARGV[1],$ARGV[2],$ARGV[3]); sub execute { $server = $_[0]; $scriptname = $_[1]; $user = $_[2]; $password = $_[3]; $it = 2; #--------------------------------------------------------------------- +------------------ #--------------------------------------------------------------------- +------------------ #--------------------------------------------------------------------- +------------------ #Authenticate if($user ne "") { $a = `net use \\\\$server\\ipc\$ /user:$user $password 2>&1`; } else { $a = `net use \\\\$server\\ipc\$ 2>&1`; } if($? != 0) { print "Could not authenticate!\n"; print "===========================================\n"; print "$a\n"; print "===========================================\n"; exit(1); } else { print "Authenticated to $server.\n"; } #--------------------------------------------------------------------- +------------------ #Get local time $a = `net time \\\\$server 2>&1`; if($? != 0) { print "Could not get local time!\n"; print "===========================================\n"; print "$a\n"; print "===========================================\n"; exit(1); } else { print "Got local time.\n"; } #--------------------------------------------------------------------- +------------------ #Calculate scheduled time local $sched = &increasetime(&readtime($a),$it); #--------------------------------------------------------------------- +------------------ #Schedule script #at \\\\$server $sched \" $aa = "at \\\\$server $sched \"$scriptname\" 2>&1"; print "Executing ==> $aa\n"; $a =`$aa`; if($? != 0) { print "Could not schedule execution!\n"; print "===========================================\n"; print "$a\n"; print "===========================================\n"; exit(1); } else { print "Execution scheduled for $sched.\n"; } #--------------------------------------------------------------------- +------------------ #Disconnect $a = `net use \\\\$server\\ipc\$ /delete 2>&1`; if($? != 0) { print "Could not disconnect!\n"; print "===========================================\n"; print "$a\n"; print "===========================================\n"; exit(1); } else { print "Disconnected.\n"; } } #--------------------------------------------------------------------- +------------------ #--------------------------------------------------------------------- +------------------ #--------------------------------------------------------------------- +------------------ sub increasetime { local $tme = $_[0]; local $increment = $_[1]; local ($hour,$min) = split(/:/,$tme); $min = $min + $increment; while($min > 59) { $min = $min - 60; $hour++; } if(length($min) == 1) { $min = "0$min"; } return "$hour:$min"; } sub readtime { local $txt = $_[0]; local $i; local $j; foreach $i (split(/\n/,$txt)) { if(index($i,"time") != -1) { $j = $i; } } local ($junk,$fulltime) = split(/is /,$j); local ($dte,$tme,$pm) = split(/ /,$fulltime); local ($hour,$min) = split(/:/,$tme); if((index($pm,"PM") != -1) && ($hour != 12)) { $hour = $hour + 12; } $nt = "$hour:$min"; return "$nt"; }

Thanks!

#!/massyn.pl The early worm gets caught by the bird.

Replies are listed 'Best First'.
Re: Running tasks on remote Windows machines
by Aristotle (Chancellor) on Jan 15, 2003 at 22:22 UTC

    Have a look Mark-Jason Dominus' Coping with Scoping article or broquaint's Lexical scoping like a fox. Basically, just about everywhere you're using local you should have used my instead. Please read at least one of these articles, then enable strict and warnings for your script and make it work under these constraints - it's not a lot of work when you've done it once or twice, and you'll be much much safer.

    Also, my eye starts twitching when I see things like

    local ($junk,$fulltime) = split(/is /,$j); Please please don't do that. Whenever you read a variable name like $junk, $trash or similar, all alarms should go off at full volume. What you want in this particulae case is my ($fulltime) = $j =~ /is (.*)/; All the other similar instances can be rephrased along the same lines.

    Makeshifts last the longest.

Re: Running tasks on remote Windows machines
by draper7 (Scribe) on Jan 15, 2003 at 18:57 UTC
    Massyn,

      Looks pretty good. I wrote something a while back similar to this but it schedules "rdisk" (ERD) on our NT/2000 server's and then copies the files back to a central location. My sugesstions:

  • Before scheduling a job the "Schedule" service needs to be running. Check it using Win32::Service.

  • Try using Win32::AdminMisc::ScheduleAdd to schedule jobs.

  • Does anyone know of a better way to get time from a windows machine other than "net time"? I've tried the Net::Time module but I couldn't get it to work correctly.


    --JD

      Win32::AdminMisc::ScheduleAdd has problems when you run against the W2K TaskScheduler. Dave has not had time to update his mods lately.

      There is a sourceforge project called TaskScheduler that is pretty slick.

      I've used:
      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; my $time = localtime; print "$time";
      to print out time on a 2kServer before
Re: Running tasks on remote Windows machines
by 2mths (Beadle) on Mar 10, 2003 at 10:20 UTC
    As I live and work on Windoze I might have got the wrong end of this stick. It looks like you want a way to execute something on a remote (Windoze) machine.

    I think you'll find that Windoze does have a service similar to Rexec (a bold statement given I don't actually know what Rexec is) it's called "Remote CMD Service" and you need the NTReskit to install it. Once installed and with the service running you can use RCMD.exe to issue remote commands to the box.

    In case anyone is actually interested in this, an alternative and simpler solution can be found at http://www.sysinternals.com/ntw2k/freeware/pstools.shtml
    PsExec will do what is wanted here, without the need to have any service installed or started. (The other tools are also most usefull in general NT support).
    I use both tools generally and in my scripts (Software distribution and general reporting).

    I am a scripter, I know I am only a scripter, but I like scripting and I can't program
      True... but in our environment, we have a standard image of Windows 2000 servers, with over 1000 servers world wide already, and still growing. In an environment this big, you can't go and load services without approval. With this method, it works, regardless of what services are installed. Now that's a bold statement -- The script still requires the windows scheduler service to be installed and running.

      This script was just one of those things that makes my life easier.. I might as well share it..