VMware Cloud Community
AymanSammour
Contributor
Contributor

Invoke-VMScript as a background job

I am pushing software to Newley created VMs, My script uses ini file to get the software required, including the argument list for that software, what I have noticed, if someone made a mistake (Typo) with the argument list field in the ini file, it will create an issue  when script runs, it gets stuck,

as the whole script is fully automated and runs unattended,  

I need to create a background job to run and time it if took longer that 5 min to terminate and carry one with the script  

any guidance would be appreciated 

Reply
0 Kudos
5 Replies
LucD
Leadership
Leadership

Can you share some minimal code to show how exactly you are running this script in the Guest OS?
Do you use Invoke-VMScript with the RunAsync switch?
If yes, you could add a loop to the script that calls Invoke-VMScript to wait for 5 minutes, if the script, in the Guest OS, doesn't return by then you could launch another script to kill the previous one.

But it depends on how you call Invoke-VMScript and what exactly you are running in the script in the Guest OS


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
AymanSammour
Contributor
Contributor

$AgentDetails=Select-HashTable -Hashtable $loadVars -Include $Agent
Write-Host $AgentDetails
$AgentName =$AgentDetails.Keys
$AgentFile =$AgentDetails.values.AgentName
$ListofServices =$AgentDetails.values.ListofServices
$Operators =$AgentDetails.values.ArgumentList
$InstallerFullpath=$AgentLocalfolder+"\"+$AgentFile
#Check if the String is empty before you split

if (-not([String]::IsNullOrWhiteSpace( $ListofServices))){
#Start to split
$ListofServices= $ListofServices.split(",")}

$Arguments =$Operators.Split("|")
$ArgumentList=@($Arguments)


Write-host "
AgentName $AgentName
ListofServices $ListofServices
ArgumentList $ArgumentList " -ForegroundColor Green

$PoS=$AgentFile.LastIndexOf(".")
$Extension=($AgentFile.Substring($PoS+1)).ToUpper()
if ($Extension -eq "MSI"){
$Installagent=@'
Start-Process "msiexec.exe" -Wait -NoNewWindow -ArgumentList '$ArgumentList'
'@
}

elseif ($Extension -eq "EXE"){
$Installagent=@'
Start-Process -FilePath $InstallerFullpath -ArgumentList '$ArgumentList'
'@
}


$install=$executionContext.InvokeCommand.ExpandString($Installagent)


$installCommand =Invoke-VMScript -vm $vmname -ScriptText $install -GuestCredential $WinodwsLocalCredentials -Server $vCentre -ScriptType Powershell -RunAsync -Verbose

Reply
0 Kudos
LucD
Leadership
Leadership

With Start-Process you start a background process.
With the PassThru switch you can monitor such a process and implement a timeout.
Something along these lines

$pName = '<your.exe>'
$timeout = 300

$start = Get-Date
$process = Start-Process $pName -PassThru

while((Get-Process -Id $process.Id) -and (New-TimeSpan -Start $start -End (Get-Date)).TotalSeconds -lt $timeout){
    sleep 5
}
if(Get-Process -Id $process.Id){
    Stop-Process -Id $process.Id
    Write-Host "Process stopped after timeout"
}
else{
    Write-Host "Process ended"
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
AymanSammour
Contributor
Contributor

the process name can be my invoke statement right ? 

Reply
0 Kudos
LucD
Leadership
Leadership

Not sure what you mean, but you will have to run this inside the Guest OS.
In other words, code like that has to be incorporated inside the code that you launch via Invoke-VMScript.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos