Hi All,
I am trying to check the state of the EX host managed by VCenter server.
I wrote this snippet and I am using 'start-job' powershell cmdlet.
{{{
$backGroundJob = Start-Job -Name "ping" -ScriptBlock {
while(1)
{
$ret = Get-VMHost -Name $esxServer
if($ret.ConnectionState -ne "Connected")
{
Write-Log "ERROR" "The ESX server $esxServer is not reachable..."
break
}
else
{
Write-Log "DEBUG" "The ESX server $esxServer is reachable..."
continue
}
}
}
}}}
Write-Log is auser defined fucntion which will write messages on console and as well as in file.
When I try to run this, I did not get any messages in the file. Which means this does not seem to work. !
Any ideas??
Thanks
Nikunj
PS background jobs run in their own runspace.
Have a look at PowerCLI – Using PowerShell Jobs to see how this could be done.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
I wrote the folowing function. It is supposed to be looping continuously checking for ESX server's state. But when I do 'get-job', I get that the job is completed.
{{{
Function checkESXReachability($viServer, $esxServer)
{
$jobcmd = {
$in = $input.'<>2__this'.read();
Add-PSSnapin VMware.VimAutomation.Core -EA silentlycontinue -EV Err;
Connect-viServer -Server $in[1];
while(1)
{
$ret = Get-VMHost -Name $in[2];
if($ret.ConnectionState -ne "Connected")
{
Write-Log "ERROR" "The ESX server $esxServer is not reachable...";
break;
}
else
{
Write-Log "DEBUG" "The ESX server $esxServer is reachable...";
continue;
}
}
}
$jobargs = @()
$jobargs += $jobcmd
$jobargs += $viServer
$jobargs += $esxServer
$backGroundJob = Start-Job -Name "ping" -InputObject $jobargs -ScriptBlock $jobargs[0]
}
}}}
Please help me find out the error.
How to make Write-Log function visible to this background job ?
Thanks
Nikunj
Try adding Start-Transcript and Stop-Transcript cmdlets to your code block.That could perhaps show you what goes wrong.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Thanks for the inputs.
On the powershell interpreter prompt. I did :
PS C:\> start-transcript -path C:transcripts\transcripts0.txt -noclobber
and then line by line I pasted my code snippet in the interpreter.
Even now, its not showing anything.!
Any pointers ?
Thanks
Nikunj
Are you running this on a XP machine ?
There is a known problem when adding a pssnapin from within a background job.
See Adding a snapin (add-pssnapin) from within a job (start-job) causes job to hang indefinitely
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi
I am running it on Windows server 2008.
I checked that link. The bug seems to be not present for Windows server 2008.
Any other pointers ?
Thanks
Nikunj
I don't think you can write to a transcript file from a background job (or at least I've never managed to do it directly). You can get the console output from a job by using the Receive-Job cmdlet, so something like this once your job has completed...
Start-Transcript -Path "BackgroundJob.log"
Receive-Job -Id $backGroundJob.Id
Stop-Transcript
I tried to do something similar with background jobs a while back and gave up, it was far simpler to have a PowerCLI script that runs in a continuous loop.
One thing to be aware of is that you can't run PowerCLI jobs on a 64 bit environment, so if you're running on a 64 bit machine, you'll run the x86 version of Powershell and PowerCLI.
You are right SImon, the ServerRemoteHost engine, which is what runs the background jobs, doesn't support Transcripts
You can force the 32-bit PS by calling it explictely.
For example the following CMD file calls the PS 32-bit (on a 64-bit machine) and start a script
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -c "C:\Temp\Test-job.ps1"
This Test-job.ps1 script looks like this
$job = { Add-PSSnapin VMware.VimAutomation.Core -EA silentlycontinue -EV Err
Connect-viServer -Server MyVC
$esx = Get-VMHost -Name MyEsx
$esx.ConnectionState } Start-Transcript "C:\Temp\transcript.txt" $job = Start-Job -Name "Test" -ScriptBlock $job
while((Get-Job -Id $job.Id).State -eq "running"){ sleep 5
} Receive-Job -Id $job.Id Stop-Transcript
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi All,
Thanks for the inputs. I will take care of various points with regard to adding snapins in background jobs.
I am trying to 'dot source' few of my scripts which has various functions and variable declarations. I will do that by using 'initializationscript' argument of start-job cmdlet.
1. How do I put multiple 'initializationscript' in 'start-job' commandlet. ? i.e If I have 2 or more scripts for dot sourcing.? I tried with passing an array variable (initarray) but it seems to be not working. it gives me this error.
{
Unexpected token 'initarray' in expression or statement.
}
Here are my commands.
{
PS C:\> $initarray
. C:\scripts\bgtask.PS1
. C:\scripts\logger.PS1
PS C:\> $ret = start-job -scriptblock {checkESXReachability $viserverip $esxserverip } -initializationscript { $initarray[0] $initarray[1] }
}
The function checkESXReachability is defined in file bgtask.PS1. The function also uses 'Write-Log' function which is defined in logger.PS1 file.
2. How do I generate a PSCredential object by using 'connect-viserver' cmdlet.? I have made connect-viserver to always ask for login credentials at the beginnig of the script. So that once user has given it, I can generate a PSCredential object and then I can pass this object in my background job during the later stages of the script. !
Please help !
Thanks
Nikunj
1) You can have multiple statements in the InitializationScript block. Just put all your dot-source lines in the block
$ret = start-job -scriptblock {checkESXReachability $viserverip $esxserverip } -initializationscript {
. C:\scripts\bgtask.PS1
. C:\scripts\logger.PS1}
2) You can prompt for the user and password with Read-Host cmdlets at the beginning of the script.
Then use these for all Connect-VIServer lines
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Regarding 1)
My bad !! It was easy !
Regarding 2)
If I am using connect-viserver with -savecredential parameter in the first time then now It shouldnt ask me again for credentials for doing connect-viserver again in the background job right ?
That is correct, if you do your first Connect-VIserver as follows
Connect-VIServer -Server MyVC -Credential (Get-Credential) -SaveCredentials
you can do later on in the script
$cred = Get-VICredentialStoreItem -Server MyVC
Connect-VIServer -Server MyVC -Credential $cred
Just watch out that there aren't multiple entries in the local credential store for that server.
If there are, you could eventually use the User property to filter out the Credential you want
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Okay, Thanks.!
Just one more thing. I am not able to use relative paths or full paths taken in a variable, in '-initializationscript' or in '-scriptblock' ?
Ex.
$bg = Start-Job -Name "ping" -scriptblock { C:\scripts\bgtask.PS1 `
$args[0] $args[1] $args[2] } -ArgumentList @($viserver, $esxserver, $logfile) `
-initializationscript { . C:\scripts\logger.PS1 ; }
Will work fine, but if I change directory to scripts\ and then run the same..
$bg = Start-Job -Name "ping" -scriptblock { .\bgtask.PS1 `
$args[0] $args[1] $args[2] } -ArgumentList @($viserver, $esxserver, $logfile) `
-initializationscript { . .\logger.PS1 ; }
This will not work !.
Even if I take full paths in a variable and then use that variable ( ex. $fulllfilepath = C:\scripts\bgtask.PS1 ) this also wont work.?
The background jobs run in a new PS engine and with a new PS environment.
So the 'Set-Location' you do before you do the Start-Job, this directory will not be reflected inside the background job.
You could do the 'Set-Location' in the InitializationScript block before you do your dot-source statements.
Did you set the variable $fulllfilepath before the Start-Job ?
If yes, that variable is not known in the new PS engine
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference