I’ve come across a very unusual problem. I’ve used jobs for parallel tasks against lots of devices, and have had lots of success with it. Right now though I’ve got an issue where my script runs fine but the line that kicks off the software install fails. This is where it gets really odd. I can take that same line of code that failed in the jobs script, run just that line and it will not fail.
The software I’m trying to install is VMWare View. Its an upgrade for thin client devices with file based write filters. It generates some logs that don’t help much. In the event viewer i see an error with the following entry “Product: VMware Horizon View Client – Error 1306.Another application has exclusive access to the file C:\ProgramData\VMware\VDM\logs\debug-2016-10-09-141938.txt. Please shut down all other applications, then click Retry.”
Don’t know why access to a txt file would stop the install from succeeding but that’t the only error in event viewer. The other verbose logs don’t help much. I could post my code, but i’m hoping someone else that uses jobs may have run into this problem before. Well I guess i’ll post the code, as to avoid someone asking for it.
#installing view 3.5.2
#10/7/2016
#Sam Kachar II
[string]$computers = cat ‘C:\352\testinstall.txt’
$total = $computers.Count
$maxjobs=70 #Number of Jobs to Run at one time
#$chunksize = 2 #Number of machines to run per job; thought i would use this but decided it better to just run one machine per job.
$jobs=@() #Initialize $job variable
#script block that will be called by start-job
$sb = {
param($computers,$i)
$comp = $computers[$i]
if (Test-Connection -computername $comp -Count 1 -Quiet){ #is the machine online??? If online log as online, failure will be logged
try{
Invoke-WMIMethod -Class Win32_Process -Name Create -Computername $comp -ArgumentList "cmd /c fbwfmgr.exe /disable" | Out-Null
Restart-Computer -ComputerName $comp -Force
sleep -Seconds 90
try{
Copy-Item -Path 'C:\352\x86\' -Destination "\\$comp\c$\install\352\" -Force -Recurse | Out-Null
}
catch{
sleep -Seconds 30
Copy-Item -Path 'C:\352\x86\' -Destination "\\$comp\c$\install\352\" -Force -Recurse | Out-Null
}
finally{
write-host "running finally block now"
#Invoke-WMIMethod -Class Win32_Process -Name Create -Computername $comp -ArgumentList "cmd /c c:\install\352\install352x86.cmd"
sleep -Seconds 20
#This line calls the actual install. It works outside of the job, but not when the script runs in its entirety. The above cmd had this line in it.
#I pulled the line out to narraw down the issue. If i run just this line the software installs...
Invoke-WMIMethod -Class Win32_Process -Name Create -Computername $comp -ArgumentList "cmd /c c:\install\352\352x86.exe /S /V`" /qn`""
sleep -Seconds 180
}
[bool[]]$x
$p = 0
$x = "true"
while($x){
sleep -Seconds 1
$p++
#write-host $p
$viewversion = (dir "\\$comp\c$\install\vmwareview\ThinClientShell.hta").LastWriteTime
if($viewversion.Year -eq 2016)
{
break
}
elseif ($p -gt 120){
break
}
}
#Invoke-WMIMethod -Class Win32_Process -Name Create -Computername $comp -ArgumentList "cmd /c fbwfmgr.exe /enable"
"$comp" | Out-File -LiteralPath "c:\352\online\installed.txt" -force -Append
}
catch
{
"$comp" | Out-File -LiteralPath "c:\352\failed\failed.txt" -force -Append
}
}
#If the machine was offline then this will log the machine name for later processing
else {
"$comp" | Out-File -literalpath "c:\352\offline\offline.txt" -force -Append
}
}
#This for loop is what controls the number of jobs and fire’s them off
for ($i=0;$i -lt $total; $i++){
$jobs += Start-Job -ScriptBlock $sb -ArgumentList($computers,$i)
#creates a variable with job objects eq to running state
$running = @($jobs | ? {$_.State -eq 'Running'})
While ($running.Count -ge $maxjobs) { #if the count of currently running jobs is ge the set ceiling
$finished = Wait-Job -Job $jobs -Any #use the wait-job cmdlet to pause script execution from creating anymore jobs
$running = @($jobs | ? {$_.State -eq 'Running'}) #once a job finishes this line runs for re-evaluation
}
}
Wait-Job -Job $jobs > $null #this line pauses script execution until all remaing jobs finish, i tested this and it works