535 lines
20 KiB
Perl
535 lines
20 KiB
Perl
|
#-----------------------------------------------------------------//
|
|||
|
# Script: access.pm
|
|||
|
#
|
|||
|
# (c) 2002 Microsoft Corporation. All rights reserved.
|
|||
|
#
|
|||
|
# decomposes the remote test boot installation run.
|
|||
|
#
|
|||
|
# Version: <2.31> 06/11/2002 : Serguei Kouzmine
|
|||
|
#
|
|||
|
#-----------------------------------------------------------------//
|
|||
|
|
|||
|
use strict;
|
|||
|
package access;
|
|||
|
|
|||
|
no strict 'refs';
|
|||
|
use vars (qw());
|
|||
|
use WMIFE qw($verbose);
|
|||
|
use Logmsg;
|
|||
|
use RemoteProc;
|
|||
|
use AutoBoottest;
|
|||
|
use vars (qw(
|
|||
|
$_ReleaseShare
|
|||
|
$_ToolShare
|
|||
|
$ToolShare
|
|||
|
$_BuildArch
|
|||
|
$_BldSku
|
|||
|
$ForceReboot
|
|||
|
$Lang
|
|||
|
$MasterMachine
|
|||
|
$MasterUserAccount
|
|||
|
$MasterUserPassword
|
|||
|
$SourcePath
|
|||
|
$TargetDrive
|
|||
|
$TargetMachine
|
|||
|
$TargetSystemDrive
|
|||
|
$TargetSystemRoot
|
|||
|
$TestUserAccount
|
|||
|
$TestUserPassword
|
|||
|
$Unattend
|
|||
|
$SourceIsDFS
|
|||
|
));
|
|||
|
|
|||
|
use Carp;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
my $USAGE =<<USAGE;
|
|||
|
Usage:
|
|||
|
&access::boottest(
|
|||
|
\$TargetMachine, # Target Machine name
|
|||
|
\$Lang, # language
|
|||
|
\$SourcePath, # Source Path in the form:
|
|||
|
\\\\<BUILDMACHINE>\\<RELEASE>\\<LANG>\\<BLDNAME>\\<SKU>\\<ARCH>
|
|||
|
or e.g.
|
|||
|
\\\\winbuilds\\release\\main\\usa\\latest.tst\\x86fre\\srv\\i386
|
|||
|
\$BuildArch # architecture
|
|||
|
\$BldSku # sku
|
|||
|
\$ToolShare # share to tools \\<BUILDMACHINE>\<TOOLS SHARE NAME>
|
|||
|
# leave this parameter undef in the case you use DFS
|
|||
|
\$TestUserAccount, # test user (leave empty for DFS install)
|
|||
|
\$TestUserPassword, # logon data (leave empty for DFS install)
|
|||
|
\$ForceReboot, # reboot switch (1: reboot, 0: don<6F>t)
|
|||
|
\$SourceIsDFS # this argument must be FALSE unless
|
|||
|
# source bits accessible through DFS (see also above)
|
|||
|
);
|
|||
|
USAGE
|
|||
|
|
|||
|
my $ToolPath = "NEWTOOLS";
|
|||
|
my $TIMEOUT = 5;
|
|||
|
my $UNATTEND = q(unattend.$_BuildArch.$_BldSku.txt);
|
|||
|
my $RELEASE = "RELEASE";
|
|||
|
my $TOOLSHARE = "BOOTTEST";
|
|||
|
my $PROCESS = "winnt32.exe";
|
|||
|
my $SERVICE = "SCHEDULE";
|
|||
|
my $TARGETDRIVE = "D:";
|
|||
|
my $TOOLDRIVE = "T:";
|
|||
|
my $RELEASEDRIVE = "Y:";
|
|||
|
|
|||
|
my $VERSION = "2.2";
|
|||
|
my $DEBUG = 0;
|
|||
|
|
|||
|
my $DELAY1 = 120;
|
|||
|
my $DELAY2 = 60;
|
|||
|
my $DELAY3 = 240;
|
|||
|
my $DELAY4 = 10;
|
|||
|
my $REPEAT = 30;
|
|||
|
my $SYSTEMROOT = $ENV{"SYSTEMROOT"};
|
|||
|
my $SYSTEMDRIVE = $ENV{"SYSTEMDRIVE"};
|
|||
|
|
|||
|
$ENV{"SCRIPT_NAME"} = "access.pm";
|
|||
|
my $Results;
|
|||
|
my @answ = ();
|
|||
|
my @Credentials = ("*");
|
|||
|
# start ...
|
|||
|
|
|||
|
$TargetMachine = undef;
|
|||
|
$SourcePath = undef;
|
|||
|
$TestUserAccount = undef;
|
|||
|
$TestUserPassword = undef;
|
|||
|
my $ToolsMachine = undef;
|
|||
|
|
|||
|
# Usage:
|
|||
|
# &access::boottest(
|
|||
|
# $TargetMachine, # Target Machine name
|
|||
|
# $SourcePath, # path to winnt32.exe, including DFS part name, e.g.
|
|||
|
#
|
|||
|
# \\winbuilds\release\main\usa\latest.tst\x86fre\srv\i386
|
|||
|
# (everything winnt32.exe copies must be in this location or directories therein)
|
|||
|
#
|
|||
|
# $BuildArch # architecture
|
|||
|
# $BldSku # sku
|
|||
|
# $ToolShare # share to tools is ignored in DFS case
|
|||
|
# $TestUserAccount, # test user is ignored in DFS case
|
|||
|
# $TestUserPassword, # logon data is ignored in DFS case
|
|||
|
# $Reboot # reboot switch (1: reboot, 0: don<6F>t)
|
|||
|
# $SourceIsDFS # this argument must be TRUE)
|
|||
|
#
|
|||
|
#
|
|||
|
#
|
|||
|
|
|||
|
sub boottest{
|
|||
|
|
|||
|
$TargetMachine = $_[0]; #$machinename
|
|||
|
$SourcePath = $_[1]; #path to winnt32
|
|||
|
$Lang = $_[2]; #lang
|
|||
|
$_BuildArch = $_[3]; #Architechture
|
|||
|
$_BldSku = $_[4]; #SKU
|
|||
|
$_ToolShare = $_[5]; #path to tools
|
|||
|
$Unattend = $_[6]; #unattend file name
|
|||
|
$TestUserAccount = $_[7]; #user for release/tools
|
|||
|
$TestUserPassword = $_[8]; #pass for user
|
|||
|
$ForceReboot = $_[9]; #Force a Reboot <=> DFS install
|
|||
|
|
|||
|
($MasterMachine, $_ReleaseShare) = $SourcePath =~ /\\\\([^\\]*)\\([^\\]*)\\.*/;
|
|||
|
($ToolsMachine, $ToolShare) = $_ToolShare =~ /\\\\([^\\]*)\\(.*)/;
|
|||
|
|
|||
|
$TargetDrive = $TARGETDRIVE;
|
|||
|
$WMIFE::DEBUG = $DEBUG;
|
|||
|
$WMIFE::TIMEOUT = $TIMEOUT;
|
|||
|
$MasterUserPassword = undef;
|
|||
|
$MasterUserAccount = $ENV{"USERDOMAIN"}."\\".$ENV{"USERNAME"};
|
|||
|
$Unattend = $UNATTEND;
|
|||
|
$Unattend =~ s/\$(\w+)\b/${$1}/eg;
|
|||
|
|
|||
|
die &WMIFE::pPpPinfo($USAGE) unless defined($TargetMachine);
|
|||
|
|
|||
|
@Credentials = ($MasterUserAccount, $MasterUserPassword)
|
|||
|
unless !$MasterUserPassword;
|
|||
|
|
|||
|
my $Process = $PROCESS;
|
|||
|
my $Service = $SERVICE;
|
|||
|
my $ToolDrive = $TOOLDRIVE;
|
|||
|
my $ReleaseDrive = $RELEASEDRIVE;
|
|||
|
my $sRootKey = $WMIFE::sRootKey;
|
|||
|
my $sBootTestDataSubKey = $WMIFE::sBootTestDataSubKey;
|
|||
|
my $sLogonUserDataSubKey = $WMIFE::sLogonUserDataSubKey;
|
|||
|
|
|||
|
my $answ;
|
|||
|
|
|||
|
$TargetSystemRoot = $SYSTEMROOT;
|
|||
|
$TargetSystemDrive = $SYSTEMDRIVE;
|
|||
|
|
|||
|
$Results = &WMIFE::ExecQuery($TargetMachine, # interactive session
|
|||
|
qq(SELECT * FROM Win32_operatingsystem),
|
|||
|
[qw(WindowsDirectory)],
|
|||
|
@Credentials);
|
|||
|
$TargetSystemRoot = $Results->[0]->{"WindowsDirectory"};
|
|||
|
$TargetSystemDrive = $TargetSystemRoot;
|
|||
|
$TargetSystemDrive =~ s/\\.*$//g;
|
|||
|
#=============================================================================
|
|||
|
|
|||
|
if ($SourceIsDFS){
|
|||
|
$ForceReboot = 0;
|
|||
|
$DEBUG = 1;
|
|||
|
my $hereIsStep;
|
|||
|
$hereIsStep =<<PROMPT4PASS;
|
|||
|
%SYSTEMROOT%\\SYSTEM32\\CSCRIPT.EXE %RAZZLETOOLPATH%\\POSTBUILDSCRIPTS\\wsh.iexplore.dialog.input.wsf
|
|||
|
rem Prompt the user for the password
|
|||
|
PROMPT4PASS
|
|||
|
$DEBUG and
|
|||
|
print $hereIsStep, "\n";
|
|||
|
my $userData = &WMIFE::BackTick($hereIsStep);
|
|||
|
my ($TestUserAccount) = $userData =~ m/BT_U\s+=\s+(.+)/g;
|
|||
|
my ($TestUserPassword) = $userData =~ m/BT_P\s+=\s+(.+)/g;
|
|||
|
$DEBUG and
|
|||
|
print STDERR $TestUserAccount,
|
|||
|
"\n",
|
|||
|
$TestUserPassword,
|
|||
|
"\n";
|
|||
|
my $ToolsToCopy = join(" ", qw(
|
|||
|
%RAZZLETOOLPATH%\\POSTBUILDSCRIPTS\\rx.wsf
|
|||
|
%RAZZLETOOLPATH%\\POSTBUILDSCRIPTS\\NTCrypt.exe
|
|||
|
)) ;
|
|||
|
$hereIsStep= <<COPYTOOLS;
|
|||
|
REM Creating the directory for tools
|
|||
|
md \\\\%TARGETMACHINE%\\%TARGETSYSTREMDRIVE%\\%TOOLPATH%
|
|||
|
REM copy everything to the tagret machine
|
|||
|
for %. in (%TOOLSTOCOPY%) do @(echo %. & copy %. \\\\%TARGETMACHINE%\\%TARGETSYSTREMDRIVE%\\%TOOLPATH%)
|
|||
|
|
|||
|
COPYTOOLS
|
|||
|
|
|||
|
my $_TargetSystemDrive = $TargetSystemDrive;
|
|||
|
$_TargetSystemDrive =~ s/\:/\$/;
|
|||
|
$hereIsStep =~ s/\%TARGETMACHINE\%/$TargetMachine/g;
|
|||
|
$hereIsStep =~ s/\%TARGETSYSTREMDRIVE\%/$_TargetSystemDrive/g;
|
|||
|
$hereIsStep =~ s/\%TOOLPATH\%/$ToolPath/g;
|
|||
|
|
|||
|
$hereIsStep =~ s/\%TOOLSTOCOPY\%/$ToolsToCopy/g;
|
|||
|
|
|||
|
print STDERR $hereIsStep, "\n";
|
|||
|
print &WMIFE::BackTick($hereIsStep);
|
|||
|
|
|||
|
} # $SourceIsDFS
|
|||
|
$answ = undef;
|
|||
|
if ($DEBUG){
|
|||
|
&logmsg( "Check pending jobs at \\\\$TargetMachine");
|
|||
|
|
|||
|
my $TasksPath = $TargetSystemRoot ."\\\\TASKS\\\\";
|
|||
|
$TasksPath =~ s/^\w:/\\/g;
|
|||
|
|
|||
|
$Results = &WMIFE::ExecQuery($TargetMachine,
|
|||
|
# task files
|
|||
|
"SELECT * FROM cim_DataFile WHERE Drive = \"$TargetSystemDrive\" AND Path = \"$TasksPath\" AND FileType Like \"Task Scheduler\%\"",
|
|||
|
[qw(FileName FileType Path)],
|
|||
|
@Credentials);
|
|||
|
|
|||
|
foreach my $Result (@$Results){
|
|||
|
$DEBUG and
|
|||
|
map {&WMIFE::FormatDebugMsg($_, $Result->{$_})}
|
|||
|
keys (%$Result);
|
|||
|
}
|
|||
|
@answ = ();
|
|||
|
map {push @answ, $_->{"FileName"}} @$Results;
|
|||
|
@answ = grep {/\S/} @answ;
|
|||
|
|
|||
|
$answ = \@answ;
|
|||
|
}
|
|||
|
|
|||
|
if ($ForceReboot){
|
|||
|
|
|||
|
&logmsg("Write $sLogonUserDataSubKey on \\\\$TargetMachine");
|
|||
|
&WMIFE::supplyRegData($TargetMachine,
|
|||
|
"SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\WINLOGON",
|
|||
|
{
|
|||
|
"DefaultUserName" => $TestUserAccount,
|
|||
|
"DefaultDomainName" => $TargetMachine,
|
|||
|
"DefaultPassword" => $TestUserPassword,
|
|||
|
"AutoAdminLogon" => "1",
|
|||
|
"ForceAutoLogon" => "1",
|
|||
|
"PasswordExpiryWarning" => "0",
|
|||
|
},
|
|||
|
{},
|
|||
|
1);
|
|||
|
|
|||
|
&logmsg("Reboot \\\\$TargetMachine to have $TestUserAccount logged");
|
|||
|
&WMIFE::ObjectExecMethod("Win32_Process",
|
|||
|
"Create",
|
|||
|
$TargetMachine,
|
|||
|
"CommandLine",
|
|||
|
"$TargetSystemRoot\\SYSTEM32\\cmd.exe /c USE $RELEASEDRIVE /D&net USE $TOOLDRIVE /D&net USE $TOOLDRIVE $_ToolShare $TestUserPassword /u:$MasterMachine\\$TestUserAccount&$TOOLDRIVE\\autologon.exe /MIGRATE&shutdown.exe /r /m \\\\$TargetMachine /f /t 0",
|
|||
|
@Credentials);
|
|||
|
|
|||
|
#Wait for system to shutdown & come back up
|
|||
|
AutoBoottest::WaitOnProcess($TargetMachine, "csrss.exe", -1, "", "");
|
|||
|
if(!AutoBoottest::WaitForProcess($TargetMachine, "services.exe", $DELAY3, "", "")){
|
|||
|
errmsg("Fatal error: $TargetMachine may have not restarted correctly");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
sleep($DELAY4); #give it another 10 secs just in case
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
&logmsg("Write $sBootTestDataSubKey on \\\\$TargetMachine");
|
|||
|
|
|||
|
&WMIFE::supplyRegData($TargetMachine,
|
|||
|
"SOFTWARE\\MICROSOFT\\BOOTTEST",
|
|||
|
{"LANG" => uc($Lang),
|
|||
|
"_BldSku" => uc($_BldSku),
|
|||
|
"_BldDrive" => $TargetDrive,
|
|||
|
"Unattend" => $Unattend,
|
|||
|
"SourcePath" => $SourcePath,
|
|||
|
"ToolsPath" => $_ToolShare,
|
|||
|
"_BuildArch" => $_BuildArch},
|
|||
|
{"COMPUTERNAME" => $ENV{"COMPUTERNAME"}},
|
|||
|
1);
|
|||
|
|
|||
|
&logmsg("Schedule task for $TargetMachine\\\\$TestUserAccount");
|
|||
|
my $stLabel = join("_", $Lang,
|
|||
|
$_BldSku ) ;
|
|||
|
my $res = &wrScheduTsk(
|
|||
|
$stLabel,
|
|||
|
$TargetMachine,
|
|||
|
$TargetSystemRoot,
|
|||
|
$ToolDrive,
|
|||
|
$ReleaseDrive,
|
|||
|
$ToolShare,
|
|||
|
$ToolsMachine,
|
|||
|
$_ReleaseShare,
|
|||
|
$MasterMachine,
|
|||
|
$TestUserAccount,
|
|||
|
$TestUserPassword,
|
|||
|
$SourceIsDFS);
|
|||
|
if("0" eq $res){
|
|||
|
errmsg("wrScheduTsk failed");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
#Wait on scheduled task for 1 min - if failed - kill it & try again
|
|||
|
if( ! AutoBoottest::WaitForTask($TargetMachine, $res, $DELAY2)){
|
|||
|
qx("schtasks /DELETE /S:$TargetMachine /U:$TestUserAccount /P:$TestUserPassword /TN:$res");
|
|||
|
&wrScheduTsk($stLabel,
|
|||
|
$TargetMachine,
|
|||
|
$TargetSystemRoot,
|
|||
|
$ToolDrive,
|
|||
|
$ReleaseDrive,
|
|||
|
$ToolShare,
|
|||
|
$ToolsMachine,
|
|||
|
$_ReleaseShare,
|
|||
|
$MasterMachine,
|
|||
|
$TestUserAccount,
|
|||
|
$TestUserPassword,
|
|||
|
$SourceIsDFS);
|
|||
|
if(0 == $res){
|
|||
|
errmsg("wrScheduTsk failed");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#We'll just die if it doesn't work this time
|
|||
|
if( ! AutoBoottest::WaitForTask($TargetMachine, $res, $DELAY2)){
|
|||
|
errmsg("Error starting task $res on $TargetMachine - exiting");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
&logmsg("Wait while $TargetMachine's drives are formatted");
|
|||
|
# beside checking for format.com it is possible to catch the moment drive is
|
|||
|
# being formatted
|
|||
|
#&wtDriveReady($TargetMachine, @Credentials);
|
|||
|
if((!AutoBoottest::WaitForProcess($TargetMachine, "format.com", 180, "", ""))
|
|||
|
||
|
|||
|
(!AutoBoottest::WaitOnProcess($TargetMachine, "format.com", 300, "", "")))
|
|||
|
{
|
|||
|
errmsg("Fatal error: $TargetMachine may not have formatted drives correctly");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
&logmsg("Verify $Process in \%TARGET\% \(TASK LIST\)");
|
|||
|
&AutoBoottest::WaitForProcess($TargetMachine, $Process, $DELAY2, "", "");
|
|||
|
$answ = &WMIFE::IsRunning("Win32_Process",
|
|||
|
$Process,
|
|||
|
"CommandLine",
|
|||
|
["ProcessId", "Name" , "CommandLine"],
|
|||
|
$TargetMachine);
|
|||
|
|
|||
|
&logmsg("@$answ");
|
|||
|
|
|||
|
1;
|
|||
|
}
|
|||
|
|
|||
|
sub wtDriveReady{
|
|||
|
|
|||
|
my ($TargetMachine, $MasterUserAccount, $MasterUserPassword) = @_;
|
|||
|
my $repeat = 0;
|
|||
|
|
|||
|
$DEBUG and
|
|||
|
print STDERR "BVT target drive on $TargetMachine:\n\n";
|
|||
|
my $Caption = "";
|
|||
|
|
|||
|
while (1){
|
|||
|
|
|||
|
$#$Results = -1;
|
|||
|
$Results =
|
|||
|
&WMIFE::ExecQuery($TargetMachine, # interactive session
|
|||
|
qq(SELECT * FROM win32_logicaldisk Where DriveType = 3 and FileSystem IS NULL),
|
|||
|
[qw(VolumeName Caption DriveType FileSystem Description)],
|
|||
|
$MasterUserAccount, $MasterUserPassword);
|
|||
|
last if scalar(@$Results);
|
|||
|
print ".";
|
|||
|
print "failed $REPEAT attempts\n" and last unless $repeat++< $REPEAT;
|
|||
|
sleep(1);
|
|||
|
}
|
|||
|
$repeat = 0;
|
|||
|
while (1){
|
|||
|
|
|||
|
$#$Results = -1;
|
|||
|
$Results =
|
|||
|
&WMIFE::ExecQuery($TargetMachine, # interactive session
|
|||
|
qq(SELECT * FROM win32_logicaldisk Where DriveType = 3 and FileSystem IS NULL),
|
|||
|
[qw(VolumeName Caption DriveType FileSystem Description)],
|
|||
|
$MasterUserAccount, $MasterUserPassword);
|
|||
|
last unless scalar(@$Results);
|
|||
|
print ".";
|
|||
|
print "failed $REPEAT attempts\n" and last unless $repeat++< $REPEAT;
|
|||
|
|
|||
|
|
|||
|
foreach my $Result (@$Results){
|
|||
|
|
|||
|
$DEBUG and
|
|||
|
map {&WMIFE::FormatDebugMsg($_, $Result->{$_})} keys (%$Result);
|
|||
|
$Caption = $Result->{"Caption"} if $Result->{"Caption"};
|
|||
|
}
|
|||
|
|
|||
|
sleep(1);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sub wrScheduTsk{
|
|||
|
|
|||
|
my (
|
|||
|
$stLabel,
|
|||
|
$TargetMachine,
|
|||
|
$TargetSystemRoot,
|
|||
|
$ToolDrive,
|
|||
|
$ReleaseDrive,
|
|||
|
$ToolShare,
|
|||
|
$ToolsMachine,
|
|||
|
$_ReleaseShare,
|
|||
|
$MasterMachine,
|
|||
|
$TestUserAccount,
|
|||
|
$TestUserPassword,
|
|||
|
$LocalInstall
|
|||
|
) = @_;
|
|||
|
# $TargetSystemRoot is lest in argument list for it could be needed
|
|||
|
my $Schtasks = "schtasks.exe";
|
|||
|
|
|||
|
my $TaskName = join "_", $stLabel, time;
|
|||
|
my $STFilever = qx("ver");
|
|||
|
my $StartTime = ( $STFilever =~ /2600/ )? "\%HH\%:\%MM\%:\%SS\%": "\%HH\%:\%MM\%";
|
|||
|
# "secs" not needed for TS running in build 36XX.
|
|||
|
|
|||
|
my $AtCommandTemplate = (!$LocalInstall)?
|
|||
|
qq(%SCHTASKS% /create /s %TARGET% /tn %TASKNAME% /u %TARGET%\\%USER% /p %PASSWORD% /sc once /st $StartTime /sd %mm%/%dd%/%yyyy% /tr cmd.exe /C NET USE %TOOLDISK% /D&NET USE %TOOLDISK% %TOOLSHARE% %PASSWORD% /U:%TOOLSMACHINE%\\%USER%&CSCRIPT.EXE %TOOLDISK%\\rx.wsf /from:\\\\%BLDMACHINE%\\%RELEASESHARE% /usedfs")
|
|||
|
:
|
|||
|
qq(%SCHTASKS% /create /s %TARGET% /tn %TASKNAME% /u %TARGET%\\%USER% /p %PASSWORD% /sc once /st $StartTime /sd %mm%/%dd%/%yyyy% /tr "%SYSTEMROOT%\\SYSTEM32\\cmd.exe /C NET USE %TOOLDISK% /D&NET USE %RELEASEDISK% /D&NET USE %TOOLDISK% %TOOLSHARE% %PASSWORD% /U:%MASTER%\\%USER%&NET USE %RELEASEDISK% \\\\%BLDMACHINE%\\%RELEASESHARE% %PASSWORD% /U:%MASTER%\\%USER%&CSCRIPT.EXE %TOOLDISK%\\rx.wsf /from:\\\\%MASTER%\\%RELEASESHARE%");
|
|||
|
# WARNING: Length of the command line argument should not exceed 255 characters
|
|||
|
|
|||
|
$DEBUG and
|
|||
|
print STDERR "AT Command template:\n\"$AtCommandTemplate\"\n";
|
|||
|
|
|||
|
my $ScheduleTime = &WMIFE::ScheduleTime($DELAY1);
|
|||
|
my $marker = ["HH" , "MM", "SS", "mm", "dd", "yyyy"];
|
|||
|
|
|||
|
my $AtCommand = $AtCommandTemplate;
|
|||
|
|
|||
|
$AtCommand =~ s/\%TASKNAME\%/$TaskName/g;
|
|||
|
$AtCommand =~ s/\%SCHTASKS\%/$Schtasks/g;
|
|||
|
$AtCommand =~ s/\%SYSTEMROOT\%/$TargetSystemRoot/g;
|
|||
|
$AtCommand =~ s/\%SYSTEMDRIVE\%/$TargetSystemDrive/g;
|
|||
|
$AtCommand =~ s/\%ToolPath\%/$ToolPath/g;
|
|||
|
|
|||
|
$AtCommand =~ s/\%TARGET\%/$TargetMachine/g;
|
|||
|
$AtCommand =~ s/\%MASTER\%/$MasterMachine/g;
|
|||
|
|
|||
|
$AtCommand =~ s/\%TOOLDISK\%/$ToolDrive/g;
|
|||
|
$AtCommand =~ s/\%TOOLSMACHINE\%/$ToolsMachine/g;
|
|||
|
# we hardcode here that TOOLSHARE is allocated on the TOOLSMACHINE
|
|||
|
$AtCommand =~ s/\%TOOLSHARE\%/\\\\$ToolsMachine\\$ToolShare/g;
|
|||
|
|
|||
|
$AtCommand =~ s/\%RELEASEDISK\%/$ReleaseDrive/g;
|
|||
|
$AtCommand =~ s/\%RELEASESHARE\%/$_ReleaseShare/g;
|
|||
|
|
|||
|
|
|||
|
$AtCommand =~ s/\%USER\%/$TestUserAccount/g;
|
|||
|
$AtCommand =~ s/\%PASSWORD\%/$TestUserPassword/g;
|
|||
|
|
|||
|
map {$AtCommand =~ s/\%$marker->[$_]\%/$ScheduleTime->[$_]/g;} (0..$#$marker);
|
|||
|
|
|||
|
for my $i (qx("net use")){
|
|||
|
# win32_share ?
|
|||
|
($i =~ /\w*\s*(\\\\$TargetMachine\\\w*\$+).*/) &&
|
|||
|
$DEBUG ? print `net use $1 /delete /y 2>&1` :
|
|||
|
`net use $1 /delete /y 2>&1`;
|
|||
|
}
|
|||
|
|
|||
|
$DEBUG and
|
|||
|
print STDERR "$AtCommand\n";
|
|||
|
system($AtCommand);
|
|||
|
$TaskName;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
1;
|
|||
|
__END__
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=head1 Scheduled autoboottest control flow.
|
|||
|
|
|||
|
=head2 RELEASE is accessed from MASTER SHARE
|
|||
|
|
|||
|
MASTER: create TARGET->TESTUSER
|
|||
|
MASTER: create MASTER->TESTUSER
|
|||
|
MASTER: create MASTER->TOOLSHARE
|
|||
|
MASTER: share MASTER->RELEASESHARE for MASTER->TESTUSER
|
|||
|
MASTER: WRITE TARGET->REGISTRY (logon data)
|
|||
|
MASTER: reboot TARGET
|
|||
|
MASTER: WRITE TARGET->REGISTRY (encrypted password)
|
|||
|
MASTER: schedule TASK for TARGET->TESTUSER
|
|||
|
MASTER: wait for TASK steps to be passed
|
|||
|
|
|||
|
|
|||
|
TARGET: execute TASK SCRIPT from MASTER->TOOLSHARE
|
|||
|
TASK SCRIPT: FORMAT TARGET->TESTDRIVE
|
|||
|
TASK SCRIPT: HANDLE TARGET->BOOT OPTIONS
|
|||
|
TASK SCRIPT: start INSTALLATION from MASTER->RELEASESHARE
|
|||
|
|
|||
|
=head2 RELEASE is accessed through DFS
|
|||
|
|
|||
|
MASTER: create TARGET->SYSTEMDRIVE->TOOLDIR
|
|||
|
MASTER: copy scripts and binaries to the TARGET
|
|||
|
MASTER: WRITE TARGET->REGISTRY (build info)
|
|||
|
MASTER: prompt user for password and encrypt it
|
|||
|
MASTER: WRITE TARGET->REGISTRY (encrypted password)
|
|||
|
MASTER: schedule TASK for TARGET->NT AUTHORITY\SYSTEM
|
|||
|
MASTER: wait for TASK steps to be passed
|
|||
|
|
|||
|
TARGET: execute TASK SCRIPT from TARGET->SYSTEMDRIVE->TOOLDIR
|
|||
|
TASK SCRIPT: DECRYPT MASTER password and get access to DFSSHARE
|
|||
|
TASK SCRIPT: FORMAT TARGET->TESTDRIVE
|
|||
|
TASK SCRIPT: HANDLE TARGET->BOOT OPTIONS
|
|||
|
TASK SCRIPT: start INSTALLATION from DFSSHARE
|
|||
|
|
|||
|
=head2 Note. This is a bare bones implementation.
|
|||
|
Room for structural improvement is:
|
|||
|
* providing the Test Machine status reflection in
|
|||
|
REGISTRY and/or FILESYSTEM areas visible from Build Machine.
|
|||
|
* manipulate settings to record the winnt32.exe messages to ease
|
|||
|
break analysis
|
|||
|
|