You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC

svn commit: r726079 [5/32] - in /incubator/vcl/tags/import: ./ managementnode/ managementnode/bin/ managementnode/etc/ managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/ managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mod...

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,798 @@
+#!/usr/bin/perl -w
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################################################################
+# $Id: Windows.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Windows.pm - VCL module to support Windows operating systems
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Windows operating systems.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+use VCL::Module::Utils::Logging;
+use VCL::Module::Utils::SCP;
+use VCL::Module::Utils::SSH;
+use File::Basename;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 run_command
+
+ Parameters  : String containing the Windows command to be run
+ Returns     : Array:
+                  - first index contains the return code of the command
+                  - indices > 0 contain the lines of output generated by running
+                    the command
+ Description : Runs a command on a Windows node. The command is executed by
+               by passing it through SSH. The command passed to this subroutine
+					is formatted so that it runs as a Windows command would normally
+               run by using the Windows command shell instead of Cygwin's bash
+               shell.
+
+=cut
+
+sub run_command {
+	my $self = shift;
+	my ($command) = @_;
+
+	# Get the computer node name
+	my $computer_node_name = $self->data->get_computer_node_name();
+
+	# Passing Windows-style commands through SSH/Cygwin causes problems
+	# Encapsulate the command in a 'cmd.exe /q /v:on /k' command and call exit afterwards
+	# First replace % with !, the /v:on switch allows this so the variables aren't interpolated
+	# /q turns echo off
+	$command =~ s/\%/\!/g;
+
+	# This causes the command to be run in a normal Windows command shell rather than Cygwin's bash shell
+	$command = "cmd.exe /q /v:on /c '$command'";
+
+	# Replace line breaks with &&
+	$command =~ s/\n/ && /g;
+
+	# Run the SSH command
+	my @ssh_results = ssh($computer_node_name, $IDENTITY_wxp, $command);
+
+	return @ssh_results;
+} ## end sub run_command
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 run_remote_script
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub run_remote_script {
+	my $self = shift;
+	my ($script_path) = @_;
+
+	# Take the script path apart
+	my ($filename, $directory, $extension) = fileparse($script_path, qr/\.[^.]*$/);
+
+	# Remove the leading period from the extension
+	$extension =~ s/^\.//;
+
+	# Assemble the remote script path
+	my $remote_script_scp_path = "\$TEMP/$filename.$extension";
+	my $remote_script_ssh_path = "\%TEMP\%\\$filename.$extension";
+
+	# Copy the script to the node
+	if (!$self->copy_file($script_path, $remote_script_scp_path)) {
+		log_warning("failed to execute script, unable to copy $script_path to $remote_script_scp_path");
+		return 0;
+	}
+
+	# Assemble a script execution command based on the extension
+	my $command;
+	if ($extension =~ /ws|js|vbs|vbe|wsf|wsh/i) {
+		# Call cscript.exe for vbs and similar files
+		$command = "%SystemRoot%/System32/cscript.exe $remote_script_ssh_path //NoLogo";
+	}
+	elsif ($extension !~ /bat|cmd/i) {
+		# Attempt to run other types of files in the Windows command interpreter
+		log_warning("unsupported script extension: $filename.$extension, attempting to run file in Windows command interpreter");
+		$command = $remote_script_ssh_path;
+	}
+	else {
+		$command = $remote_script_ssh_path;
+	}
+
+	# Attempt to run the script
+	my ($command_exit_status, @command_output) = $self->run_command($command);
+	if ($command_exit_status) {
+		log_warning("failed to execute script: $script_path");
+	}
+
+	return ($command_exit_status, @command_output);
+} ## end sub run_remote_script
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 copy_file
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub copy_file {
+	my $self = shift;
+	my ($source_file_path, $destination_file_path) = @_;
+
+	# Get the computer node name
+	my $computer_node_name = $self->data->get_computer_node_name();
+
+	my %scp_options = (options          => 'v',
+							 identity_file    => $IDENTITY_wxp,
+							 source_path      => $source_file_path,
+							 destination_host => $computer_node_name,
+							 destination_path => $destination_file_path,);
+
+	# Run the SCP command
+	if (!scp(\%scp_options)) {
+		log_warning("failed to copy file using SCP");
+		return 0;
+	}
+
+	log_info("file copied using SCP: $source_file_path --> $computer_node_name:$destination_file_path");
+	return 1;
+} ## end sub copy_file
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 capture_prepare
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub capture_prepare {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+
+	my $request_id               = $self->data->get_request_id();
+	my $reservation_id           = $self->data->get_reservation_id();
+	my $image_id                 = $self->data->get_image_id();
+	my $image_os_name            = $self->data->get_image_os_name();
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $image_os_type            = $self->data->get_image_os_type();
+	my $image_name               = $self->data->get_image_name();
+	my $imagemeta_sysprep        = $self->data->get_imagemeta_sysprep();
+	my $computer_id              = $self->data->get_computer_id();
+	my $computer_short_name      = $self->data->get_computer_short_name();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	my $computer_type            = $self->data->get_computer_type();
+	my $user_id                  = $self->data->get_user_id();
+	my $user_unityid             = $self->data->get_user_login_id();
+	my $managementnode_shortname = $self->data->get_management_node_short_name();
+	my $computer_private_ip      = $self->data->get_computer_private_ip();
+
+	notify($ERRORS{'OK'}, 0, "beginning Windows-specific image capture preparation tasks: $image_name on $computer_short_name");
+
+	my @sshcmd;
+
+	# Change password of root and sshd service back to default
+	# Needed only for sshd service on windows OS's
+	my $p = $WINDOWS_ROOT_PASSWORD;
+	if (changewindowspasswd($computer_short_name, "root", $p)) {
+		notify($ERRORS{'OK'}, 0, "changed Windows password on $computer_short_name, root, $p");
+	}
+	else {
+		notify($ERRORS{'OK'}, 0, "failed to change windows password $computer_short_name,root,$p");
+	}
+
+
+	# Check for user account and clean out if listed
+	if (_is_user_added($computer_node_name, $user_unityid, $computer_type, $image_os_name)) {
+		# Make sure user is logged off
+		my @QA = run_ssh_command($computer_node_name, $IDENTITY_wxp, "cmd /c qwinsta.exe", "root");
+		foreach my $r (@{$QA[1]}) {
+			if ($r =~ /([>]?)([-a-zA-Z0-9]*)\s+([a-zA-Z0-9]*)\s+ ([0-9]*)\s+([a-zA-Z]*)/) {
+				my $state   = $5;
+				my $session = $2;
+				my $user    = $3;
+				if ($5 =~ /Active/) {
+					notify($ERRORS{'OK'}, 0, "detected $user on $session still logged on $computer_node_name $r, sleeping 7 before logging off");
+					sleep 7;
+					my @LF = run_ssh_command($computer_node_name, $IDENTITY_wxp, "cmd /c logoff.exe $session");
+					foreach my $l (@{$LF[1]}) {
+						notify($ERRORS{'OK'}, 0, "output from attempt to logoff $user on $session");
+					}
+
+				}
+			} ## end if ($r =~ /([>]?)([-a-zA-Z0-9]*)\s+([a-zA-Z0-9]*)\s+ ([0-9]*)\s+([a-zA-Z]*)/)
+		} ## end foreach my $r (@{$QA[1]})
+		    #delete user
+		if (del_user($computer_node_name, $user_unityid, $computer_type, $image_os_name)) {
+			notify($ERRORS{'OK'}, 0, "$user_unityid account deleted from $computer_node_name");
+		}
+	} ## end if (_is_user_added($computer_node_name, $user_unityid...
+
+	# Determine if machine has static private IP address
+	# If so we need to change back to DHCP
+	if ($image_name =~ /^win2003/) {
+		notify($ERRORS{'OK'}, 0, "Windows Server 2003 image detected, private adapter will be changed from DHCP to static on $computer_short_name");
+
+		my %ip;
+		my $myadapter;
+		undef @sshcmd;
+		@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "ipconfig -all", "root");
+		# build hash of needed info and set the correct private adapter.
+		foreach my $a (@{$sshcmd[1]}) {
+			if ($a =~ /Ethernet adapter (.*):/) {
+				#print "$1\n";
+				$myadapter = $1;
+			}
+			if ($a =~ /IP Address([\s.]*): $computer_private_ip/) {
+				$ip{$myadapter}{"private"} = 1;
+				notify($ERRORS{'OK'}, 0, "privateIP found $computer_private_ip");
+			}
+			if ($a =~ /DHCP Enabled([\s.]*): (No|Yes)/) {
+				$ip{$myadapter}{"DHCPenabled"} = $2;
+				notify($ERRORS{'OK'}, 0, "DHCP enabled $2");
+			}
+		} ## end foreach my $a (@{$sshcmd[1]})
+		my $privateadapter;
+		foreach my $key (keys %ip) {
+			if (defined($ip{$key}{private})) {
+				if ($ip{$key}{private}) {
+					$privateadapter = $key;
+				}
+			}
+		}
+
+		if ($ip{$privateadapter}{"DHCPenabled"} =~ /No/) {
+			notify($ERRORS{'OK'}, 0, "DHCP disabled for $privateadapter on $computer_node_name - reseting to dhcp");
+			if (open(NETSH, "/usr/bin/ssh -q -i $management_node_keys $computer_node_name \"netsh interface ip set address name=\\\"$privateadapter\\\" source=dhcp\" & 2>&1 |")) {
+				#losing connection
+				my $go = 1;
+				while ($go) {
+					#print "hi\n";
+					sleep 4;
+					if (open(PS, "ps -ef |")) {
+						my @ps = <PS>;
+						close(PS);
+						sleep 4;
+						foreach my $p (@ps) {
+							if ($p =~ /$computer_node_name netsh interface/) {
+								if ($p =~ /(root)\s+([0-9]*)/) {
+									if (open(KILLIT, "kill -9 $2 |")) {
+										close(KILLIT);
+										close(NETSH);
+										notify($ERRORS{'OK'}, 0, "killing ssh $computer_node_name netsh process");
+									}
+								}
+							}
+						} ## end foreach my $p (@ps)
+					} ## end if (open(PS, "ps -ef |"))
+					$go = 0;
+				} ## end while ($go)
+			}    # Close open netsh SSH handle
+
+			#make sure it came back confirm is was reset to dhcp
+			sleep 5;
+			my $sshd_status = _sshd_status($computer_node_name, $image_name);
+			if ($sshd_status eq "on") {
+				notify($ERRORS{'OK'}, 0, "successful $computer_node_name is accessible after dhcp assignment");
+				my $myadapter;
+				undef @sshcmd;
+				@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "ipconfig -all", "root");
+				# build hash of needed info and set the correct private adapter.
+				foreach my $a (@{$sshcmd[1]}) {
+					if ($a =~ /Ethernet adapter (.*):/) {
+						#print "$1\n";
+						$myadapter = $1;
+					}
+					if ($a =~ /IP Address([\s.]*): $computer_private_ip/) {
+						$ip{$myadapter}{"private"} = 1;
+					}
+					if ($a =~ /DHCP Enabled([\s.]*): (No|Yes)/) {
+						$ip{$myadapter}{"DHCPenabled"} = $2;
+					}
+				} ## end foreach my $a (@{$sshcmd[1]})
+				if ($ip{$privateadapter}{"DHCPenabled"} =~ /Yes/) {
+					notify($ERRORS{'OK'}, 0, "successful $computer_node_name is correctly assigned to use dhcp");
+				}
+				elsif ($ip{$privateadapter}{"DHCPenabled"} =~ /No/) {
+					notify($ERRORS{'CRITICAL'}, 0, "could not change $privateadapter on $computer_node_name back  to dhcp");
+
+					return 0;
+				}
+			} ## end if ($sshd_status eq "on")
+			else {
+				notify($ERRORS{'CRITICAL'}, 0, "sshd_status set to off, can not reconnect to $computer_node_name");
+				return 0;
+			}
+		}    # Close if DHCP == no
+
+		else {
+			notify($ERRORS{'OK'}, 0, "dhcp for $privateadapter is set to Yes on $computer_node_name $ip{$privateadapter}{DHCPenabled} - no change needed");
+		}
+	} ## end if ($image_name =~ /^win2003/)
+
+	if ($IPCONFIGURATION eq "static") {
+		#so we don't have conflicts we should set the public adapter back to dhcp
+		#this change is immediate
+		#figure out  which adapter it public
+		my $myadapter;
+		my %ip;
+		my ($privateadapter, $publicadapter);
+		undef @sshcmd;
+		@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "ipconfig -all", "root");
+		# build hash of needed info and set the correct private adapter.
+		my $id = 1;
+		foreach my $a (@{$sshcmd[1]}) {
+			if ($a =~ /Ethernet adapter (.*):/) {
+				$myadapter                 = $1;
+				$ip{$myadapter}{"id"}      = $id;
+				$ip{$myadapter}{"private"} = 0;
+			}
+			if ($a =~ /IP Address([\s.]*): $computer_private_ip/) {
+				$ip{$myadapter}{"private"} = 1;
+			}
+			if ($a =~ /Physical Address([\s.]*): ([-0-9]*)/) {
+				$ip{$myadapter}{"MACaddress"} = $2;
+			}
+			$id++;
+		} ## end foreach my $a (@{$sshcmd[1]})
+
+		foreach my $key (keys %ip) {
+			if (defined($ip{$key}{private})) {
+				if (!($ip{$key}{private})) {
+					$publicadapter = "\"$key\"";
+				}
+			}
+		}
+
+		undef @sshcmd;
+		my $netshcmd = "netsh interface ip set address name=\\\"$publicadapter\\\" source=dhcp";
+		@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $netshcmd, "root");
+		foreach my $l (@{$sshcmd[1]}) {
+			if ($l =~ /Ok/) {
+				notify($ERRORS{'OK'}, 0, "successfully set $publicadapter to dhcp");
+			}
+			else {
+				notify($ERRORS{'OK'}, 0, "problem setting $publicadapter to dhcp on $computer_node_name @{ $sshcmd[1] }");
+			}
+		}
+	} ## end if ($IPCONFIGURATION eq "static")
+
+	# Defrag before removing pagefile
+	# we do this to speed up the process
+	# defraging without a page file takes a little longer
+	notify($ERRORS{'OK'}, 0, "starting defrag on $computer_node_name");
+	undef @sshcmd;
+	@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "cmd.exe /c defrag C: -f", "root");
+	my $defragged = 0;
+	foreach my $d (@{$sshcmd[1]}) {
+		if ($d =~ /Defragmentation Report/) {
+			notify($ERRORS{'OK'}, 0, "successfully defragmented $computer_node_name");
+			$defragged = 1;
+		}
+	}
+	if (!$defragged) {
+		notify($ERRORS{'WARNING'}, 0, "problem occurred while defragmenting $computer_node_name: @{ $sshcmd[1] }");
+	}
+
+
+	# Copy new auto_create_image.vbs and auto_prepare_for_image.vbs
+	# This moves(sometimes) the pagefile and reboots the box
+	# It actually checks for a removes the pagefile.sys
+	my @scp;
+	if (run_scp_command("$TOOLS/auto_create_image.vbs", "$computer_node_name:auto_create_image.vbs", $management_node_keys)) {
+		notify($ERRORS{'OK'}, 0, "successfully copied auto_create_image.vbs to $computer_node_name");
+	}
+	else {
+		notify($ERRORS{'CRITICAL'}, 0, "failed to copy auto_create_image.vbs to $computer_node_name ");
+		return 0;
+	}
+
+
+	# Make sure sshd service is set to auto
+	if (_set_sshd_startmode($computer_node_name, "auto")) {
+		notify($ERRORS{'OK'}, 0, "successfully set auto mode for sshd start");
+	}
+	else {
+		notify($ERRORS{'CRITICAL'}, 0, "failed to set auto mode for sshd on $computer_node_name");
+		return 0;
+	}
+
+	my @list;
+	my $l;
+	#execute the vbs script to disable the pagefile and reboot
+	undef @sshcmd;
+	@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "cscript.exe //Nologo auto_create_image.vbs", "root");
+	foreach $l (@{$sshcmd[1]}) {
+		if ($l =~ /createimage reboot/) {
+			notify($ERRORS{'OK'}, 0, "auto_create_image.vbs initiated, $computer_node_name rebooting, sleeping 50");
+			sleep 50;
+			next;
+		}
+		elsif ($l =~ /failed error/) {
+			notify($ERRORS{'WARNING'}, 0, "auto_create_image.vbs failed, @{ $sshcmd[1] }");
+			#legacy code for a bug in xcat, now fixed
+			# force a reboot, or really a power cycle.
+			#crap hate to do this.
+			notify($ERRORS{'WARNING'}, 0, "forcing a power cycle");
+			if (_rpower($computer_node_name, "boot")) {
+				notify($ERRORS{'WARNING'}, 0, "forced power cycle complete");
+				next;
+			}
+		} ## end elsif ($l =~ /failed error/)  [ if ($l =~ /createimage reboot/)
+	} ## end foreach $l (@{$sshcmd[1]})
+
+
+	#Set up simple ping loop to determine if machine is actually rebooting
+	my $online   = 1;
+	my $pingloop = 0;
+	notify($ERRORS{'OK'}, 0, "checking for pingable $computer_node_name");
+	while ($online) {
+		if (!(_pingnode($computer_node_name))) {
+			notify($ERRORS{'OK'}, 0, "Success $computer_node_name is not pingable");
+			$online = 0;
+		}
+		else {
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is still pingable - loop $pingloop");
+			sleep 10;
+			$pingloop++;
+		}
+		if ($pingloop > 10) {
+			notify($ERRORS{'CRITICAL'}, 0, "$computer_node_name should have rebooted by now, trying to force it");
+			if (_rpower($computer_node_name, "boot")) {
+				notify($ERRORS{'WARNING'}, 0, "forced power cycle complete");
+				sleep 25;
+				next;
+			}
+		}
+	} ## end while ($online)
+
+
+	# Wait until the reboot process has started to shutdown services
+	notify($ERRORS{'OK'}, 0, "$computer_node_name rebooting, waiting");
+	my $socketflag = 0;
+
+
+	REBOOTED:
+	my $rebooted          = 1;
+	my $reboot_wait_count = 0;
+	while ($rebooted) {
+		if ($reboot_wait_count > 55) {
+			notify($ERRORS{'CRITICAL'}, 0, "waited $reboot_wait_count on reboot after auto_create_image on $computer_node_name");
+			return 0;
+		}
+		notify($ERRORS{'OK'}, 0, "$computer_node_name not completed reboot sleeping for 25");
+		sleep 25;
+		if (_pingnode($computer_node_name)) {
+			#it pingable check if sshd is open
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is pingable, checking sshd port");
+			my $sshd = _sshd_status($computer_node_name, $image_name);
+			if ($sshd =~ /on/) {
+				$rebooted = 0;
+				notify($ERRORS{'OK'}, 0, "$computer_node_name sshd is open");
+			}
+			else {
+				notify($ERRORS{'OK'}, 0, "$computer_node_name sshd NOT open yet,sleep 5");
+				sleep 5;
+			}
+		} ## end if (_pingnode($computer_node_name))
+		$reboot_wait_count++;
+	}    # Close while rebooted
+
+
+	# Check for recent bug
+	undef @sshcmd;
+	@sshcmd = run_ssh_command($computer_node_name, $IDENTITY_wxp, "uname -s");
+	foreach my $l (@{$sshcmd[1]}) {
+		if ($l =~ /^Warning:/) {
+			#if (makesshgkh($computer_node_name)) {
+			#}
+		}
+		if ($l =~ /^Read from socket failed:/) {
+			if ($socketflag) {
+				notify($ERRORS{'CRITICAL'}, 0, "could not login $computer_node_name via ssh socket failure");
+				return 0;
+			}
+			notify($ERRORS{'CRITICAL'}, 0, "discovered ssh read from socket failure on $computer_node_name, attempting to repair");
+			#power cycle node
+			if (_rpower($computer_node_name, "cycle")) {
+				notify($ERRORS{'CRITICAL'}, 0, "$computer_node_name power cycled going to reboot check routine");
+				sleep 40;
+				$socketflag = 1;
+				goto REBOOTED;
+			}
+		} ## end if ($l =~ /^Read from socket failed:/)
+	} ## end foreach my $l (@{$sshcmd[1]})
+
+	notify($ERRORS{'OK'}, 0, "proceeding to CIMONITOR");
+	#monitor for signal to set node to image and then reboot
+	my $sshd_status;
+	my ($loop, $rebootsignal, $reboot_copied) = 0;
+	CIMONITOR:
+	#check ssh port in case we finish above steps before first reboot completes
+	# while ssh port is off sleep few seconds then loop
+	# this section is useless for linux images
+	my $ping_result = _pingnode($computer_node_name);
+	#check our loop
+	if ($loop > 200) {
+		notify($ERRORS{'CRITICAL'}, 0, "CIMONITOR $computer_node_name taking longer to reboot than expected, check it");
+		return 0;
+	}
+	notify($ERRORS{'OK'}, 0, "CIMONITOR ping check");
+	if (!$ping_result) {
+		sleep 5;
+		notify($ERRORS{'OK'}, 0, "CIMONITOR ping is off waiting for $computer_node_name to complete reboot");
+		$loop++;
+		goto CIMONITOR;
+	}
+	# is port 22 open yet
+	if (!nmap_port($computer_node_name, 22)) {
+		notify($ERRORS{'OK'}, 0, "port 22 not open on $computer_node_name yet, looping");
+		$loop++;
+		sleep 3;
+		goto CIMONITOR;
+	}
+
+	# Remove old Sysprep files if they exist
+	if (run_ssh_command($computer_node_name, $IDENTITY_wxp, "/usr/bin/rm.exe -rf C:\/Sysprep", "root")) {
+		notify($ERRORS{'OK'}, 0, "removed any existing Sysprep files");
+	}
+
+	# Copy Sysprep files
+	COPY_SYSPREP:
+	if ($imagemeta_sysprep) {
+		#cp sysprep to C:
+		#chmod C:\Sysprep\*
+		# which sysprep to use
+		my $sysprep_files;
+		if ($image_name =~ /^winxp/) {
+			$sysprep_files = $SYSPREP;
+		}
+		elsif ($image_name =~ /^win2003/) {
+			$sysprep_files = $SYSPREP_2003;
+		}
+
+		notify($ERRORS{'OK'}, 0, "copying Sysprep files to $computer_short_name");
+		if (run_scp_command($sysprep_files, "$computer_node_name:C:\/Sysprep", $IDENTITY_wxp)) {
+			notify($ERRORS{'OK'}, 0, "copied Sysprep directory $sysprep_files to $computer_node_name C:");
+
+			if (run_ssh_command($computer_node_name, $IDENTITY_wxp, "/usr/bin/chmod.exe -R 755 C:\/Sysprep", "root")) {
+				notify($ERRORS{'OK'}, 0, "chmoded -R 755 C:\/Sysprep files ");
+			}
+			else {
+				notify($ERRORS{'CRITICAL'}, 0, "could not chmod -R 755 on $computer_node_name $!");
+			}
+		} ## end if (run_scp_command($sysprep_files, "$computer_node_name:C:\/Sysprep"...
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "could not copy $sysprep_files to $computer_node_name, $!");
+			return 0;
+		}
+	} ## end if ($imagemeta_sysprep)
+
+	# Set sshd service startup to manual
+	if (_set_sshd_startmode($computer_node_name, "manual")) {
+		notify($ERRORS{'OK'}, 0, "successfully set manual mode for sshd start");
+	}
+	else {
+		notify($ERRORS{'CRITICAL'}, 0, "failed to set manual mode for sshd on $computer_node_name");
+		return 0;
+	}
+
+
+	#actually remove the pagefile.sys sometimes movefile.exe does not work
+	if (run_ssh_command($computer_node_name, $IDENTITY_wxp, "/usr/bin/rm -v C:\/pagefile.sys", "root")) {
+		notify($ERRORS{'OK'}, 0, "removed pagefile.sys ");
+	}
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+} ## end sub capture_prepare
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 capture_start
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub capture_start {
+
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+
+	my $request_id               = $self->data->get_request_id();
+	my $reservation_id           = $self->data->get_reservation_id();
+	my $image_id                 = $self->data->get_image_id();
+	my $image_os_name            = $self->data->get_image_os_name();
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $image_os_type            = $self->data->get_image_os_type();
+	my $image_name               = $self->data->get_image_name();
+	my $imagemeta_sysprep        = $self->data->get_imagemeta_sysprep();
+	my $computer_id              = $self->data->get_computer_id();
+	my $computer_short_name      = $self->data->get_computer_short_name();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	my $computer_type            = $self->data->get_computer_type();
+	my $user_id                  = $self->data->get_user_id();
+	my $user_unityid             = $self->data->get_user_login_id();
+	my $managementnode_shortname = $self->data->get_management_node_short_name();
+	my $computer_private_ip      = $self->data->get_computer_private_ip();
+
+	notify($ERRORS{'OK'}, 0, "initiating Windows image capture: $image_name on $computer_short_name");
+
+	my @sshcmd;
+
+	if ($imagemeta_sysprep) {
+		notify($ERRORS{'OK'}, 0, "starting sysprep on $computer_node_name");
+		if (open(SSH, "/usr/bin/ssh -q -i $IDENTITY_wxp $computer_node_name \"C:\/Sysprep\/sysprep.cmd\" 2>&1 |")) {
+			my $notstop = 1;
+			my $loop    = 0;
+			while ($notstop) {
+				my $l = <SSH>;
+				$loop++;
+				#notify($ERRORS{'DEBUG'}, 0, "sysprep.cmd loop count: $loop");
+				#notify($ERRORS{'DEBUG'}, 0, "$l");
+				if ($l =~ /sysprep/) {
+					notify($ERRORS{'OK'}, 0, "sysprep.exe has started, $l");
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process in 60 seconds");
+					sleep 60;
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process");
+					if (_killsysprep($computer_node_name)) {
+						notify($ERRORS{'OK'}, 0, "killed sshd process for sysprep command");
+					}
+
+					notify($ERRORS{'DEBUG'}, 0, "closing SSH filehandle");
+					close(SSH);
+					notify($ERRORS{'DEBUG'}, 0, "SSH filehandle closed");
+
+					$notstop = 0;
+				} ## end if ($l =~ /sysprep/)
+				elsif ($l =~ /sysprep.cmd: Permission denied/) {
+					notify($ERRORS{'CRITICAL'}, 0, "chmod 755 failed to correctly set execute on sysprep.cmd output $l");
+					close(SSH);
+					return 0;
+				}
+
+				#avoid infinite loop
+				if ($loop > 1000) {
+					notify($ERRORS{'DEBUG'}, 0, "sysprep executed in loop control condition, exceeded limit");
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process in 60 seconds");
+					sleep 60;
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process");
+					if (_killsysprep($computer_node_name)) {
+						notify($ERRORS{'OK'}, 0, "killed sshd process for sysprep command");
+					}
+
+					notify($ERRORS{'DEBUG'}, 0, "closing SSH filehandle");
+					close(SSH);
+					notify($ERRORS{'DEBUG'}, 0, "SSH filehandle closed");
+
+					$notstop = 0;
+				} ## end if ($loop > 1000)
+
+			} ## end while ($notstop)
+		}    # Close open handle for SSH sysprep.cmd command
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to start sysprep on $computer_node_name $!");
+			return 0;
+		}    # Close sysprep.cmd could not be launched
+	}    # Close if Sysprep
+
+	else {
+		#non sysprep option
+		#
+		#just reboot machine -- future expansion of additional methods newsid, custom scripts, etc.
+		notify($ERRORS{'OK'}, 0, "starting custom script VCLprep1.vbs on $computer_node_name");
+		if (run_scp_command("$TOOLS/VCLprep1.vbs", "$computer_node_name:VCLprep1.vbs", $IDENTITY_wxp)) {
+			undef @sshcmd;
+			@sshcmd = run_ssh_command($computer_node_name, $IDENTITY_wxp, "cscript //Nologo VCLprep1.vbs", "root");
+			foreach my $s (@{$sshcmd[1]}) {
+				chomp($s);
+				if ($s =~ /copied VCLprepare/) {
+					notify($ERRORS{'OK'}, 0, "$s");
+				}
+				if ($s =~ /rebooting/) {
+					notify($ERRORS{'OK'}, 0, "SUCCESS started image procedure on $computer_node_name");
+					last;
+				}
+			} ## end foreach my $s (@{$sshcmd[1]})
+		}    # Close SCP VCLPrep1.vbs
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to copy $TOOLS/VCLprep1.vbs to $computer_node_name ");
+			return 0;
+		}
+	}    # Close if not Sysprep
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+} ## end sub capture_start
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+
+=cut

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,84 @@
+#!/usr/bin/perl -w
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################################################################
+# $Id: Desktop.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Windows::Desktop
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides...
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows::Desktop;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+
+=cut

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/Vista.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/Vista.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/Vista.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/Vista.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,1508 @@
+#!/usr/bin/perl -w
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################################################################
+# $Id: Vista.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Windows::Desktop::Vista.pm - VCL module to support Windows Vista operating system
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Windows Vista.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows::Desktop::Vista;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows::Desktop);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+use VCL::Module::Provisioning::xCAT;
+use File::Basename;
+
+##############################################################################
+
+=head1 CLASS VARIABLES
+
+=cut
+
+=head2 $CONFIGURATION_FILES
+
+ Data type   : Scalar
+ Description : Location of script/utilty/configuration files needed to
+               configure the OS. This is normally the directory under
+					the 'tools' directory specific to this OS.
+
+=cut
+
+our $CONFIGURATION_DIRECTORY = "$TOOLS/Sysprep_Vista";
+
+=head2 $ROOT_PASSWORD
+
+ Data type   : Scalar
+ Description : Password for the node's root account.
+
+=cut
+
+our $ROOT_PASSWORD = $WINDOWS_ROOT_PASSWORD;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 capture_prepare
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub capture_prepare {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+
+	my $request_id               = $self->data->get_request_id();
+	my $reservation_id           = $self->data->get_reservation_id();
+	my $image_id                 = $self->data->get_image_id();
+	my $image_os_name            = $self->data->get_image_os_name();
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $image_os_type            = $self->data->get_image_os_type();
+	my $image_name               = $self->data->get_image_name();
+	my $imagemeta_sysprep        = $self->data->get_imagemeta_sysprep();
+	my $computer_id              = $self->data->get_computer_id();
+	my $computer_short_name      = $self->data->get_computer_short_name();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	my $computer_type            = $self->data->get_computer_type();
+	my $user_id                  = $self->data->get_user_id();
+	my $user_unityid             = $self->data->get_user_login_id();
+	my $managementnode_shortname = $self->data->get_management_node_short_name();
+	my $computer_private_ip      = $self->data->get_computer_private_ip();
+	
+	notify($ERRORS{'OK'}, 0, "beginning Windows Vista image capture preparation tasks: $image_name on $computer_short_name");
+	
+	$self->disable_autoadminlogon();
+	#$self->import_registry_file("$CONFIGURATION_DIRECTORY/Scripts/test.reg");
+	#$self->disable_pagefile();
+	#$self->firewall_disable_rdp();
+	#$self->firewall_enable_rdp('152.1.0.0/16');
+	exit;
+	
+	# Node variables
+	my $local_configuration_directory = 'C:/VCL';
+	my $local_scripts_directory = 'C:/VCL/Scripts';
+	
+	
+	# Remove old configuration files if they exist
+	notify($ERRORS{'OK'}, 0, "attempting to remove old configuration directory if it exists: $local_configuration_directory");
+	my ($remove_old_status, $remove_old_output) = run_ssh_command($computer_node_name, $management_node_keys, "/usr/bin/rm.exe -rf $local_configuration_directory");
+	if (defined($remove_old_status) && $remove_old_status == 0) {
+		notify($ERRORS{'OK'}, 0, "removed existing configuration directory: $local_configuration_directory");
+	}
+	elsif (defined($remove_old_status)) {
+		notify($ERRORS{'OK'}, 0, "unable to remove existing configuration directory: $local_configuration_directory, exit status: $remove_old_status, output:\n@{$remove_old_output}");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to remove existing configuration directory: $local_configuration_directory");
+		return 0;
+	}
+
+
+	# Copy configuration files
+	notify($ERRORS{'OK'}, 0, "copying Sysprep and other configuration files to $computer_short_name");
+	if (run_scp_command($CONFIGURATION_DIRECTORY, "$computer_node_name:$local_configuration_directory", $IDENTITY_wxp)) {
+		notify($ERRORS{'OK'}, 0, "copied $CONFIGURATION_DIRECTORY directory to $computer_node_name:$local_configuration_directory");
+
+		notify($ERRORS{'OK'}, 0, "attempting to set permissions on $computer_node_name:$local_configuration_directory");
+		if (run_ssh_command($computer_node_name, $IDENTITY_wxp, "/usr/bin/chmod.exe -R 755 $local_configuration_directory")) {
+			notify($ERRORS{'OK'}, 0, "chmoded -R 755 $computer_node_name:$local_configuration_directory");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "could not chmod -R 755 $computer_node_name:$local_configuration_directory");
+		}
+	} ## end if (run_scp_command($CONFIGURATION_DIRECTORY, "$computer_node_name:C:\/Sysprep"...
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to copy $CONFIGURATION_DIRECTORY to $computer_node_name");
+		return 0;
+	}
+
+
+	# Set root account password
+	notify($ERRORS{'OK'}, 0, "changing root password on $computer_short_name");
+	my ($root_password_exit_status, $root_password_output) = run_ssh_command($computer_node_name, $management_node_keys, "net user root '$ROOT_PASSWORD'");
+	if ($root_password_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "root password changed to $ROOT_PASSWORD");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to change root password to $ROOT_PASSWORD, exit status: $root_password_exit_status, output:\n@{$root_password_output}");
+		return 0;
+	}
+
+	# Log off all currently logged in users
+	notify($ERRORS{'OK'}, 0, "logging off all currently logged in users");
+	logoff_users($computer_node_name);
+	
+	# Wait to allow any files in use by users justed logged out to close
+	notify($ERRORS{'OK'}, 0, "waiting for 5 seconds after any users were logged off to allow files to close");
+	sleep 5;
+	
+	# Delete the user assigned to this reservation
+	notify($ERRORS{'OK'}, 0, "attempting to delete user $user_unityid from $computer_node_name");
+	delete_user($computer_node_name, $user_id);
+	
+	
+	my @sshcmd;
+	if ($IPCONFIGURATION eq "static") {
+		#so we don't have conflicts we should set the public adapter back to dhcp
+		#this change is immediate
+		#figure out  which adapter it public
+		my $myadapter;
+		my %ip;
+		my ($privateadapter, $publicadapter);
+		undef @sshcmd;
+		@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "ipconfig -all", "root");
+		# build hash of needed info and set the correct private adapter.
+		my $id = 1;
+		foreach my $a (@{$sshcmd[1]}) {
+			if ($a =~ /Ethernet adapter (.*):/) {
+				$myadapter                 = $1;
+				$ip{$myadapter}{"id"}      = $id;
+				$ip{$myadapter}{"private"} = 0;
+			}
+			if ($a =~ /IP Address([\s.]*): $computer_private_ip/) {
+				$ip{$myadapter}{"private"} = 1;
+			}
+			if ($a =~ /Physical Address([\s.]*): ([-0-9]*)/) {
+				$ip{$myadapter}{"MACaddress"} = $2;
+			}
+			$id++;
+		} ## end foreach my $a (@{$sshcmd[1]})
+
+		foreach my $key (keys %ip) {
+			if (defined($ip{$key}{private})) {
+				if (!($ip{$key}{private})) {
+					$publicadapter = "\"$key\"";
+				}
+			}
+		}
+
+		undef @sshcmd;
+		my $netshcmd = "netsh interface ip set address name=\\\"$publicadapter\\\" source=dhcp";
+		@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $netshcmd, "root");
+		foreach my $l (@{$sshcmd[1]}) {
+			if ($l =~ /Ok/) {
+				notify($ERRORS{'OK'}, 0, "successfully set $publicadapter to dhcp");
+			}
+			else {
+				notify($ERRORS{'OK'}, 0, "problem setting $publicadapter to dhcp on $computer_node_name @{ $sshcmd[1] }");
+			}
+		}
+	} ## end if ($IPCONFIGURATION eq "static")
+
+	# Defrag before removing pagefile
+	# we do this to speed up the process
+	# defraging without a page file takes a little longer
+	#DEFRAG: notify($ERRORS{'OK'}, 0, "starting defrag on $computer_node_name");
+	#my ($defrag_exit_status, $defrag_output) = run_ssh_command($computer_node_name, $management_node_keys, "defrag.exe C: -v");
+	#if (defined($defrag_exit_status)) {
+	#	notify($ERRORS{'OK'}, 0, "defrag exit status: $defrag_exit_status, defrag output:\n$defrag_output");
+	#}
+	#else {
+	#	notify($ERRORS{'WARNING'}, 0, "defrag failed");
+	#}
+	
+	
+
+	my @list;
+	my $l;
+	#execute the vbs script to disable the pagefile and reboot
+	undef @sshcmd;
+	@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, "cscript.exe //Nologo $local_scripts_directory/auto_create_image.vbs");
+	foreach $l (@{$sshcmd[1]}) {
+		if ($l =~ /createimage reboot/) {
+			notify($ERRORS{'OK'}, 0, "auto_create_image.vbs initiated, $computer_node_name rebooting, sleeping 50");
+			sleep 50;
+			next;
+		}
+		elsif ($l =~ /failed error/) {
+			notify($ERRORS{'WARNING'}, 0, "auto_create_image.vbs failed, @{ $sshcmd[1] }");
+			#legacy code for a bug in xcat, now fixed
+			# force a reboot, or really a power cycle.
+			#crap hate to do this.
+			notify($ERRORS{'WARNING'}, 0, "forcing a power cycle");
+			if (VCL::Module::Provisioning::xCAT::_rpower($computer_node_name, "cycle")) {
+				notify($ERRORS{'WARNING'}, 0, "forced power cycle complete");
+				next;
+			}
+		} ## end elsif ($l =~ /failed error/)  [ if ($l =~ /createimage reboot/)
+	} ## end foreach $l (@{$sshcmd[1]})
+
+
+	#Set up simple ping loop to determine if machine is actually rebooting
+	my $online   = 1;
+	my $pingloop = 0;
+	notify($ERRORS{'OK'}, 0, "checking for pingable $computer_node_name");
+	while ($online) {
+		if (!(_pingnode($computer_node_name))) {
+			notify($ERRORS{'OK'}, 0, "Success $computer_node_name is not pingable");
+			$online = 0;
+		}
+		else {
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is still pingable - loop $pingloop");
+			sleep 10;
+			$pingloop++;
+		}
+		if ($pingloop > 10) {
+			notify($ERRORS{'CRITICAL'}, 0, "$computer_node_name should have rebooted by now, trying to force it");
+			if (VCL::Module::Provisioning::xCAT::_rpower($computer_node_name, "boot")) {
+				notify($ERRORS{'WARNING'}, 0, "forced power cycle complete");
+				sleep 25;
+				next;
+			}
+		}
+	} ## end while ($online)
+
+
+	# Wait until the reboot process has started to shutdown services
+	notify($ERRORS{'OK'}, 0, "$computer_node_name rebooting, waiting");
+	my $socketflag = 0;
+
+
+	REBOOTED:
+	my $rebooted          = 1;
+	my $reboot_wait_count = 0;
+	while ($rebooted) {
+		if ($reboot_wait_count > 55) {
+			notify($ERRORS{'CRITICAL'}, 0, "waited $reboot_wait_count on reboot after auto_create_image on $computer_node_name");
+			return 0;
+		}
+		notify($ERRORS{'OK'}, 0, "$computer_node_name not completed reboot sleeping for 25");
+		sleep 25;
+		if (_pingnode($computer_node_name)) {
+			#it pingable check if sshd is open
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is pingable, checking sshd port");
+			my $sshd = _sshd_status($computer_node_name, $image_name);
+			if ($sshd =~ /on/) {
+				$rebooted = 0;
+				notify($ERRORS{'OK'}, 0, "$computer_node_name sshd is open");
+			}
+			else {
+				notify($ERRORS{'OK'}, 0, "$computer_node_name sshd NOT open yet,sleep 5");
+				sleep 5;
+			}
+		} ## end if (_pingnode($computer_node_name))
+		$reboot_wait_count++;
+	}    # Close while rebooted
+
+
+	# Check for recent bug
+	undef @sshcmd;
+	@sshcmd = run_ssh_command($computer_node_name, $IDENTITY_wxp, "uname -s");
+	foreach my $l (@{$sshcmd[1]}) {
+		if ($l =~ /^Warning:/) {
+			#if (makesshgkh($computer_node_name)) {
+			#}
+		}
+		if ($l =~ /^Read from socket failed:/) {
+			if ($socketflag) {
+				notify($ERRORS{'CRITICAL'}, 0, "could not login $computer_node_name via ssh socket failure");
+				return 0;
+			}
+			notify($ERRORS{'CRITICAL'}, 0, "discovered ssh read from socket failure on $computer_node_name, attempting to repair");
+			#power cycle node
+			if (VCL::Module::Provisioning::xCAT::_rpower($computer_node_name, "cycle")) {
+				notify($ERRORS{'CRITICAL'}, 0, "$computer_node_name power cycled going to reboot check routine");
+				sleep 40;
+				$socketflag = 1;
+				goto REBOOTED;
+			}
+		} ## end if ($l =~ /^Read from socket failed:/)
+	} ## end foreach my $l (@{$sshcmd[1]})
+
+	notify($ERRORS{'OK'}, 0, "proceeding to CIMONITOR");
+	#monitor for signal to set node to image and then reboot
+	my $sshd_status;
+	my ($loop, $rebootsignal, $reboot_copied) = 0;
+	CIMONITOR:
+	#check ssh port in case we finish above steps before first reboot completes
+	# while ssh port is off sleep few seconds then loop
+	# this section is useless for linux images
+	my $ping_result = _pingnode($computer_node_name);
+	#check our loop
+	if ($loop > 200) {
+		notify($ERRORS{'CRITICAL'}, 0, "CIMONITOR $computer_node_name taking longer to reboot than expected, check it");
+		return 0;
+	}
+	notify($ERRORS{'OK'}, 0, "CIMONITOR ping check");
+	if (!$ping_result) {
+		sleep 5;
+		notify($ERRORS{'OK'}, 0, "CIMONITOR ping is off waiting for $computer_node_name to complete reboot");
+		$loop++;
+		goto CIMONITOR;
+	}
+	# is port 22 open yet
+	if (!nmap_port($computer_node_name, 22)) {
+		notify($ERRORS{'OK'}, 0, "port 22 not open on $computer_node_name yet, looping");
+		$loop++;
+		sleep 3;
+		goto CIMONITOR;
+	}
+
+	## Set sshd service startup to manual
+	#if (_set_sshd_startmode($computer_node_name, "manual")) {
+	#	notify($ERRORS{'OK'}, 0, "successfully set manual mode for sshd start");
+	#}
+	#else {
+	#	notify($ERRORS{'CRITICAL'}, 0, "failed to set manual mode for sshd on $computer_node_name");
+	#	return 0;
+	#}
+
+
+	#actually remove the pagefile.sys sometimes movefile.exe does not work
+	if (run_ssh_command($computer_node_name, $IDENTITY_wxp, "/usr/bin/rm -fv C:\/pagefile.sys")) {
+		notify($ERRORS{'OK'}, 0, "removed pagefile.sys ");
+	}
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+} ## end sub capture_prepare
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 capture_start
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub capture_start {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+
+	my $request_id               = $self->data->get_request_id();
+	my $reservation_id           = $self->data->get_reservation_id();
+	my $image_id                 = $self->data->get_image_id();
+	my $image_os_name            = $self->data->get_image_os_name();
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $image_os_type            = $self->data->get_image_os_type();
+	my $image_name               = $self->data->get_image_name();
+	my $imagemeta_sysprep        = $self->data->get_imagemeta_sysprep();
+	my $computer_id              = $self->data->get_computer_id();
+	my $computer_short_name      = $self->data->get_computer_short_name();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	my $computer_type            = $self->data->get_computer_type();
+	my $user_id                  = $self->data->get_user_id();
+	my $user_unityid             = $self->data->get_user_login_id();
+	my $managementnode_shortname = $self->data->get_management_node_short_name();
+	my $computer_private_ip      = $self->data->get_computer_private_ip();
+
+	notify($ERRORS{'OK'}, 0, "initiating Windows image capture: $image_name on $computer_short_name");
+
+	my @sshcmd;
+
+	if ($imagemeta_sysprep) {
+		notify($ERRORS{'OK'}, 0, "starting sysprep on $computer_node_name");
+		if (open(SSH, "/usr/bin/ssh -q -i $IDENTITY_wxp $computer_node_name \"C:\/Sysprep\/sysprep.cmd\" 2>&1 |")) {
+			my $notstop = 1;
+			my $loop    = 0;
+			while ($notstop) {
+				my $l = <SSH>;
+				$loop++;
+				#notify($ERRORS{'DEBUG'}, 0, "sysprep.cmd loop count: $loop");
+				#notify($ERRORS{'DEBUG'}, 0, "$l");
+				if ($l =~ /sysprep/) {
+					notify($ERRORS{'OK'}, 0, "sysprep.exe has started, $l");
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process in 60 seconds");
+					sleep 60;
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process");
+					if (_killsysprep($computer_node_name)) {
+						notify($ERRORS{'OK'}, 0, "killed sshd process for sysprep command");
+					}
+
+					notify($ERRORS{'DEBUG'}, 0, "closing SSH filehandle");
+					close(SSH);
+					notify($ERRORS{'DEBUG'}, 0, "SSH filehandle closed");
+
+					$notstop = 0;
+				} ## end if ($l =~ /sysprep/)
+				elsif ($l =~ /sysprep.cmd: Permission denied/) {
+					notify($ERRORS{'CRITICAL'}, 0, "chmod 755 failed to correctly set execute on sysprep.cmd output $l");
+					close(SSH);
+					return 0;
+				}
+
+				#avoid infinite loop
+				if ($loop > 1000) {
+					notify($ERRORS{'DEBUG'}, 0, "sysprep executed in loop control condition, exceeded limit");
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process in 60 seconds");
+					sleep 60;
+
+					notify($ERRORS{'DEBUG'}, 0, "attempting to kill management node sysprep.cmd SSH process");
+					if (_killsysprep($computer_node_name)) {
+						notify($ERRORS{'OK'}, 0, "killed sshd process for sysprep command");
+					}
+
+					notify($ERRORS{'DEBUG'}, 0, "closing SSH filehandle");
+					close(SSH);
+					notify($ERRORS{'DEBUG'}, 0, "SSH filehandle closed");
+
+					$notstop = 0;
+				} ## end if ($loop > 1000)
+
+			} ## end while ($notstop)
+		}    # Close open handle for SSH sysprep.cmd command
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to start sysprep on $computer_node_name $!");
+			return 0;
+		}    # Close sysprep.cmd could not be launched
+	}    # Close if Sysprep
+
+	else {
+		#non sysprep option
+		#
+		#just reboot machine -- future expansion of additional methods newsid, custom scripts, etc.
+		notify($ERRORS{'OK'}, 0, "starting custom script VCLprep1.vbs on $computer_node_name");
+		if (run_scp_command("$TOOLS/VCLprep1.vbs", "$computer_node_name:VCLprep1.vbs", $IDENTITY_wxp)) {
+			undef @sshcmd;
+			@sshcmd = run_ssh_command($computer_node_name, $IDENTITY_wxp, "cscript //Nologo VCLprep1.vbs", "root");
+			foreach my $s (@{$sshcmd[1]}) {
+				chomp($s);
+				if ($s =~ /copied VCLprepare/) {
+					notify($ERRORS{'OK'}, 0, "$s");
+				}
+				if ($s =~ /rebooting/) {
+					notify($ERRORS{'OK'}, 0, "SUCCESS started image procedure on $computer_node_name");
+					last;
+				}
+			} ## end foreach my $s (@{$sshcmd[1]})
+		}    # Close SCP VCLPrep1.vbs
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to copy $TOOLS/VCLprep1.vbs to $computer_node_name ");
+			return 0;
+		}
+	}    # Close if not Sysprep
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+} ## end sub capture_start
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 user_exists
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub user_exists {
+	my ($node, $user)  = @_;
+	notify($ERRORS{'WARNING'}, 0, "node is not defined") if (!(defined($node)));
+	notify($ERRORS{'WARNING'}, 0, "user is not defined") if (!(defined($user)));
+
+	my ($net_user_exit_status, $net_user_output) = run_ssh_command($node, $IDENTITY_wxp, "net user $user");
+	if ($net_user_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "user $user exists on $node");
+		return 1;
+	}
+	elsif ($net_user_exit_status == 2) {
+		notify($ERRORS{'OK'}, 0, "user $user does NOT exist on $node");
+		return 0;
+	}
+	elsif ($net_user_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine if user $user exists on $node, exit status: $net_user_exit_status, output:\n@{$net_user_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if user $user exists on $node");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 logoff_users
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub logoff_users {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, "qwinsta.exe");
+	if ($exit_status > 0) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run qwinsta.exe on $computer_node_name, exit status: $exit_status, output:\n@{$output}");
+		return;
+	}
+	elsif (!defined($exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run qwinsta.exe SSH command on $computer_node_name");
+		return;
+	}
+	
+	my @active_user_lines = grep(/Active/, @{$output});
+	
+	notify($ERRORS{'OK'}, 0, "users are currently logged in on $computer_node_name: " . @active_user_lines);
+	
+	foreach my $active_user_line (@active_user_lines) {
+		$active_user_line =~ /\s+(\S+)\s+(.*\w)\s*(\d+)\s+Active.*/;
+		my $session_name = $1;
+		my $username = $2;
+		my $session_id = $3;
+		
+		notify($ERRORS{'DEBUG'}, 0, "user logged in: $username, session name: $session_name, session id: $session_id");
+		
+		my ($logoff_exit_status, $logoff_output) = run_ssh_command($computer_node_name, $management_node_keys, "logoff.exe /v $session_id");
+		if ($logoff_exit_status == 0) {
+			notify($ERRORS{'OK'}, 0, "logged off user: $username, exit status: $logoff_exit_status, output:\n@{$logoff_output}");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to log off user: $username, exit status: $logoff_exit_status, output:\n@{$logoff_output}");
+		}
+		
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 delete_user
+
+ Parameters  : $node, $user, $type, $osname
+ Returns     : 1 success 0 failure
+ Description : removes user account and profile directory from specificed node
+
+=cut
+
+sub delete_user {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	# Attempt to get the username from the arguments
+	# If no argument was supplied, use the user specified in the DataStructure
+	my $username = shift;
+	if (!(defined($username))) {
+		$username = $self->data->get_user_logon_id();
+	}
+	
+	notify($ERRORS{'OK'}, 0, "attempting to delete user $username from $computer_node_name");
+	
+	# Attempt to delete the user account
+	my $delete_user_command = "net user $username /DELETE";
+	my ($delete_user_exit_status, $delete_user_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_user_command);
+	if (defined($delete_user_exit_status) && $delete_user_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "deleted user $username from $computer_node_name");
+	}
+	elsif (defined($delete_user_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to delete user $username from $computer_node_name, exit status: $delete_user_exit_status, output:\n@{$delete_user_output}");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command delete user $username from $computer_node_name");
+		return;
+	}
+
+	# Delete the user's home directory
+	my $delete_profile_command = "/bin/rm -rf /cygdrive/c/Users/$username";
+	my ($delete_profile_exit_status, $delete_profile_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_profile_command);
+	if (defined($delete_profile_exit_status) && $delete_profile_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "deleted profile for user $username from $computer_node_name");
+	}
+	elsif (defined($delete_profile_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to delete profile for user $username from $computer_node_name, exit status: $delete_profile_exit_status, output:\n@{$delete_profile_output}");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command delete profile for user $username from $computer_node_name");
+		return;
+	}
+	
+	return 1;
+} ## end sub del_user
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 disable_pagefile
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub disable_pagefile {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	my $disable_pagefile_key = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management";
+	my $disable_pagefile_command = "reg.exe add \"$disable_pagefile_key\" /v \"PagingFiles\" /t REG_SZ /d \"\" /f";
+	my ($disable_pagefile_exit_status, $disable_pagefile_output) = run_ssh_command($computer_node_name, $management_node_keys, $disable_pagefile_command);
+	if ($disable_pagefile_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "registry key set to disable pagefile");
+	}
+	elsif ($disable_pagefile_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to set registry key to disable pagefile, exit status: $disable_pagefile_exit_status, output:\n@{$disable_pagefile_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to set registry key to disable pagefile");
+		return;
+	}
+
+	# Attempt to reboot the computer in order to delete the pagefile
+	if ($self->reboot()) {
+		notify($ERRORS{'OK'}, 0, "computer was rebooted after disabling pagefile in the registry");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to reboot computer after disabling pagefile");
+		return;
+	}
+	
+	# Attempt to delete the pagefile
+	my $delete_pagefile_command = "attrib.exe -S -H -R C:/pagefile.sys";
+	$delete_pagefile_command .= " && /usr/bin/rm.exe -rfv C:/pagefile.sys";
+	my ($delete_pagefile_exit_status, $delete_pagefile_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_pagefile_command);
+	if ($delete_pagefile_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "pagefile.sys was deleted");
+		return 1;
+	}
+	elsif ($delete_pagefile_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to delete pagefile.sys, exit status: $delete_pagefile_exit_status, output:\n@{$delete_pagefile_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete pagefile.sys");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 import_registry_file
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub import_registry_file {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	my $registry_file_path = shift;
+	if (!defined($registry_file_path) || !$registry_file_path) {
+		notify($ERRORS{'WARNING'}, 0, "registry file path was not passed correctly as an argument");
+		return;
+	}
+	
+	my $registry_file_contents = `cat $registry_file_path`;
+	notify($ERRORS{'DEBUG'}, 0, "registry file contents:\n$registry_file_contents");
+	$registry_file_contents =~ s/([\"])/\\$1/gs;
+	
+	my $import_registry_command = "/usr/bin/echo.exe -E \"$registry_file_contents\" > tmp.reg";
+	$import_registry_command .= " && reg.exe IMPORT tmp.reg";
+	my ($import_registry_exit_status, $import_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $import_registry_command);
+	if ($import_registry_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "registry file contents imported");
+	}
+	elsif ($import_registry_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to import registry file contents, exit status: $import_registry_exit_status, output:\n@{$import_registry_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to import registry file contents");
+		return;
+	}
+	
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 import_registry_string
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub import_registry_string {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	my $registry_string = shift;
+	if (!defined($registry_string) || !$registry_string) {
+		notify($ERRORS{'WARNING'}, 0, "registry file path was not passed correctly as an argument");
+		return;
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "registry string:\n$registry_string");
+	$registry_string =~ s/([\"])/\\$1/gs;
+	
+	my $import_registry_command = "/usr/bin/echo.exe -E \"$registry_string\" > tmp.reg";
+	$import_registry_command .= " && reg.exe IMPORT tmp.reg";
+	my ($import_registry_exit_status, $import_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $import_registry_command);
+	if ($import_registry_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "registry string contents imported");
+	}
+	elsif ($import_registry_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to import registry string contents, exit status: $import_registry_exit_status, output:\n@{$import_registry_output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to import registry string contents");
+		return;
+	}
+	
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 enable_autoadminlogon
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub enable_autoadminlogon {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+
+	my $registry_string .= <<"EOF";
+Windows Registry Editor Version 5.00
+
+; This file enables autoadminlogon for the root account
+
+[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon]
+"AutoAdminLogon"="1"
+"DefaultUserName"="root"
+"DefaultPassword"= "$ROOT_PASSWORD"
+EOF
+	
+	# Import the string into the registry
+	if ($self->import_registry_string($registry_string)) {
+		notify($ERRORS{'WARNING'}, 0, "successfully enabled autoadminlogon");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to enable autoadminlogon");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 disable_autoadminlogon
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub disable_autoadminlogon {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+
+	my $registry_string .= <<EOF;
+Windows Registry Editor Version 5.00
+
+; This file disables autoadminlogon for the root account
+
+[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon]
+"AutoAdminLogon"="0"
+"DefaultUserName"=""
+"DefaultPassword"= ""
+EOF
+	
+	# Import the string into the registry
+	if ($self->import_registry_string($registry_string)) {
+		notify($ERRORS{'WARNING'}, 0, "successfully disabled autoadminlogon");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to disable autoadminlogon");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reboot
+
+ Parameters  : 
+ Returns     : 
+ Description : 
+
+=cut
+
+sub reboot {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	my $reboot_start_time = time();
+	notify($ERRORS{'DEBUG'}, 0, "reboot will be attempted on $computer_node_name");
+	
+	# Make sure sshd service is set to auto
+	notify($ERRORS{'DEBUG'}, 0, "attempting to make sure sshd service startup is set to auto");
+	if (_set_sshd_startmode($computer_node_name, "auto")) {
+		notify($ERRORS{'OK'}, 0, "successfully set sshd service startup mode to auto on $computer_node_name");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to set sshd service startup mode to auto on $computer_node_name");
+	}
+	
+	
+	# Initiate the shutdown.exe command to reboot the computer
+	my $shutdown_command = "C:/Windows/system32/shutdown.exe -r -t 0 -f";
+	my ($shutdown_exit_status, $shutdown_output) = run_ssh_command($computer_node_name, $management_node_keys, $shutdown_command);
+	if (defined($shutdown_exit_status)  && $shutdown_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "successfully executed reboot command on $computer_node_name");
+	}
+	elsif (defined($shutdown_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to execute reboot command on $computer_node_name, exit status: $shutdown_exit_status, output:\n@{$shutdown_output}");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to reboot $computer_node_name");
+		return;
+	}
+	
+	notify($ERRORS{'OK'}, 0, "sleeping for 30 seconds while $computer_node_name begins reboot");
+	sleep 30;
+	
+	# Wait maximum of 4 minutes for the computer to go offline then come back up
+	if (!$self->wait_for_ping(4)) {
+		# Check if the computer was ever offline, it should have been or else reboot never happened
+		notify($ERRORS{'WARNING'}, 0, "$computer_node_name never responded to ping, attempting hard power reset");
+		
+		# Just explicitly call xCAT's _rpower for now
+		# TODO: implement public reset() subroutines in all of the provisioning modules
+		# TODO: allow provisioning and OS modules access to each other's subroutines
+		if (VCL::Module::Provisioning::xCAT::_rpower($computer_node_name, "cycle")) {
+			notify($ERRORS{'OK'}, 0, "initiated hard power reset on $computer_node_name");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "reboot failed, failed to initiate hard power reset on $computer_node_name");
+			return 0;
+		}
+		
+		# Wait for computer to respond to ping after initiating hard reset
+		# Wait longer than the first attempt
+		if (!$self->wait_for_ping(6)) {
+			# Check if the computer was ever offline, it should have been or else reboot never happened
+			notify($ERRORS{'WARNING'}, 0, "reboot failed, $computer_node_name never responded to ping even after hard power reset");
+			return 0;
+		}
+	}
+	
+	notify($ERRORS{'OK'}, 0, "sleeping for 15 seconds while $computer_node_name initializes");
+	sleep 15;
+	
+	# Ping successful, try ssh
+	notify($ERRORS{'OK'}, 0, "waiting for ssh to respond on $computer_node_name");
+	if ($self->wait_for_ssh(3)) {
+		my $reboot_end_time = time();
+		my $reboot_duration = ($reboot_end_time - $reboot_start_time);
+		notify($ERRORS{'OK'}, 0, "reboot succeeded on $computer_node_name, took $reboot_duration seconds");\
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "reboot failed, ssh never became available on $computer_node_name");
+		return 0;
+	}
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 wait_for_ping
+
+ Parameters  : Maximum number of minutes to wait (optional)
+ Returns     : 1 if computer is pingable, 0 otherwise
+ Description : Attempts to ping the computer specified in the DataStructure
+               for the current reservation. It will wait up to a maximum number
+					of minutes. This can be specified by passing the subroutine an
+					integer value or the default value of 5 minutes will be used.
+
+=cut
+
+sub wait_for_ping {
+	my $self = shift;
+	my $computer_node_name = $self->data->get_computer_node_name();
+	
+	# Attempt to get the total number of minutes to wait from the command line
+	my $total_wait_minutes = shift;
+	if (!defined($total_wait_minutes) || $total_wait_minutes !~ /^\d+$/) {
+		$total_wait_minutes = 5;
+	}
+	
+	# Looping configuration variables
+	# Seconds to wait in between loop attempts
+	my $attempt_delay = 30;
+	# Total loop attempts made
+	# Add 1 to the number of attempts because if you're waiting for x intervals, you check x+1 times including at 0
+	my $attempts = ($total_wait_minutes * 2) + 1;
+	
+	notify($ERRORS{'OK'}, 0, "waiting for $computer_node_name to respond to ping, maximum of $total_wait_minutes minutes");
+	
+	# Loop until computer is online
+	my $computer_was_offline = 0;
+	my $computer_pingable = 0;
+	for (my $attempt = 1; $attempt <= $attempts; $attempt++) {
+		notify($ERRORS{'OK'}, 0, "attempt $attempt/$attempts: checking if computer is pingable: $computer_node_name");
+		$computer_pingable = _pingnode($computer_node_name);
+		
+		if ($computer_pingable && $computer_was_offline) {
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is pingable, reboot is nearly complete");
+			last;
+		}
+		elsif ($computer_pingable && !$computer_was_offline) {
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is still pingable, reboot has not begun");
+		}
+		else {
+			$computer_was_offline = 1;
+			notify($ERRORS{'OK'}, 0, "$computer_node_name is not pingable, reboot is not complete");
+		}
+		
+		notify($ERRORS{'OK'}, 0, "sleeping for $attempt_delay seconds before next ping attempt");
+		sleep $attempt_delay;
+	}
+	
+	# Check if the computer ever went offline and if it is now pingable
+	if ($computer_pingable && $computer_was_offline) {
+		notify($ERRORS{'OK'}, 0, "$computer_node_name was offline and is now pingable");
+		return 1;
+	}
+	elsif ($computer_pingable && !$computer_was_offline) {
+		notify($ERRORS{'WARNING'}, 0, "$computer_node_name was never offline and is still pingable");
+		return 0;
+	}
+	else {
+		my $total_wait = ($attempts * $attempt_delay);
+		notify($ERRORS{'WARNING'}, 0, "$computer_node_name is not pingable after waiting for $total_wait seconds");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 wait_for_ssh
+
+ Parameters  : Maximum number of minutes to wait (optional)
+ Returns     : 1 if ssh succeeded to computer, 0 otherwise
+ Description : Attempts to communicate to the computer specified in the
+               DataStructure for the current reservation via SSH. It will wait
+					up to a maximum number of minutes. This can be specified by
+					passing the subroutine an integer value or the default value
+					of 5 minutes will be used.
+
+=cut
+
+sub wait_for_ssh {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	# Attempt to get the total number of minutes to wait from the arguments
+	# If not specified, use default value
+	my $total_wait_minutes = shift;
+	if (!defined($total_wait_minutes) || $total_wait_minutes !~ /^\d+$/) {
+		$total_wait_minutes = 5;
+	}
+	
+	# Looping configuration variables
+	# Seconds to wait in between loop attempts
+	my $attempt_delay = 15;
+	# Total loop attempts made
+	# Add 1 to the number of attempts because if you're waiting for x intervals, you check x+1 times including at 0
+	my $attempts = ($total_wait_minutes * 4) + 1;
+	
+	notify($ERRORS{'OK'}, 0, "waiting for $computer_node_name to respond to ssh, maximum of $total_wait_minutes minutes");
+	
+	# Loop until ssh is available
+	my $ssh_result = 0;
+	for (my $attempt = 1; $attempt <= $attempts; $attempt++) {
+		notify($ERRORS{'OK'}, 0, "attempt $attempt/$attempts: checking ssh on computer: $computer_node_name");
+		
+		# Run a test SSH command
+		my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, "echo testing ssh on $computer_node_name");
+
+		# The exit status will be 0 if the command succeeded
+		if (defined($exit_status) && $exit_status == 0) {
+			notify($ERRORS{'OK'}, 0, "test ssh command succeeded on $computer_node_name");
+			return 1;
+		}
+		
+		notify($ERRORS{'OK'}, 0, "sleeping for $attempt_delay seconds before next ssh attempt");
+		sleep $attempt_delay;
+	}
+	
+	notify($ERRORS{'WARNING'}, 0, "$computer_node_name is not available via ssh");
+	return 0;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ping_private
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_enable_ping_private {
+	my $self = shift;
+	
+	my %firewall_parameters = (
+		name => 'VCL: allow ping from private network',
+		dir => 'in',
+		action => 'allow',
+		description => 'Allows incoming ping (ICMP type 8) messages from 10.x.x.x addresses',
+		enable => 'yes',
+		localip => '10.0.0.0/8',
+		remoteip => '10.0.0.0/8',
+		protocol => 'icmpv4:8,any',
+	);
+	
+	# Call the configure firewall subroutine, pass it the necessary parameters
+	if ($self->firewall_configure(\%firewall_parameters)) {
+		notify($ERRORS{'OK'}, 0, "successfully opened firewall for incoming ping on private network");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall for incoming ping on private network");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ssh_private
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_enable_ssh_private {
+	my $self = shift;
+	
+	my %firewall_parameters = (
+		name => 'VCL: allow ssh port 22 from private network',
+		dir => 'in',
+		action => 'allow',
+		description => 'Allows incoming TCP port 22 traffic from 10.x.x.x addresses',
+		enable => 'yes',
+		localip => '10.0.0.0/8',
+		remoteip => '10.0.0.0/8',
+		localport => '22',
+		protocol => 'TCP',
+	);
+	
+	# Call the configure firewall subroutine, pass it the necessary parameters
+	if ($self->firewall_configure(\%firewall_parameters)) {
+		notify($ERRORS{'OK'}, 0, "successfully opened firewall for incoming ssh via TCP port 22 on private network");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall for incoming ssh via TCP port 22 on private network");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_rdp
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_enable_rdp {
+	my $self = shift;
+	
+	# Check if the remote IP was passed correctly as an argument
+	my $remote_ip = shift;
+	if (!defined($remote_ip) || $remote_ip !~ /[\d\.\/]/) {
+		$remote_ip = 'any';
+	}
+	
+	my %firewall_parameters = (
+		name => "VCL: allow RDP port 3389 from $remote_ip",
+		dir => 'in',
+		action => 'allow',
+		description => "Allows incoming TCP port 3389 traffic from $remote_ip",
+		enable => 'yes',
+		remoteip => $remote_ip,
+		localport => '3389',
+		protocol => 'TCP',
+	);
+	
+	# Call the configure firewall subroutine, pass it the necessary parameters
+	if ($self->firewall_configure(\%firewall_parameters)) {
+		notify($ERRORS{'OK'}, 0, "successfully opened firewall for incoming RDP via TCP port 3389 from $remote_ip");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall for incoming RDP via TCP port 3389 from $remote_ip");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_disable_rdp
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_disable_rdp {
+	my $self = shift;
+	
+	#"\netsh.exe advfirewall firewall delete rule name=RDP protocol=TCP localport=3389"
+
+	my %firewall_parameters = (
+		name => 'all',
+		localport => '3389',
+		protocol => 'TCP',
+	);
+	
+	# Call the configure firewall subroutine, pass it the necessary parameters
+	if ($self->firewall_close(\%firewall_parameters)) {
+		notify($ERRORS{'OK'}, 0, "successfully closed firewall for incoming RDP via TCP port 3389");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to close firewall for incoming RDP via TCP port 3389");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_configure
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_configure {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	# Check the arguments
+	my $firewall_parameters = shift;
+	if (!defined($firewall_parameters) || !$firewall_parameters) {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall on $computer_node_name, parameters hash reference was not passed");
+		return;
+	}
+	if (!defined($firewall_parameters->{name}) || !$firewall_parameters->{name}) {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall on $computer_node_name, 'name' hash key was not passed");
+		return;
+	}
+	if (!defined($firewall_parameters->{dir}) || !$firewall_parameters->{dir}) {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall on $computer_node_name, 'dir' hash key was not passed");
+		return;
+	}
+	if (!defined($firewall_parameters->{action}) || !$firewall_parameters->{action}) {
+		notify($ERRORS{'WARNING'}, 0, "failed to open firewall on $computer_node_name, 'action' hash key was not passed");
+		return;
+	}
+	
+	# Add quotes around anything with a space in the parameters hash which isn't already enclosed in quotes
+	foreach my $rule_property (sort keys(%{$firewall_parameters})) {
+		$firewall_parameters->{$rule_property} =~ s/^(.*\s.*)$/\"$1\"/g;
+			notify($ERRORS{'DEBUG'}, 0, "enclosing property in quotes: $firewall_parameters->{$rule_property}");
+	}
+	
+	# Attempt to run the command to set existing firewall rule
+	
+	# Usage: set rule
+	#		group=<string> | name=<string>
+	#		[dir=in|out]
+	#		[profile=public|private|domain|any[,...]]
+	#		[program=<program path>]
+	#		[service=service short name|any]
+	#		[localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
+	#			<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[localport=0-65535|RPC|RPC-EPMap|any[,...]]
+	#		[remoteport=0-65535|any[,...]]
+	#		[protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
+	#			tcp|udp|any]
+	#		new
+	#		[name=<string>]
+	#		[dir=in|out]
+	#		[program=<program path>
+	#		[service=<service short name>|any]
+	#		[action=allow|block|bypass]
+	#		[description=<string>]
+	#		[enable=yes|no]
+	#		[profile=public|private|domain|any[,...]]
+	#		[localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
+	#			<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[localport=0-65535|RPC|RPC-EPMap|any[,...]]
+	#		[remoteport=0-65535|any[,...]]
+	#		[protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
+	#			tcp|udp|any]
+	#		[interfacetype=wireless|lan|ras|any]
+	#		[rmtcomputergrp=<SDDL string>]
+	#		[rmtusrgrp=<SDDL string>]
+	#		[edge=yes|no]
+	#		[security=authenticate|authenc|notrequired]
+	
+	# Assemble the command based on the keys populated in the hash
+	my $set_rule_command = "netsh.exe advfirewall firewall set rule";
+	$set_rule_command .= " name=$firewall_parameters->{name}";
+	$set_rule_command .= " new";
+	foreach my $rule_property (sort keys(%{$firewall_parameters})) {
+		next if $rule_property eq 'name';
+		$set_rule_command .= " $rule_property=$firewall_parameters->{$rule_property}";
+	}
+	
+	# Attempt to set properties of existing rule
+	notify($ERRORS{'DEBUG'}, 0, "attempting to set matching firewall rules on $computer_node_name, command:\n$set_rule_command");
+	my ($set_rule_exit_status, $set_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $set_rule_command);
+	if (defined($set_rule_exit_status)  && ($set_rule_exit_status == 0)) {
+		notify($ERRORS{'OK'}, 0, "successfully set matching firewall rules");
+		return 1;
+	}
+	elsif (defined($set_rule_exit_status)  && ($set_rule_exit_status == 1)) {
+		notify($ERRORS{'OK'}, 0, "unable to set matching firewall rules, rule does not exist");
+	}
+	elsif (defined($set_rule_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to set matching firewall rules on $computer_node_name, exit status: $set_rule_exit_status, output:\n@{$set_rule_output}");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to set matching firewall rules on $computer_node_name");
+	}
+	
+	
+	# Attempt to run the command to add the firewall rule
+	
+	# Usage: add rule name=<string>
+	#      dir=in|out
+	#      action=allow|block|bypass
+	#      [program=<program path>]
+	#      [service=<service short name>|any]
+	#      [description=<string>]
+	#      [enable=yes|no (default=yes)]
+	#      [profile=public|private|domain|any[,...]]
+	#      [localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#      [remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
+	#         <IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#      [localport=0-65535|RPC|RPC-EPMap|any[,...] (default=any)]
+	#      [remoteport=0-65535|any[,...] (default=any)]
+	#      [protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
+	#         tcp|udp|any (default=any)]
+	#      [interfacetype=wireless|lan|ras|any]
+	#      [rmtcomputergrp=<SDDL string>]
+	#      [rmtusrgrp=<SDDL string>]
+	#      [edge=yes|no (default=no)]
+	#      [security=authenticate|authenc|notrequired (default=notrequired)]
+	
+	# Assemble the command based on the keys populated in the hash
+	my $add_rule_command = "netsh.exe advfirewall firewall add rule";
+	$add_rule_command .= " name=$firewall_parameters->{name}";
+	foreach my $rule_property (sort keys(%{$firewall_parameters})) {
+		next if $rule_property eq 'name';
+		$add_rule_command .= " $rule_property=$firewall_parameters->{$rule_property}";
+	}
+	
+	# Add the firewall rule
+	my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+	if (defined($add_rule_exit_status)  && $add_rule_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "successfully added firewall rule");
+	}
+	elsif (defined($add_rule_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule on $computer_node_name, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule on $computer_node_name");
+		return;
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_close
+
+ Parameters  : 
+ Returns     : 1 if succeeded, 0 otherwise
+ Description : 
+
+=cut
+
+sub firewall_close {
+	my $self = shift;
+	my $management_node_keys     = $self->data->get_management_node_keys();
+	my $computer_node_name       = $self->data->get_computer_node_name();
+	
+	# Make sure firewall parameters hash was passed
+	my $firewall_parameters = shift;
+	if (!defined($firewall_parameters) || !$firewall_parameters) {
+		notify($ERRORS{'WARNING'}, 0, "failed to close firewall on $computer_node_name, parameters hash reference was not passed");
+		return;
+	}
+	
+	# Add quotes around anything with a space in the parameters hash which isn't already enclosed in quotes
+	foreach my $rule_property (sort keys(%{$firewall_parameters})) {
+		$firewall_parameters->{$rule_property} =~ s/^(.*\s.*)$/\"$1\"/g;
+		notify($ERRORS{'DEBUG'}, 0, "enclosing '$rule_property' property in quotes: $firewall_parameters->{$rule_property}");
+	}
+	
+	# Usage: delete rule name=<string>
+	#		[dir=in|out]
+	#		[profile=public|private|domain|any[,...]]
+	#		[program=<program path>]
+	#		[service=<service short name>|any]
+	#		[localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
+	#			<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
+	#		[localport=0-65535|RPC|RPC-EPMap|any[,...]]
+	#		[remoteport=0-65535|any[,...]]
+	#		[protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
+	#			tcp|udp|any]
+
+	# Assemble the command based on the keys populated in the hash
+	my $delete_rule_command = "netsh.exe advfirewall firewall delete rule";
+	foreach my $rule_property (sort keys(%{$firewall_parameters})) {
+		$delete_rule_command .= " $rule_property=$firewall_parameters->{$rule_property}";
+	}
+	
+	# Attempt to delete existing rules
+	notify($ERRORS{'DEBUG'}, 0, "attempting to delete matching firewall rules on $computer_node_name, command:\n$delete_rule_command");
+	my ($delete_rule_exit_status, $delete_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $delete_rule_command);
+	if (defined($delete_rule_exit_status)  && ($delete_rule_exit_status == 0)) {
+		notify($ERRORS{'OK'}, 0, "successfully deleted matching firewall rules");
+		return 1;
+	}
+	elsif (defined($delete_rule_exit_status)  && ($delete_rule_exit_status == 1)) {
+		notify($ERRORS{'OK'}, 0, "unable to delete matching firewall rules, rule does not exist");
+		return 1;
+	}
+	elsif (defined($delete_rule_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to delete matching firewall rules on $computer_node_name, exit status: $delete_rule_exit_status, output:\n@{$delete_rule_output}");
+		return 0;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to delete matching firewall rules on $computer_node_name");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+=head1 COPYRIGHT AND LICENSE
+
+ Copyright (C) 2004-2008 by NC State University. All Rights Reserved.
+
+ Virtual Computing Laboratory
+ North Carolina State University
+ Raleigh, NC, USA 27695
+
+ For use license and copyright information see LICENSE and COPYRIGHT files
+ included in the source files.
+
+=cut

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/XP.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/XP.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/XP.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/XP.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+##############################################################################
+# $Id: XP.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Windows::Desktop::XP
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides...
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows::Desktop::XP;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows::Desktop);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+=head1 COPYRIGHT AND LICENSE
+
+ Copyright (C) 2004-2008 by NC State University. All Rights Reserved.
+
+ Virtual Computing Laboratory
+ North Carolina State University
+ Raleigh, NC, USA 27695
+
+ For use license and copyright information see LICENSE and COPYRIGHT files
+ included in the source files.
+
+=cut

Propchange: incubator/vcl/tags/import/managementnode/lib/VCL/Module/OS/Windows/Desktop/XP.pm
------------------------------------------------------------------------------
    svn:executable =