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

Hello, I have pieced together several scripts from other people and have a script that will open a notes database, read through the email, parse out specific information, and write this information to a file.

I still have 2 steps to perform. First I need to find a way to pass the password to the notes client logon, and delete the email that the script parsed.

I am not able to find any samples of these to steps on the internet and was hoping that someone on this forum might be able to help me.

One thought I had for the logon issue might be to launch the client and somehow look for the logon window to appear and enter the password once it does.

Any help would be very appreciated. Thanks in advance

#use strict; use English; use warnings; use vars qw($opt_d $opt_v); use Getopt::Std; use Win32::OLE; use Win32::PerfLib; use Win32::API; use Win32::Process::Info; my %counter; my %r_counter; my $TOKEN_QUERY; my $TOKEN_ADJUST_PRIVILEGES; my $SE_PRIVILEGE_ENABLED; my $PROCESS_TERMINATE; my $SE_DEBUG_NAME; my $GetCurrentProcess; my $OpenProcessToken; my $LookupPrivilegeValue; my $AdjustTokenPrivileges; my $OpenProcess; my $TerminateProcess; my $CloseHandle; my $myserver = "xxxxxxx"; my $mydatabase = "mail/xxxxxxx.nsf"; # Define a directory to store the results my $dir = 'D:/PerlTestFolder/Notes'; # Define a list of "Normal" folders to skip my @badlist = ('_Archiving', 'Archiving\\Age of Documents', 'Discussio +n Threads', 'Events'); # Auto-print carriage returns $OUTPUT_RECORD_SEPARATOR = "\n"; # Open the email database in Lotus Notes my $notes = Win32::OLE->new('Notes.NotesSession', 'Quit') or die "Can' +t open Lotus Notes"; my $database = $notes->GetDatabase($myserver,$mydatabase); $database->OpenMail; # Verify the server connection print "Connected to ", $database->{Title}, " on ", $database->{Server} +if $opt_v; # Loop over all of the folders foreach my $viewname (GetViews($database)) { # Get the object for this View print "Checking folder $viewname..."; my $view = $database->GetView($viewname); # Create a subdirectory to store the messages in $viewname =~ tr/()$//d; $viewname =~ s(\\)(.)g; chdir ($dir); # Get the first document in the folder my $num = 1; my $doc = $view->GetFirstDocument; next unless $doc; GetInfo($num, $dir, $doc); # Get the remaining documents in the folder while ($doc = $view->GetNextDocument($doc)) { $num++; GetInfo($num, $dir, $doc); } } #kill_process("notes2.exe"); sub GetInfo { my ($num, $path, $doc) = @_; my $subject = $doc->{Subject}->[0]; #Debug helper #print "Processing message $subject"; if ($subject =~ m/ISCD Notification/){ if ($subject =~ m/ISCD Notification Start/) { parseemail($num, $path, $doc, "Start", "", $subject); } elsif ($subject =~ m/ISCD Notification Stop/) { my $nid = ""; $nid = substr $subject, 22; parseemail($num, $path, $doc, "Stop", $nid, $subject); } } } sub GetViews { my ($database) = @_; my @views = (); # Loop through all of the views in this database my $array_ref = $database->{Views}; foreach my $view (@$array_ref) { my $name = $view->{Name}; # We only want folders if it's the Inbox # or a normal folder name with no parentheses if (($name eq '($Inbox)')){ # --Change to read only inbox-- #To read all folders, line above should be "if (($name eq +'($Inbox)') or ($name !~ /\(.+\)/)) {" # Add the folder name to the @views list # if it's not in the @badlist push(@views, $name) unless (grep { $name eq $_ } @badlist) +; } if (($name eq '($Inbox)') or ($name !~ /\(.+\)/)) { } } return @views; } sub parseemail{ my ($num, $path, $doc, $type, $nid, $subject) = @_; my $body = $doc->{Body}; my $service = ""; my $org = ""; my $geo = ""; my $dur = ""; my $text = ""; my @lines = split /\n/, $body; foreach my $line (@lines) { if ($line =~ m/Service:/){ $service = substr $line, 8; $service =~ s/^\s+//; $service =~ s/\s+$//; } if ($line =~ m/Organization:/){ $org = substr $line, 13; $org =~ s/^\s+//; $org =~ s/\s+$//; } if ($line =~ m/Geography:/){ $geo = substr $line, 10; $geo =~ s/^\s+//; $geo =~ s/\s+$//; } if ($line =~ m/Duration:/){ $dur = substr $line, 9; $dur =~ s/^\s+//; $dur =~ s/\s+$//; } if ($line =~ m/Text:/){ $text = substr $line, 5; $text =~ s/^\s+//; $text =~ s/\s+$//; } } print "\"$type\",\"$nid\",\"$service\",\"$org\",\"$geo\",\"$du +r\",\"$text\""; # Write the contents of the message to a file my $filename = "ISCD_Notification_$num.txt"; open (TEXTFILE, ">$path/$filename") or die "Can't create $path $fi +lename: $!"; print TEXTFILE "\"$type\",\"$nid\",\"$service\",\"$org\",\"$geo\", +\"$dur\",\"$text\""; close TEXTFILE; } sub kill_process { my $process = shift; my $result = 0; my $pid = getpid($process); if ($pid){ if (kill_pid($pid)){ print "Process=Successfully killed $process\n"; } else{ print "Process=Cannot kill $process\n"; } } else{ print "Process=$process not found\n"; } } sub getpid { my $process = shift; my $server = $ENV{COMPUTERNAME}; my $pid; Win32::PerfLib::GetCounterNames($server, \%counter); %r_counter = map { $counter{$_} => $_ } keys %counter; my $process_obj = $r_counter{Process}; my $process_id = $r_counter{'ID Process'}; my $perflib = new Win32::PerfLib($server) || return 0; my $proc_ref = {}; $perflib->GetObjectList($process_obj, $proc_ref); $perflib->Close(); my $instance_ref = $proc_ref->{Objects}->{$process_obj}->{Instance +s}; foreach my $p (sort keys %{$instance_ref}){ my $counter_ref = $instance_ref->{$p}->{Counters}; foreach my $i (keys %{$counter_ref}){ if($counter_ref->{$i}->{CounterNameTitleIndex} == $process_id && $instance_ref->{$p}->{Name} eq $process) +{ $pid = $counter_ref->{$i}->{Counter}; last; } } } #try again using a different approach WMI unless ($pid){ if (my $pi = Win32::Process::Info->new($server)){ my $processes = $pi->GetProcInfo(); my $number = @$processes; foreach (@$processes){ if ($_->{Name} =~ /$process/i){ $pid = $_->{ProcessId}; } } } } $pid?return $pid:return 0; } sub pidalive { my $pid = shift; my $server = $ENV{COMPUTERNAME}; Win32::PerfLib::GetCounterNames($server, \%counter); %r_counter = map { $counter{$_} => $_ } keys %counter; my $process_obj = $r_counter{Process}; my $process_id = $r_counter{'ID Process'}; my $perflib = new Win32::PerfLib($server) || return 0; my $proc_ref = {}; $perflib->GetObjectList($process_obj, $proc_ref); $perflib->Close(); my $instance_ref = $proc_ref->{Objects}->{$process_obj}->{Instance +s}; foreach my $p (sort keys %{$instance_ref}){ my $counter_ref = $instance_ref->{$p}->{Counters}; foreach my $i (keys %{$counter_ref}){ if ($counter_ref->{$i}->{Counter} == $pid){ return $pid; } } } return 0; } sub kill { my $process = shift; my $pid = getpid($process); if ($pid){ Configure(); my $iResult = ForceKill( $pid ); return 1 if( $iResult ); } return 0; } sub kill_pid { my $pid = shift; Configure(); my $iResult = ForceKill( $pid ); return 1 if( $iResult ); return 0; } sub ForceKill { my( $Pid ) = @_; my $iResult = 0; my $phToken = pack( "L", 0 ); # Fetch the process's token if($OpenProcessToken->Call($GetCurrentProcess->Call(), $TOKEN_ADJU +ST_PRIVILEGES | $TOKEN_QUERY, $phToken )){ my $hToken = unpack( "L", $phToken ); # Set the debug privilege on the token if( SetPrivilege( $hToken, $SE_DEBUG_NAME, 1 ) ){ # Now that we have debug privileges on the process # open the process so we can mess with it. my $hProcess = $OpenProcess->Call( $PROCESS_TERMINATE, 0, +$Pid ); if( $hProcess ){ # We no longer need the debug privilege since we have +opened # the process so remove the privilege. SetPrivilege( $hToken, $SE_DEBUG_NAME, 0 ); # Let's termiante the process $iResult = $TerminateProcess->Call( $hProcess, 0 ); $CloseHandle->Call( $hProcess ); } } $CloseHandle->Call( $hToken ); } return $iResult; } sub SetPrivilege { my( $hToken, $pszPriv, $bSetFlag ) = @_; my $pLuid = pack( "Ll", 0, 0 ); my $iResult; # Lookup the LIUD of the privilege if( $LookupPrivilegeValue->Call( "\x00\x00", $pszPriv, $pLuid ) ){ # Unpack the LUID my $pPrivStruct = pack( "LLlL", 1, unpack( "Ll", $pLuid ), ( ( $bSetFlag )? $SE_PRIVILEGE_ENABLED +: 0 ) ); # Now modify the process's token to set the required privilege $iResult = ( 0 != $AdjustTokenPrivileges->Call( $hToken, 0, $pPrivStruct, length( $pPrivS +truct ), 0, 0 ) ); } return $iResult; } sub Configure { $TOKEN_QUERY = 0x0008; $TOKEN_ADJUST_PRIVILEGES = 0x0020; $SE_PRIVILEGE_ENABLED = 0x02; $PROCESS_TERMINATE = 0x0001; $SE_DEBUG_NAME = "SeDebugPrivilege"; # Prepare to use some specialized Win32 API calls $GetCurrentProcess = new Win32::API( 'Kernel32.dll', 'GetCurre +ntProcess', [], N ) || die; $OpenProcessToken = new Win32::API( 'AdvApi32.dll', 'OpenProc +essToken', [N,N,P], I ) || die; $LookupPrivilegeValue = new Win32::API( 'AdvApi32.dll', 'LookupPr +ivilegeValue', [P,P,P], I ) || die; $AdjustTokenPrivileges = new Win32::API( 'AdvApi32.dll', 'AdjustTo +kenPrivileges', [N,I,P,N,P,P], I ) || die; $OpenProcess = new Win32::API( 'Kernel32.dll', 'OpenProc +ess', [N,I,N], N ) || die; $TerminateProcess = new Win32::API( 'Kernel32.dll', 'Terminat +eProcess', [N,I], I ) || die; $CloseHandle = new Win32::API( 'Kernel32.dll', 'CloseHan +dle', [N], I ) || die; }