Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Windows Scheduler Issues

by seigniory (Sexton)
on Mar 30, 2001 at 03:19 UTC ( [id://68232]=perlquestion: print w/replies, xml ) Need Help??

seigniory has asked for the wisdom of the Perl Monks concerning the following question:

I have a script running on a utility server that works flawlessly when run interactively on a Windows 2000 machine. If I double-click on it, or run it at the command line everything is fine. When I schedule it, only part of the script seems to function. Here's the detail: The machine has a share from a remote machine mapped to a local drive. The share contains a bunch of IIS logs. The script is to go into that drive, recurse through all the directories, zip up all the log files, delete the originals if successful, and then email me the results of its actions. Like I said, when I double click the script it works fine. I'm using the command-line interface to WinZip in the following format to a) kick off the zipping and to store the results of it in $result. Here's the script:
########################################################### # IIS Log File Archiver # Resurses through directories and zips all files, # removes the old file if successful, then emails a # detailed log file to the specified email address. ########################################################### $directory = 'K:\'; $zipApp = 'D:\IISArchive\wzzip.exe'; $logFile = ''; $SMTPServer = '10.0.1.2'; $mailTo = 'me@me.com'; $reportSubject = 'Daily IISArchive Report'; ########################################################### use Socket; $|++; &recurseDirectory($directory); &emailLogFile(); exit; ########################################################### sub recurseDirectory { my $zipApp = 'D:\IISArchive\wzzip.exe'; my $thisDirectory = $_[0] . "\\"; opendir (THISDIR, $thisDirectory); my @theseContents = readdir (THISDIR); closedir (THISDIR); foreach my $item (@theseContents) { if (!($item =~ /\.zip$/)) { if (!($item =~ /^\./)) { my $temp = $thisDirectory.$item; if (-d $temp) { $::logFile .= "\n_____________________\n$item\ +n"; &recurseDirectory($temp); } else { my $tempZipped = $temp; $tempZipped =~ s/\.log/\.zip/g; if (&notTodaysLogFile($item)) { $::logFile .= "$::zipApp \"$tempZipped\" \ +"$temp\"\n"; my $result = `$::zipApp -m \"$tempZipped\" + \"$temp\"\n`; $::logFile .= $result."\n"; if ($result =~ /Unable to erase the file:/ +) { unlink($tempZipped); } } else { $::logFile .= " --> Skipping today's log f +ile, $item\n"; } } } } } } ########################################################### sub notTodaysLogFile { my @times = localtime(time); $times[5] = $times[5] - 100; if ($times[5] < 10) { $times[5] = "0".$times[5]; } $times[4]++; if ($times[4] < 10) { $times[4] = "0".$times[4]; } if ($times[3] < 10) { $times[3] = "0".$times[3]; } if ($_[0] =~ /$times[5]$times[4]$times[3]\.log/) { return 0; } else { return 1; } } ########################################################### sub emailLogFile { my $smtp_server = $::SMTPServer; my $pop_server = $smtp_server; my $to = $::mailTo; my $subject = $::reportSubject; my $message = $::logFile; my $proto = getprotobyname('tcp'); socket(SOCK, AF_INET, SOCK_STREAM, $proto); my $iaddr = gethostbyname($smtp_server); my $port = getservbyname('smtp', 'tcp'); my $sin = sockaddr_in($port, $iaddr); connect(SOCK, $sin); my $err = ''; send SOCK, "HELO localhost\r\n", 0; recv SOCK, $junk, 512, 0; if ($junk =~ /^5/) {$err = "true";} send SOCK, "mail from: <IISArchive\@webloyalty.com>\r\n", 0; recv SOCK, $poo, 512, 0; if ($poo =~ /^5/) {$err = "true";} send SOCK, "RCPT To:<$to>\r\n", 0; recv SOCK, $poo, 512, 0; if ($poo =~ /^5/) {$err = "true";} send SOCK, "DATA\r\n", 0; recv SOCK, $poo, 512, 0; if ($poo =~ /^5/) {$err = "true";} send SOCK, "From: IISArchive\@webloyalty.com\r\n", 0; send SOCK, "Date: ".localtime()."\r\n", 0; send SOCK, "To: $to\r\n", 0; send SOCK, "Subject: $subject\r\n", 0; send SOCK, "\r\n$message\r\n.\r\n", 0; recv SOCK, $poo, 512, 0; if ($poo =~ /^5/) {$err = "Yes";} send SOCK, "QUIT\r\n", 0; recv SOCK, $poo, 512, 0; if ($poo =~ /^5/) {$err = "Yes";} close SOCK; }
Why won't this program work when scheduled? All I get is a blank email, so I know the script is trying to run. And yes, I know it's rather ugly and I should really use the Net:SMTP object, but I'm not trying to be too pretty right now... build the walls and roof first, put the furniture in after it's watertight. Thanks in advance -- Matt

Replies are listed 'Best First'.
(tye)Re: Windows Scheduler Issues
by tye (Sage) on Mar 30, 2001 at 03:32 UTC

    Stuff run from the scheduler probably gets a different security context which doesn't give it any access to network shares.

    You can try LogonUser() followed by CreateProcessAsUser() (see Win32::AdminMisc from http://www.roth.net/, perhaps) or you can try to configure the scheduler service to run as a specific user (which still might not be enough).

            - tye (but my friends call me "Tye")
      Actually, I have tried everything I can think of as far as permissions go - even so far as to try the Domain administrator account and the local administrator account. No dice.

        Well, I did say "and that might not be enough" ):

        The scheduler may start jobs in a different security context than its own (you did stop and restart it, right?) and then you can be "domain admin" but have a security context that allows no net access.

        You could look for configuration options in the scheduler to see if you can configure what type of security context it lauches its jobs.

        You could skip using the scheduler and just have a Perl script running as a service.

        You could try using Win32::NetResource to specify a username and password to the share in order to access the files.

        You could try the LogonUser() and CreateProcessAsUser() thing.

        You could also do some debugging to figure out where the script is dying. For example, redirect STDOUT and STDERR to a file inside a BEGIN block at the top of the script and print status messages.

                - tye (but my friends call me "Tye")
Re: Windows Scheduler Issues
by wardk (Deacon) on Mar 30, 2001 at 05:26 UTC

    I had to deal with this about 2 years ago. my foggy recollection is that schedule jobs run as "System", and the "system" user has absolutely zero rights on other machines (but is like root on the local). You cannot get the system account priviledges set for other machines, so logging in as another user is required.

    I am pretty sure I used the module mentioned by tye, but in effect, what I had to do was startup and then login/alias myself as a user that had priviledges on the target shares. I do remember it was a real pain in the ass (I recall swearing alot and damning all things windows to eternal hell), and ended up finding an alternative solution. I wish I could be more helpful, but it's been too long and I don't have any of that code.

    if you can manage to get this going, I'd certainly ++ your tutorial :-)

    PS: since it runs from an icon, maybe you need that rocking monkey toy that Homer Simpson used to tap his keyboard in order to keep the nuclear reactor from melting down? (oh wait, that didn't work) :-)

Re: Windows Scheduler Issues
by myocom (Deacon) on Mar 30, 2001 at 04:15 UTC

    You might try putting in some debug prints to a log file you could check later (the contents of the %Env hash might be particularly useful if you suspect it's a security problem.

    And while you say you're not trying to be too pretty yet, it strikes me as significantly easier to use one of the several mail modules (which would make it easier to debug, as well!) instead of doing raw socket writes. You might also investigate Archive::Zip (and Compress::Zlib) to do your zipping for you, too.

    There's something to be said for building the walls and the roof out of pre-cut lumber rather than trees you uproot yourself.

(jcwren) Re: Windows Scheduler Issues
by jcwren (Prior) on Mar 30, 2001 at 19:18 UTC

    I had a similiar problem under NT4.0. The problem was that the Scheduler task normally runs as 'System Account', a user with few priviledges. What I did to solve it was go into Start->Control Panel->Services, double-click on 'Scheduler', select the radio button for 'Log on as', and set the account/password you want the scheduler to run as.

    I don't remember if that changes the scheduler instance only for jobs created by that user, or if other jobs scheduled by other users will now run under that account. I treat NT/Win2K as a single user system, not a casual terminal that people can log into, so I can't say.

    I fought with this when it came to sharing drives. Everything was working fine, except I couldn't access a shared network resource. Anyway, I'm imagining that Win2K has something similiar, since it's so heavily NT based.

    Update: Win2K has a similiar facility. Goto Start->Control Panel->Adminstrative Tools->Services. Scroll down and double-click 'RunAs Service', and select the 'Log On' tab.

    --Chris

    e-mail jcwren
      Windows 2000 won't let you run the scheduler in the context of another account - it fails to start with the message "Run individual jobs in the context of the desired account" message. I also tried wrapping it in a batch file - same deal - when the batch file is double clicked, it works, when it's scheduled, it's not. I'm going to try a different file schedule utility - winat maybe - I'll keep you posted.

        "Run individual jobs in the context of the desired account"

        ...which seems to imply that you can configure what security context you want each job to run it. That sounds like the easiest solution if you can just find where that is documented.

                - tye (but my friends call me "Tye")
Re: Windows Scheduler Issues
by c-era (Curate) on Mar 30, 2001 at 18:57 UTC
    I've had this problem in the past, what is happening is that when the workstation is not logged in, or another user is logged in, the K: share is not mapped. There is a way to force a share to always be mapped, even when nobody is logged in. I remember how this is done, but mabey someone else will. I'll also try doing a search to find what needed to be done.

    UPDATE: I remembered what is was, it wasn't the network path. I had to wrap the perl script with a batch file. This was the batch file:

    d:\perl\bin\perl.exe c:\path\script.pl
    Using this with the run as checked the script would work.
Re: Windows Scheduler Issues
by jorg (Friar) on Mar 30, 2001 at 19:01 UTC
    I have no solution to your problem so you might not be interested in this post (by the looks of it wardk seems to know what he's talking about).
    What struck me in your code is you style of Perl coding in this script is very similar to my style about a year ago (before i started using it nearly on a daily basis).
    So at the risk of getting flamed for posting besides the issue, here are a few (hopefully) helpfull pointers that will make your perl neater and shorter *cough

    You can flatten your foreach loop :
    foreach my $item (@theseContents) { if (!($item =~ /\.zip$/)) { if (!($item =~ /^\./)) { my $temp = $thisDirectory.$item; if (-d $temp) { ....... } } } }
    would become (in a more perl-ish way)
    foreach my $item(@theseContents){ next unless ($item =~ /\.zip$/); next unless ($item =~ /^\./); ..... rest_of_code ...... }
    This will already eliminate two levels of brackets, making your source more readable.

    Your notTodaysLogFile sub could (not saying should) be shortened up to:
    my $file = shift; #grab the first arg to the sub my $todayfile = sprintf("%02d%02d%02d\.log", $times[5]-100,$times[4]+1, $times[3]); #then your exit routine


    Jorg

    "Do or do not, there is no try" -- Yoda

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://68232]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2024-04-19 12:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found