示例#1
0
 public void TestTasks()
 {
     foreach (VMWareVirtualMachine virtualMachine in _test.PoweredVirtualMachines)
     {
         // copy a batch file to the remote machine, execute it and collect results
         string localTempFilename  = Path.GetTempFileName();
         string remoteTempFilename = string.Format(@"C:\{0}", Path.GetFileName(localTempFilename));
         string remoteBatFilename  = string.Format(@"C:\{0}.bat", Path.GetFileNameWithoutExtension(localTempFilename));
         File.WriteAllText(localTempFilename, string.Format(@"dir C:\ > {0}", remoteTempFilename));
         virtualMachine.CopyFileFromHostToGuest(localTempFilename, remoteBatFilename);
         VMWareVirtualMachine.Process cmdProcess = virtualMachine.RunProgramInGuest(
             "cmd.exe", string.Format("/C \"{0}\"", remoteBatFilename));
         Assert.IsNotNull(cmdProcess);
         Assert.AreEqual(0, cmdProcess.ExitCode);
         virtualMachine.CopyFileFromGuestToHost(remoteTempFilename, localTempFilename);
         string remoteDirectoryListing = File.ReadAllText(localTempFilename);
         ConsoleOutput.WriteLine(remoteDirectoryListing);
         Assert.IsTrue(remoteDirectoryListing.Contains(Path.GetFileName(remoteTempFilename)));
         Assert.IsTrue(remoteDirectoryListing.Contains(Path.GetFileName(remoteBatFilename)));
         // delete the temp files
         virtualMachine.DeleteFileFromGuest(remoteTempFilename);
         virtualMachine.DeleteFileFromGuest(remoteBatFilename);
         File.Delete(localTempFilename);
         // virtualMachine.PowerOff();
     }
 }
示例#2
0
        public void TestRecordingBeginEnd()
        {
            if (!_test.Config.RunWorkstationTests)
            {
                Assert.Ignore("Skipping, Workstation tests disabled.");
            }

            foreach (VMWareVirtualMachine virtualMachine in _test.PoweredVirtualMachines)
            {
                Assert.IsFalse(virtualMachine.IsRecording);
                string snapshotName = Guid.NewGuid().ToString();
                ConsoleOutput.WriteLine("Begin recording ...");
                VMWareSnapshot snapshot = virtualMachine.BeginRecording(snapshotName, Guid.NewGuid().ToString());
                Assert.IsNotNull(snapshot);
                Assert.IsTrue(virtualMachine.IsRecording);
                Assert.IsFalse(virtualMachine.IsReplaying);
                virtualMachine.WaitForToolsInGuest();
                ConsoleOutput.WriteLine("Snapshot: {0}", snapshot.DisplayName);
                VMWareVirtualMachine.Process cmdProcess = virtualMachine.RunProgramInGuest("cmd.exe", "/C dir");
                Assert.IsNotNull(cmdProcess);
                ConsoleOutput.WriteLine("Process: {0}", cmdProcess.Id);
                ConsoleOutput.WriteLine("End recording ...");
                virtualMachine.EndRecording();
                Assert.IsFalse(virtualMachine.IsRecording);
                Assert.IsFalse(virtualMachine.IsReplaying);
                ConsoleOutput.WriteLine("Begin replay ...");
                snapshot.BeginReplay(Constants.VIX_VMPOWEROP_LAUNCH_GUI, VMWareInterop.Timeouts.ReplayTimeout);
                Assert.IsTrue(virtualMachine.IsReplaying);
                Thread.Sleep(10000);
                snapshot.EndReplay();
                Assert.IsFalse(virtualMachine.IsReplaying);
                ConsoleOutput.WriteLine("Removing snapshot ...");
                snapshot.RemoveSnapshot();
            }
        }
示例#3
0
        /// <summary>
        /// Execute a file from a remote vm.
        /// </summary>
        private TaskResult Execute(CommandTaskConfig executeConfig)
        {
            TaskResult copyFileResult = new TaskResult();

            copyFileResult.CmdLine = executeConfig.CmdLine;
            copyFileResult.Name    = executeConfig.Name;
            try
            {
                ConsoleOutput.WriteLine("{0}{1} 'Remote:{2}'",
                                        executeConfig.WaitForCompletion ? "Executing" : "Detaching",
                                        executeConfig.ActivateWindow ? " and activating" : "",
                                        executeConfig.CmdLine);

                if (!_installInstance.SimulationOnly)
                {
                    int options = 0;
                    if (!executeConfig.WaitForCompletion)
                    {
                        options |= Constants.VIX_RUNPROGRAM_RETURN_IMMEDIATELY;
                    }
                    if (executeConfig.ActivateWindow)
                    {
                        options |= Constants.VIX_RUNPROGRAM_ACTIVATE_WINDOW;
                    }

                    VMWareVirtualMachine.Process process = _installInstance.VirtualMachine.RunProgramInGuest(
                        executeConfig.Command, executeConfig.CommandLineArgs, options);

                    string exitCodeAction = "success";
                    if (executeConfig.IgnoreExitCode)
                    {
                        exitCodeAction = "ignored";
                    }
                    else if (process.ExitCode != executeConfig.ExitCode)
                    {
                        exitCodeAction = "error";
                    }
                    ConsoleOutput.WriteLine("Finished 'Remote:{0}', exit code = {1} ({2})",
                                            executeConfig.CmdLine, process.ExitCode, exitCodeAction);

                    if (!executeConfig.IgnoreExitCode && executeConfig.WaitForCompletion)
                    {
                        if (process.ExitCode != executeConfig.ExitCode)
                        {
                            throw new Exception(string.Format("Execute failed, return code: {0}",
                                                              process.ExitCode));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                copyFileResult.LastError = ex.Message;
                copyFileResult.Success   = false;
                ConsoleOutput.WriteLine(ex);
            }

            return(copyFileResult);
        }
示例#4
0
 /*
  * Detaches commands as the SYSTEM user in the guest OS
  * Added the /WAIT argument to have hstart64 run until it's called process (PsExec) is done. So tracking hstart is the most
  * effective way of figuring out if the process is alive.
  */
 private static VMWareVirtualMachine.Process detachSystemCommand(string command, string args, VMWareVirtualMachine sysVm)
 {
     VMWareVirtualMachine.Process tst, desiredProc = null, hstartWait = sysVm.DetachProgramInGuest(pstempGuest + @"\hstart64.exe", "/WAIT /UAC \"" + pstempGuest + "\\PsExec.exe /accepteula -i -s \"" + command + "\" " + args + "\"");
     while ((tst = sysVm.GuestProcesses.FindProcess(hstartWait.Name, StringComparison.CurrentCulture)) != null && desiredProc == null)
     {
         desiredProc = sysVm.GuestProcesses.FindProcess(Path.GetFileName(command), StringComparison.CurrentCulture);
     }
     return(desiredProc);
 }
示例#5
0
 protected void TestRunScriptInGuest()
 {
     foreach (VMWareVirtualMachine virtualMachine in _test.PoweredVirtualMachines)
     {
         StringBuilder script = new StringBuilder();
         script.AppendLine("print \"Hello World\";");
         VMWareVirtualMachine.Process cmdProcess = virtualMachine.RunScriptInGuest(@"c:\perl\bin\perl.exe", script.ToString());
         Assert.IsNotNull(cmdProcess);
         Assert.AreEqual(0, cmdProcess.ExitCode);
     }
 }
示例#6
0
 /*
  * Run PolicySync as system user
  * To wait for the completion of PolicySync, we look for PsExec.exe process on guest,
  * when null is returned the process does not exist
  */
 private static void policySync(VMWareVirtualMachine ivm)
 {
     VMWareVirtualMachine.Process psync = detachSystemCommand(@"C:\Program Files (x86)\LANDesk\LDClient\PolicySync.exe", "", ivm);
     if (psync != null)
     {
         while (ivm.GuestProcesses.FindProcess(psync.Name, StringComparison.CurrentCulture) != null)
         {
             System.Threading.Thread.Sleep(1000);
         }
     }
     Console.WriteLine("[\u221A] PolicySync complete.");
 }
示例#7
0
 /*
  * Runs regedit export of LANDesk software tracking, pulls file from guest -> host and returns number of lines in the file.
  *
  */
 private static int getRegEntryNum(VMWareVirtualMachine ivm)
 {
     if (ivm.FileExistsInGuest(pstempGuest + @"\reg.txt"))
     {
         ivm.DeleteFileFromGuest(pstempGuest + @"\reg.txt");
     }
     VMWareVirtualMachine.Process proc = ivm.RunProgramInGuest(@"C:\Windows\System32\Reg.exe", "export \"HKEY_LOCAL_MACHINE\\SOFTWARE\\LANdesk\\SOFTWARE\" \"" + pstempGuest + "\\reg.txt\"");
     if (File.Exists(workingDir + @"\reg.txt"))
     {
         File.Delete(workingDir + @"\reg.txt");
     }
     ivm.CopyFileFromGuestToHost(pstempGuest + @"\reg.txt", workingDir + @"\reg.txt");
     return(File.ReadAllLines(workingDir + @"\reg.txt").Length);
 }
        private void Run(out string logfile, string args)
        {
            logfile = _config.LogFile;

            _process = _vm.RunProgramInGuest(
                _config.DestinationPath, args, 0);

            if (_config.ExitCodes.Count > 0)
            {
                _config.ExitCodes.Check(_process.ExitCode);
            }
            else if (_process.ExitCode != 0)
            {
                throw new Exception(string.Format("Execution failed, return code: {0}",
                                                  _process.ExitCode));
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            using (VMWareVirtualHost host = GetConnectedHost())
            {
                using (VMWareVirtualMachine virtualMachine = OpenVirtualMachine(host))
                {
                    LoginGuest(virtualMachine);
                    Log.LogMessage(string.Format("Running '{0}{1}'", _guestProgramName,
                                                 string.IsNullOrEmpty(_commandLineArgs)
                            ? string.Empty
                            : " " + _commandLineArgs));
                    _process = virtualMachine.RunProgramInGuest(_guestProgramName, _commandLineArgs, 0, _runProgramTimeout);
                }
            }

            return(true);
        }
示例#10
0
        /// <summary>
        /// Execute dotNetInstaller.
        /// </summary>
        /// <param name="dniPath"></param>
        /// <param name="dniArgs"></param>
        /// <param name="action"></param>
        /// <param name="logfile"></param>
        private void DniExec(string dniPath, string dniArgs, DniAction action, out string logfile)
        {
            logfile = string.Format("{0}{1}.log", _config.DestinationPath, action);

            _process = _vm.RunProgramInGuest(
                _config.DestinationPath, string.Format("/q /log /LogFile \"{0}\" {1}",
                                                       logfile, dniArgs), 0);

            if (_config.ExitCodes.Count > 0)
            {
                _config.ExitCodes.Check(_process.ExitCode);
            }
            else if (_process.ExitCode != 0)
            {
                throw new Exception(string.Format("Execution failed, return code: {0}",
                                                  _process.ExitCode));
            }
        }
示例#11
0
 public void TestListAndKillProcesses()
 {
     foreach (VMWareVirtualMachine virtualMachine in _test.PoweredVirtualMachines)
     {
         VMWareVirtualMachine.Process notepadProcess = virtualMachine.DetachProgramInGuest("notepad.exe");
         ConsoleOutput.WriteLine("Notepad.exe: {0}", notepadProcess.Id);
         VMWareProcessCollection guestProcesses = virtualMachine.GuestProcesses;
         Assert.IsTrue(guestProcesses.ContainsKey(notepadProcess.Id));
         foreach (KeyValuePair <long, VMWareVirtualMachine.Process> process in guestProcesses)
         {
             Assert.IsTrue(process.Value.Id >= 0);
             Assert.IsFalse(string.IsNullOrEmpty(process.Value.Name));
             ConsoleOutput.WriteLine("{0}: {1} [{2}] ({3})", process.Value.Id, process.Value.Name, process.Value.Command, process.Value.Owner);
         }
         notepadProcess.KillProcessInGuest();
         Thread.Sleep(3000); // doc says: depending on the behavior of the guest operating system, there may be a short delay after the job completes before the process truly disappears
         VMWareProcessCollection guestProcesses2 = virtualMachine.GuestProcesses;
         Assert.IsFalse(guestProcesses2.ContainsKey(notepadProcess.Id));
     }
 }
        /// <summary>
        /// Install an MSI
        /// </summary>
        /// <param name="action">msi action</param>
        /// <param name="msiPath">path to the msi</param>
        /// <param name="msiArgs">additional msi parameters</param>
        /// <param name="logfile">resulting log file</param>
        private void MsiExec(string msiPath, string msiArgs, MsiAction action, out string logfile)
        {
            string msiAction = MsiActionToString(action);

            logfile = string.Format("{0}{1}.log", msiPath, msiAction);

            _msiexecProcess = this.VirtualMachineHost.RunProgramInGuest(
                "msiexec.exe", string.Format("/qn /{0} \"{1}\" /l*v \"{2}\" {3}",
                                             msiAction, msiPath, logfile, msiArgs), 0);

            if (_msiexecProcess.ExitCode == 3010)
            {
                // reboot required
            }
            else if (_msiexecProcess.ExitCode != 0)
            {
                throw new Exception(string.Format("{0} failed, return code: {1}",
                                                  action, _msiexecProcess.ExitCode));
            }
        }
示例#13
0
 public Process(VMWareVirtualMachine.Process p)
 {
     this.p = p;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            using (VMWareVirtualHost host = GetConnectedHost())
            {
                using (VMWareVirtualMachine virtualMachine = OpenVirtualMachine(host))
                {
                    LoginGuest(virtualMachine);
                    Log.LogMessage(string.Format("Running '{0}{1}'", _guestProgramName, 
                        string.IsNullOrEmpty(_commandLineArgs)
                            ? string.Empty 
                            : " " + _commandLineArgs));
                    _process = virtualMachine.RunProgramInGuest(_guestProgramName, _commandLineArgs, 0, _runProgramTimeout);
                }
            }

            return true;
        }
        /// <summary>
        /// Execute dotNetInstaller.
        /// </summary>
        /// <param name="dniPath"></param>
        /// <param name="dniArgs"></param>
        /// <param name="action"></param>
        /// <param name="logfile"></param>
        private void DniExec(string dniPath, string dniArgs, DniAction action, out string logfile)
        {
            logfile = string.Format("{0}{1}.log", _config.DestinationPath, action);

            _process = _vm.RunProgramInGuest(
                _config.DestinationPath, string.Format("/q /log /LogFile \"{0}\" {1}",
                    logfile, dniArgs), 0);

            if (_config.ExitCodes.Count > 0)
            {
                _config.ExitCodes.Check(_process.ExitCode);
            }
            else if (_process.ExitCode != 0)
            {
                throw new Exception(string.Format("Execution failed, return code: {0}",
                    _process.ExitCode));
            }
        }
        /// <summary>
        /// Install an MSI
        /// </summary>
        /// <param name="action">msi action</param>
        /// <param name="msiPath">path to the msi</param>
        /// <param name="msiArgs">additional msi parameters</param>
        /// <param name="logfile">resulting log file</param>
        private void MsiExec(string msiPath, string msiArgs, MsiAction action, out string logfile)
        {
            string msiAction = MsiActionToString(action);
            logfile = string.Format("{0}{1}.log", msiPath, msiAction);

            _msiexecProcess = this.VirtualMachineHost.RunProgramInGuest(
                "msiexec.exe", string.Format("/qn /{0} \"{1}\" /l*v \"{2}\" {3}",
                    msiAction, msiPath, logfile, msiArgs), 0);

            if (_msiexecProcess.ExitCode == 3010)
            {
                // reboot required
            }
            else if (_msiexecProcess.ExitCode != 0)
            {
                throw new Exception(string.Format("{0} failed, return code: {1}",
                    action, _msiexecProcess.ExitCode));
            }
        }
        private void Run(out string logfile, string args)
        {
            logfile = _config.LogFile;

            _process = _vm.RunProgramInGuest(
                _config.DestinationPath, args, 0);

            if (_config.ExitCodes.Count > 0)
            {
                _config.ExitCodes.Check(_process.ExitCode);
            }
            else if (_process.ExitCode != 0)
            {
                throw new Exception(string.Format("Execution failed, return code: {0}",
                    _process.ExitCode));
            }
        }
示例#18
0
        // Main method. Start point of the program
        static void Main(string[] args)
        {
            /*
             * Print a banner to the screen
             */
            Console.WriteLine(Properties.Resources.banner);



            /*
             * Do nothing if no arguments given.
             *
             * if the argument is -f, output to a file instead of console.
             */
            if (args.Length == 0 || args == null)
            {
                Environment.Exit(0);
            }
            else if (args[0] == "-f")
            {
                consoleOut = false;
            }



            /*
             * Get the current directory and store in a variable to avoid multiple calls
             */
            workingDir = Directory.GetCurrentDirectory();



            /*
             * Check to ensure that the pstemp directory is present in the same directory as
             * the TestSuite.exe file, with all important files included
             */
            pstempHost = workingDir + @"\pstemp";
            if (!Directory.Exists(pstempHost))
            {
                Console.WriteLine("[!] Error: the pstemp directory does not exist.");
                Environment.Exit(0);
            }
            else if (!File.Exists(pstempHost + @"\hstart64.exe") ||
                     !File.Exists(pstempHost + @"\PsExec.exe"))
            {
                Console.WriteLine("[!] Error: one or more files missing from pstemp directory.");
                Environment.Exit(0);
            }



            /*
             * Read lines from teh variables.ini file and set variables accordingly
             */
            string[] vars = File.ReadAllLines(workingDir + @"\Resources\variables.ini");
            foreach (string var in vars)
            {
                if (var.Contains("DOMAIN="))
                {
                    domainName = var.Replace("DOMAIN=", "");
                }
                else if (var.Contains("USERNAME="******"USERNAME="******"");
                }
                else if (var.Contains("PASSWORD="******"PASSWORD="******"");
                }
                else if (var.Contains("VMX="))
                {
                    vmxPath = var.Replace("VMX=", "");
                }
                else if (var.Contains("CPUID="))
                {
                    compId = var.Replace("CPUID=", "");
                }
                else if (var.Contains("TESTSPERSNAP="))
                {
                    testPerSnap = int.Parse(var.Replace("TESTSPERSNAP=", ""));
                }
                else if (var.Contains("TASKCNXNSTRING="))
                {
                    taskString = var.Replace("TASKCNXNSTRING=", "");
                }
                else if (var.Contains("IMAGENAME="))
                {
                    imageName = var.Replace("IMAGENAME=", "");
                }
                else if (var.Contains("PICTIME="))
                {
                    picTime = int.Parse(var.Replace("PICTIME=", ""));
                }
                else if (var.Contains("USESERVER="))
                {
                    useServer = bool.Parse(var.Replace("USESERVER=", ""));
                }
                else if (var.Contains("HOSTNAME="))
                {
                    hostName = var.Replace("HOSTNAME=", "");
                }
                else if (var.Contains("HOSTUSER="******"HOSTUSER="******"");
                }
                else if (var.Contains("HOSTPASS="******"HOSTPASS="******"");
                }
                else if (var.Contains("SFWRCNXNSTRING="))
                {
                    sfwrString = var.Replace("SFWRCNXNSTRING=", "");
                }
                else if (var.Contains("SCREENSHOTSDIR="))
                {
                    screenShotsDir = var.Replace("SCREENSHOTSDIR=", "");
                }
            }



            /*
             * If some variable is not initialized, exit.
             */
            if (domainName == null ||
                usrnm == null ||
                psswd == null ||
                vmxPath == null ||
                compId == null ||
                taskString == null ||
                useServer == null ||
                sfwrString == null)
            {
                Console.WriteLine("[!] An essential variable has not been initiated. See variables.ini");
                Environment.Exit(0);
            }



            /*
             * If no image name was given, use the name of the VMX file
             */
            if (imageName == null)
            {
                imageName = Path.GetFileNameWithoutExtension(vmxPath);
            }
            screenShotsDir = screenShotsDir + imageName;



            /*
             * If the output is specified to file, redirect all Console.WriteLine to a file instead of the console.
             */
            if (!consoleOut)
            {
                FileStream   fStream = new FileStream(screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt", FileMode.OpenOrCreate, FileAccess.Write);
                StreamWriter fileOut = new StreamWriter(fStream);
                Console.SetOut(fileOut);
            }


            /*
             * If useServer is true and any of the essential server variables are empty, quit
             */
            if ((bool)useServer && (hostName == null ||
                                    hostPass == null ||
                                    hostUser == null))
            {
                Console.WriteLine("[!] Variables.ini is not configured for server use.");
                Environment.Exit(0);
            }



            /*
             * Create a new directory with the date and time stamp to store the test results
             */
            resultDir = workingDir + @"\Results\";
            System.IO.Directory.CreateDirectory(resultDir);


            resultDir = resultDir + imageName + @"\";
            System.IO.Directory.CreateDirectory(resultDir);



            /*
             * Create the autoLogon.reg file, used to allow auto-logon in the guest OS after snapshot revert
             *
             * Sets to auto login
             * Turns off screensaver (broken?)
             * Turns off lock screen (broken?)
             */
            try
            {
                if (File.Exists(pstempHost + @"\autoLogon.reg"))
                {
                    File.Delete(pstempHost + @"\autoLogon.reg");
                }
                string[] lines = { "Windows Registry Editor Version 5.00",
                                   @"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]",
                                   "\"DefaultUserName\"=\"" + usrnm + "\"",
                                   "\"DefaultDomainName\"=\"" + domainName + "\"",
                                   "\"DefaultPassword\"=\"" + psswd + "\"",
                                   "\"AutoAdminLogon\"=\"1\"",
                                   "",
                                   @"[HKEY_CURRENT_USER\Control Panel\Desktop]",
                                   "\"ScreenSaveActive\"=\"0\"",
                                   "",
                                   @"[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization]",
                                   "\"NoLockScreen\"=dword:00000001" };
                File.WriteAllLines(pstempHost + @"\autoLogon.reg", lines);
            }
            catch (Exception e)
            {
                Console.WriteLine("[!] Could not create auto-login registry file. You may need to do this manually.");
                Console.WriteLine("[?] Exception message: " + e.Message);
            }



            /*
             * Query the SQL database and use the reader to create a collection of
             * the information
             */
            try
            {
                conn = new SqlConnection(taskString);
                conn.Open();
                cmd    = new SqlCommand(Properties.Resources.taskQuery + compId, conn); // use the command resource, add the computer ID number
                reader = cmd.ExecuteReader();
                tests  = new Dictionary <int, TestPackage>();
                while (reader.Read())
                {
                    tests.Add(reader.GetInt32(1), new TestPackage(reader.GetString(0), reader.GetInt32(1).ToString()));
                }
                reader.Close();
                conn.Close();
                Console.WriteLine("[i] " + tests.Count + " packages assigned to this machine.");
            }
            catch (SqlException sqle)
            {
                Console.WriteLine("Exception thrown: " + sqle.Message);
                Environment.Exit(0);
            }



            /*
             * Create VirtualHost and VirtualMachine objects with using directive
             */
            using (VMWareVirtualHost vhost = new VMWareVirtualHost())
            {
                /*
                 * Connect to either vSphere or Workstation, based on useServer variable
                 */
                if ((bool)useServer)
                {
                    vhost.ConnectToVMWareVIServer(hostName, hostUser, hostPass);
                    Console.WriteLine("[\u221A] Connected to vSphere.");
                }
                else
                {
                    vhost.ConnectToVMWareWorkstation();
                    Console.WriteLine("[\u221A] Connected to VMWareWorkstation.");
                }


                /*
                 * Open a virtual machine using the vmxPath
                 */
                using (VMWareVirtualMachine vm = vhost.Open(vmxPath))
                {
                    Console.WriteLine("[\u221A] Virtual machine opened.");



                    /*
                     * Power on the virtual machine and log in interactively.
                     * Requires user to log in interactively on the VM
                     */
                    try
                    {
                        vm.PowerOn();
                        Console.WriteLine("[\u221A] Powered on.");

                        vm.WaitForToolsInGuest();
                        Console.WriteLine("[\u221A] Tools found in guest.");


                        /*
                         * Login using the interactive login procedure
                         */
                        interactiveLogin(vm);



                        /*
                         * Copy necessary files for SYSTEM execution from host to guest.
                         *
                         */
                        if (vm.DirectoryExistsInGuest(pstempGuest))
                        {
                            vm.DeleteDirectoryFromGuest(pstempGuest);
                        }
                        vm.CopyFileFromHostToGuest(pstempHost, pstempGuest);
                        Console.WriteLine("[\u221A] Files copied to temp directory " + pstempGuest + ".");



                        /*
                         * Run the AutoLogon script for proper VM rollbacks
                         * We try try to delete the PSEXESVC process, if it exists. If it doesn't it throws an exception,
                         * which we ignore.
                         */
                        VMWareVirtualMachine.Process reg = detachSystemCommand(@"C:\Windows\regedit.exe", "/s \"" + pstempGuest + "\\autoLogon.reg\"", vm);
                        if (reg != null)
                        {
                            while (vm.GuestProcesses.FindProcess(reg.Name, StringComparison.CurrentCulture) != null)
                            {
                                ;
                            }
                        }
                        Console.WriteLine("[\u221A] Registry configured for auto logon.");



                        /*
                         * Create snapshot for deployment rollbacks
                         * If a snapshot
                         */
                        try
                        {
                            deployPoint = vm.Snapshots.GetNamedSnapshot(snapName);
                            deployPoint.RemoveSnapshot();
                        }
                        catch (VMWareException) { }

                        deployPoint = vm.Snapshots.CreateSnapshot(snapName, "Start point for deployment tests");
                        Console.WriteLine("[\u221A] Snapshot 'deployPoint' captured.");


                        /*
                         * Sync policies with server.
                         */
                        policySync(vm);



                        /*
                         * Create a list of all files in the policy directory
                         * Remove all non-xml files from the list
                         * Look for the task ID in the file name, and map the file name to the correct package
                         */

                        policyDirectoryFiles = vm.ListDirectoryInGuest(@"C:\ProgramData\LANDesk\Policies", false);
                        policyDirectoryFiles.RemoveAll(x => !(x.Contains(".xml")));

                        foreach (string dir in policyDirectoryFiles)
                        {
                            Match m   = idPattern.Match(dir);
                            int   key = (m.Success) ? Int32.Parse(m.Value.Substring(3, 4)) : -1;
                            if (tests.ContainsKey(key))
                            {
                                tests[key].Cmd = dir;
                            }
                        }
                        Console.WriteLine((policyDirectoryFiles.Count == tests.Count) ? "[\u221A] All packages can be deployed." : "[!] There are " + policyDirectoryFiles.Count + " policy files and " + tests.Count + " tasks assigned.");



                        /*
                         * Rrun through each entry in the dictionary of test cases,
                         *
                         */
                        using (myConn = new MySqlConnection(sfwrString))
                        {
                            myConn.Open();
                            foreach (KeyValuePair <int, TestPackage> entry in tests)
                            {
                                TestPackage test = entry.Value;

ReTest:
                                try
                                {
                                    /*
                                     * Query SLM, if any result is given test is a pass else fail
                                     */
                                    myCmd          = new MySqlCommand("SELECT * FROM software WHERE task_id=" + test.TaskID, myConn);
                                    myReader       = myCmd.ExecuteReader();
                                    test.NewResult = new TestResult("SLM Entry Exists", (myReader.HasRows) ? "1" : "0", "");
                                    myReader.Close();



                                    /*
                                     * If there is no xml file for the package, continue
                                     * For the package that cannot be deployed, add a test result saying so
                                     * If it can be deployed, add a positive test result
                                     */
                                    if (!test.isDeployable)
                                    {
                                        Console.WriteLine("[!] Continuing, cannot deploy " + test.Name);
                                        test.NewResult = new TestResult("LANDesk Task Available", "0", "Policy file not found.");
                                        continue;
                                    }
                                    else
                                    {
                                        Console.WriteLine("[*] Deploying " + test.Name);
                                        test.NewResult = new TestResult("LANDesk Task Available", "1", "");
                                    }



                                    /*
                                     * Directory for pictures resolved from resultDir and taskID
                                     */
                                    picDir = resultDir + test.TaskID + @"\";
                                    System.IO.Directory.CreateDirectory(picDir);



                                    /*
                                     * Get the number of registry entries in the LANDesk reg folder before deployment
                                     */
                                    int beforeDeploy = getRegEntryNum(vm);



                                    /*
                                     * Capture the process to determine when the deployment is complete
                                     * Start timing the deployment from when the PsExec process is detected
                                     */
                                    VMWareVirtualMachine.Process deployProcess = detachSystemCommand(@"C:\Program Files (x86)\LANDesk\LDClient\SDCLIENT.EXE", test.Cmd, vm);
                                    stopwatch.Restart();



                                    /*
                                     * While the program deploys
                                     * if 10000ms has passed since last pic taken, take a pic and increment
                                     * if the test is taking too long, add a failed test, revert snapshot, convert
                                     * png files to single gif and go to the next test
                                     */
                                    int pictureCount = 0;
                                    while (vm.GuestProcesses.FindProcess(deployProcess.Name, StringComparison.CurrentCulture) != null)
                                    {
                                        if (stopwatch.ElapsedMilliseconds > pictureCount * picTime)
                                        {
                                            vm.CaptureScreenImage().Save(picDir + pictureCount++.ToString() + @".png");
                                        }
                                        if (stopwatch.ElapsedMilliseconds > test.MaxTime)
                                        {
                                            test.NewResult = new TestResult("LANDesk Task Completed", "0", "");
                                            test.Pngs      = Directory.GetFiles(picDir);
                                            test.PicsDir   = picDir;
                                            revertAndLogin(vm);
                                            goto NextTest;
                                        }
                                    }
                                    stopwatch.Stop();
                                    test.Time      = stopwatch.ElapsedMilliseconds;
                                    test.NewResult = new TestResult("LANDesk Task Completed", "1", test.Time.ToString());
                                    detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname htmldialog}\"", vm);
                                    Console.WriteLine("[\u221A] Task complete. Task took " + (test.Time / 1000) + " seconds.");



                                    /*
                                     * The task has successfully completed running, we now add to the TestPackage object the
                                     * names of all .png files and the location of these files, for later gif creation.
                                     */
                                    test.Pngs    = Directory.GetFiles(picDir);
                                    test.PicsDir = picDir;



                                    /*
                                     * Test if a new registry key was added. If there are more registry entries now than before the deployment,
                                     * pass. Otherwise fail.
                                     */
                                    test.NewResult = new TestResult("Registry Key Added", (beforeDeploy < getRegEntryNum(vm)) ? "1" : "0", "");



                                    /*
                                     * Check to see if any of the exe's returned by query to database exist on the guest
                                     *
                                     */
                                    bool anyExeOnGuest = false;
                                    myCmd    = new MySqlCommand(Properties.Resources.exeQuery + test.TaskID, myConn);
                                    myReader = myCmd.ExecuteReader();
                                    if (!myReader.HasRows)
                                    {
                                        anyExeOnGuest = true;
                                    }
                                    else
                                    {
                                        while (myReader.Read())
                                        {
                                            string exeName = myReader.GetString(2);
                                            string fileId  = myReader.GetString(0);
                                            if (vm.FileExistsInGuest(exeName))
                                            {
                                                /*
                                                 * If the file exists on the guest; run the exe, wait 60 seconds and take a pic.
                                                 */
                                                anyExeOnGuest = true;
                                                VMWareVirtualMachine.Process testExe = vm.DetachProgramInGuest(myReader.GetString(2));
                                                stopwatch.Restart();
                                                while (stopwatch.ElapsedMilliseconds < 60000 && vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null)
                                                {
                                                    ;
                                                }
                                                if (vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null)
                                                {
                                                    vm.CaptureScreenImage().Save(picDir + "exescreen_" + fileId + ".png");
                                                    try
                                                    {
                                                        testExe.KillProcessInGuest();
                                                    }
                                                    catch { }
                                                }
                                                detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname @(javaw, java)}\"", vm);
                                                test.NewResult = new TestResult("Ran EXE - " + Path.GetFileName(exeName), "1", fileId);
                                            }
                                        }// end myReader.Read() while
                                    }



                                    /*
                                     * If there are no exe's on the guest, result is a fail.
                                     * If there are, result is a pass with optional message
                                     */
                                    test.NewResult = (!anyExeOnGuest) ? new TestResult("Files Installed", "0", "") : new TestResult("Files Installed", "1", (!myReader.HasRows) ? "No executables returned" : "");
                                    myReader.Close();



                                    /*
                                     *
                                     * If the number of tests completed is greater than the revert
                                     * threshold, revert and continue testing.
                                     * Otherwise, kill the htmldialog.exe process for the next test.
                                     */
                                    if (++count == testPerSnap)
                                    {
                                        revertAndLogin(vm);
                                    }
                                }
                                catch (Exception e)
                                {
                                    /*
                                     * If this code is reached, test has not completed.
                                     * If this is not the first test deployed since a test passed, revert and try the test again.
                                     * Otherwise, revert and move to the next test.
                                     * Add a test result containing some info from Exception e
                                     */
                                    if (count != 0)
                                    {
                                        Console.WriteLine("[!] Test suite error.");
                                        Console.WriteLine("[!] Restarting test of " + test.Name);
                                        revertAndLogin(vm);
                                        goto ReTest;
                                    }
                                    test.NewResult = new TestResult("Test Suite Error", "0", e.Message);
                                    Console.WriteLine("[!] Exception caught, rolling back then moving to next test: ");
                                    Console.WriteLine("Type: " + e.GetType().ToString());
                                    Console.WriteLine("Message: " + e.Message);
                                    Console.WriteLine("Stack trace:\n" + e.StackTrace);
                                    revertAndLogin(vm);
                                }

                                NextTest :;
                            }// end foreach


                            try
                            {
                                /*
                                 * We now have a dictionary of all the tests with taskID as the keys.
                                 * Send the results to the SQL server
                                 */
                                Console.WriteLine("[\u221A] Sending test results to database.");
                                myDeleteCmd = new MySqlCommand("DELETE FROM unit_test WHERE image=?image AND task_id=?task");
                                myDeleteCmd.Parameters.AddWithValue("?image", imageName);
                                myDeleteCmd.Parameters.AddWithValue("?task", "");
                                myDeleteCmd.Connection  = myConn;
                                myDeleteCmd.CommandType = System.Data.CommandType.Text;

                                myCmd             = new MySqlCommand(@"INSERT INTO unit_test (task_id, image, test_name, result, message) VALUES (?task_id, ?image, ?test_name, ?result, ?message)");
                                myCmd.CommandType = System.Data.CommandType.Text;
                                myCmd.Connection  = myConn;
                                myCmd.Parameters.AddWithValue("?image", imageName);
                                myCmd.Parameters.AddWithValue("?task_id", "");
                                myCmd.Parameters.AddWithValue("?test_name", "");
                                myCmd.Parameters.AddWithValue("?result", "");
                                myCmd.Parameters.AddWithValue("?message", "");

                                foreach (KeyValuePair <int, TestPackage> entry in tests)
                                {
                                    myDeleteCmd.Parameters["?task"].Value = entry.Value.TaskID;
                                    myDeleteCmd.ExecuteNonQuery();

                                    myCmd.Parameters["?task_id"].Value = entry.Value.TaskID;
                                    foreach (TestResult result in entry.Value.AllResults)
                                    {
                                        myCmd.Parameters["?test_name"].Value = result.Name;
                                        myCmd.Parameters["?result"].Value    = result.Result;
                                        myCmd.Parameters["?message"].Value   = result.Message;
                                        myCmd.ExecuteNonQuery();
                                    }
                                }

                                Console.WriteLine("[\u221A] Results committed to database.");
                            }


                            /*
                             * If the database commit failed, print all results to a file in the working directory.
                             */
                            catch (Exception)
                            {
                                string       fileName = screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt";
                                FileStream   fStream  = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
                                StreamWriter fileOut  = new StreamWriter(fStream);
                                foreach (KeyValuePair <int, TestPackage> pair in tests)
                                {
                                    foreach (TestResult result in pair.Value.AllResults)
                                    {
                                        fileOut.WriteLine(pair.Key.ToString() + "," + imageName + "," + result.Name + "," + result.Result + "," + result.Message);
                                    }
                                }
                                Console.WriteLine("[\u221A] Results written to file.\n" + fileName);
                            }
                        }// end of myConn using statement



                        /*
                         * Gif creation
                         */
                        Console.WriteLine("[\u221A] Creating gifs.");
                        foreach (KeyValuePair <int, TestPackage> pair in tests)
                        {
                            pair.Value.createGif();
                        }



                        /*
                         * Copy the screenshots and gifs to the share
                         */
                        CopyFolder(resultDir, screenShotsDir);

                        Console.WriteLine("[\u221A] Testing complete. Exiting.");
                    }// end try



                    /*
                     * If for whatever reason an exception is thrown, print the error message to the screen.
                     * Distinguish between VMWare exception and other exceptions.
                     */
                    catch (VMWareException vmwe)
                    {
                        Console.WriteLine("[!] VMware exception: " + vmwe.Message);
                        Console.WriteLine(vmwe.ToString());
                        Console.WriteLine(vmwe.Source);
                        Environment.Exit(0);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("[!] Exception: " + e.Message + "\n");
                        Console.WriteLine("[!] Type:" + e.GetType());
                        Console.WriteLine(e.Source);
                        Console.WriteLine(e.StackTrace);
                        Environment.Exit(0);
                    }
                } // End vm using
            }     // End vhost using
        }         // end main