SHIFT

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


Sidebar

Recently Changed Pages:

View All Pages


View All Tags


LinkedIn




WIKI Disclaimer: As with most other things on the Internet, the content on this wiki is not supported. It was contributed by me and is published “as is”. It has worked for me, and might work for you.
Also note that any view or statement expressed anywhere on this site are strictly mine and not the opinions or views of my employer.


Pages with comments

View All Comments

srmguestscript

SRM Script in Recovered VM: Check And Start Automatic Services

Because the script in SRM Script: Start All Windows Services only works in case of a recovery and not in tests, I decided to have the Windows Services checked from within the VM itself. Because the script needs to be run from the VM itself it had to be a script that every Windows version we use would understand and be able to execute. So that means that powershell is out of the question because that is not installed on each server.

Luckily, a collegue created a vbs script (the horror!) which can be executed by both Windows Server 2003 and Windows Server 2008. So, the process to get this script running in SRM recovered VMs is like this:

  1. Use a powershell script, run from the SRM server, for each VM, to copy a vbs script and a start script to the VM
  2. Start the vbs script using the option to start a script inside the VM

So this requires quite a lot configuration:

  • A powershell script which has to be started for each VM
  • A vbs script that has to be copied to the VM
  • A start script that has to be copied to the VM

The Scripts

Powershell Script to Copy Other Scripts

# Script Details
# Author: Sjoerd Hooft
# Creation Date: 2013-04-16
 
# Note: this is a light script to reduce overhead and execution time for these powershells command. The only thing logged is the errors. 
 
# Script functionality
# 1. Copy scripts to recovered VM
# 3. Email the errors to the SRM administrator
 
# Variables
$scriptname = $myinvocation.mycommand.name
$scriptlocation = Split-Path $myinvocation.mycommand.path
$vcenter = $env:VMware_VC_Host
$vm = $env:VMware_VM_Name
$vbsscript = "CheckServices.vbs"
$cmdscript = "startCheckServices.bat"
$MailServer = "10.10.10.25"
$toemail = "it@getshifting_com"
$fromemail = "vcenter$getshifting_com"
$guestdir = "C:\SRM"
 
# Add VMware snapin
if(-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)){
   Add-PSSnapin VMware.VimAutomation.Core}
 
# Email functions
Function Send-Email ($subject, $info){
   Send-MailMessage -To $toemail -From $fromemail -SmtpServer $mailserver -Subject $subject -Body $info}
 
# Connect to vCenter
Connect-VIServer $vcenter
 
# Copy scripts to VM
Copy-VMGuestFile -Source $scriptlocation\$vbsscript -Destination $guestdir -Force -VM $vm -LocalToGuest -HostUser root -HostPassword XXXXXXXXXXXX -GuestUser Administrator -GuestPassword XXXXXXXXXXXXXXXXXXXX
Copy-VMGuestFile -Source $scriptlocation\$cmdscript -Destination $guestdir -Force -VM $vm -LocalToGuest -HostUser root -HostPassword XXXXXXXXXXXX -GuestUser Administrator -GuestPassword XXXXXXXXXXXXXXXXXXXX
 
# Disconnect from vCenter
Disconnect-VIServer * -Confirm:$false
 
# Send last 10 errors to logfile
$allerrors = $error[0..9]
 
# Preparing info for email
# It would be preferred to list the recovery plan name in the subject and the VMs in the body. This is yet not possible with powershell/powerCLI.
$subject = "Result: $scriptname : $VM"
$info = "These are the last 10 errors: $allerrors"
Send-Email $subject $info

VBS Script to Check And Start Services

The name of the VBS script should be “CheckServices.vbs”:

' Name : Checkservices.vbs
' Description : This script will check if Automatic Services are running, if not it wil start the service.
'               After 5 minutes is will run the check again.
'		At the end it will make a log file of the action taken place. If the second check gives not started 
'		automatic services, it will also change the file name to easily sort the problems in a filelist
' Author : Mark Rinket
' Version : 1.00
' Date : 10-04-2013
 
'Create output Array
Set OutputText = CreateObject("System.Collections.ArrayList")
OutputText.add "Services check"
OutputText.add "=============="
 
' Create an Array of services which will not be checked
Set ListNonCheck = CreateObject("System.Collections.ArrayList")
 
ListNonCheck.add "TBS"
ListNonCheck.add "Ati Hotkey Poller"
ListNonCheck.add "NetBackup SAN Client Fibre Transport Service"
ListNonCheck.add "BMR Boot Service"
ListNonCheck.add "clr_optimization_v4.0.30319_32"
ListNonCheck.add "clr_optimization_v4.0.30319_64"
ListNonCheck.add "sppsvc"
ListNonCheck.add "SysmonLog"
ListNonCheck.add "ShellHWDetection"
 
 
'Create FileObject
Set objFSO=CreateObject("Scripting.FileSystemObject")
 
'Create log file
outFile="c:\srm\log.txt"
Set objFile = objFSO.CreateTextFile(outFile,True)
 
'output to logfile
objFile.Write "Start script" & vbCrLf
objFile.Write "Waiting 5 minutes" & vbCrLf
 
'wait 5 minutes
'5 minutes is 300000 (5 min * 60 sec * 1000 milliseconds)
 
OutputText.add "Waiting 5 minutes.."
wscript.sleep 300000
OutputText.add ""
 
 
'set to local computer
strComputer = "."
 
'Make an WMI object
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
 
OutputText.add "First Check"
OutputText.add "==========="
 
 
'Retrieve list of services
Set objListOfServices = objWMIService.ExecQuery("Select * from Win32_Service")
 
'Reset counters
CountStopped=0
CountRunning=0
 
'walk trough all services
For Each objService in objListOfServices
 
	'Reset Checker
	Check=True
 
	'service need te be CHECKED
	For each NonChecked in  ListNonCheck
 
		if NonChecked = objService.name then check=False
	next
 
	'if check is needed find out if it is in Automatic mode
	if Check=True and objService.StartMode = "Auto" then
 
		'Output to logfile
		objFile.Write "Checking : " & objService.name & " ; " & objService.DisplayName & vbCrLf
 
		'Is it running
		if objService.State <> "Running" then
 
			'Service is not running; at entry to file
			OutputText.add "Starting : " & objService.name & " ; " & objService.DisplayName
 
 
 
			'Start service
			errReturn = objService.StartService() 
			OutputText.add "Return Status :" & errReturn
			OutputText.add ""
			CountStopped=CountStopped+1
		else
 
 
			CountRunning=CountRunning+1
 
		end if 
 
 
	end if
 
 
Next
 
'If services were restarted wait and check again
if CountStopped>0 then
 
	'wait 5 minutes
	'5 minutes is 300000 (5 min * 60 sec * 1000 milliseconds)
 
 
	OutputText.add ""
	OutputText.add "Waiting 5 minutes.."
	wscript.sleep 300000
	OutputText.add ""
 
	OutputText.add "Second Check"
	OutputText.add "============"
 
 
	'Reset counters
	CountStopped=0
	CountRunning=0
 
	'walk through all services
	Set objListOfServices = objWMIService.ExecQuery("Select * from Win32_Service")
 
	For Each objService in objListOfServices
 
		'Reset Checker
		Check=True
 
		'service need te be CHECKED
		For each NonChecked in ListNonCheck
 
			if NonChecked = objService.name then check=False
		next
 
		'if check is needed find out if it is in Automatic mode
		if Check=True and objService.StartMode = "Auto" then
 
 
			'Is it running
			if objService.State <> "Running" then
 
				'Service is not running; at entry to file
				OutputText.add objService.name & " ; " & objService.DisplayName
				CountStopped=CountStopped+1
 
			else
				CountRunning=CountRunning+1
 
			end if 
 
 
		end if
 
 
	Next
 
end if
 
'Close Log file
objFile.Close
 
 
'add info about all Automatic Services
OutputText.add ""
OutputText.add "TOTAL: Services Running: " & CountRunning & "; Stopped Serives: " & CountStopped
 
 
'Get Computername
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
 
'Check if second run still has not running services.
if CountStopped > 0 then
 
	'Create failed text file
	outFile="c:\srm\Failed-" & strComputer & "-services.txt"
	Set objFile = objFSO.CreateTextFile(outFile,True)
 
else
 
	'Create normal text file
	outFile="c:\srm\"  & strComputer & "-services.txt"
	Set objFile = objFSO.CreateTextFile(outFile,True)
 
end if
 
'Write all outputText entries to the file
For each OutputLine in OutputText
 
	objFile.Write OutputLine & vbCrLf
 
next
 
'Close file
objFile.Close

Start Script

The name of this batfile should be “startcheckservices.bat”:

c:\windows\system32\cscript.exe c:\srm\CheckServices.vbs //NoLogo //B

Configure Protected VM

With all the script in place the VMs can be configure. In SRM, go to the recovery plan of the VMs and navigate to the VMs tab:

  • Select the VM and click “Configure Recovery”
  • Select the “Post Power On Steps” and click on Add
  • Select “Command on SRM Server”, and configure like this:
    • Name: Copy Services Script To VM
    • Content: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File G:\scripts\srmguestservices.ps1
    • Timeout: 10 minutes
  • Click OK and click on Add again
  • Select “Command on Recovered VM”, and configure like this:
    • Name: Check Services
    • Content: C:\Windows\System32\cmd.exe /C C:\srm\startcheckservices.bat
    • Timeout: 2 minutes
  • Click OK

Now the VM is configured to run the scripts as required. Note the following points:

  • If the VMware Tools timeout the post power on commands will not be executed. You'll have to test what is an acceptable timeout for your VMware Tools
  • The check services script will take at least 5 minutes, and will therefor always timeout in the recovery plan. The script will however continue to run, and so will your recovery plan, minimizing the recovery time.

Resources

You could leave a comment if you were logged in.
srmguestscript.txt · Last modified: 2021/09/24 00:25 (external edit)