Полное раскрытие. Моя проблема может быть связана с неполным пониманием модуля Citrix PowerShell для Xen Desktop.
У меня есть следующий блок скриптов.Он вызывается в цикле, один раз для каждой виртуальной машины в списке.Я использую PowerShell Jobs
, поскольку хочу, чтобы поток пользовательского интерфейса оставался свободным для обновления пользовательского интерфейса во время выполнения заданий.
Код "A"
$j = Start-Job -Name $jobName -ScriptBlock {
param($url, $uuid, $cred, $snapshotName)
$ErrorActionPreference = "Stop"
try
{
$error.clear()
$xSS = $cred | Connect-XenServer -url $url -NoWarnCertificates -SetDefaultSession -PassThru;
$vm = (Get-XenVM -SessionOpaqueRef $xss.opaque_ref -uuid $uuid)
#Create snapshot
Invoke-XenVM -Async -SessionOpaqueRef $xss.opaque_ref -VM $vm -XenAction Snapshot -NewName $snapshotName
return "OK"
}
catch
{
return ("ERROR: "+$error)
}
} -ArgumentList $global:configFileVmMetaData.poolUrl, $xenVm.key, $global:cred, $snapshotName
Код "A" работает нормально, но это занимает больше времени, чем необходимо, потому что я выполняю командлет Connect-XenServer
каждый раз, когда вызываю блок скрипта.
Итак, я попытался вызвать Connect-XenServer
после выхода из цикла и передачи переменной сеанса, как показано ниже в Код "B" .В результате была выдана ошибка Could not find open sessions to any XenServers
внутри блока скрипта.Я предполагаю, что переменная сеанса $ xss как-то колеблется, когда она передается в блок скрипта.
Есть идеи, почему переменная $ xss сеанса удаляется?
Код "B "
$xSS = $cred | Connect-XenServer -url $global:configFileVmMetaData.poolUrl -NoWarnCertificates -SetDefaultSession -PassThru;
loop
{
$j = Start-Job -Name $jobName -ScriptBlock {
param($xss, $uuid, $snapshotName)
$ErrorActionPreference = "Stop"
try
{
$error.clear()
$vm = (Get-XenVM -SessionOpaqueRef $xss.opaque_ref -uuid $uuid)
#Create snapshot
Invoke-XenVM -Async -SessionOpaqueRef $xss.opaque_ref -VM $vm -XenAction Snapshot -NewName $snapshotName
return "OK"
}
catch
{
return ("ERROR: "+$error)
}
} -ArgumentList $xss, $xenVm.key, $snapshotName
}
Дополнительные примеры, основанные на ответе Robert Cotterman
Во всех случаях я все еще получаю ошибку Could not find open sessions to any
XenServers
К вашему сведению - Использование PowerShell 5.1
Пример использования $using
.Содержимое переменной передается и возвращается как положено
cls
$aLocal = "AAA"
$bLocal = "BBB"
$j = Start-Job -Name "TestJob" -ScriptBlock {
return ($using:aLocal + " *** " + $using:bLocal)
}
while ($true)
{
$g = get-job -name "TestJob"
write-host ("get-job " + $g.Name + " is " + $g.State)
if ($g.State -ne "Running")
{
break
}
start-sleep -Seconds 1
}
write-host ("receive-Job='" + (receive-Job -Name "TestJob") +"'")
$g = get-Job -Name "TestJob"
Write-Host ("get-Job "+$g.name + " " + $g.state + " " + $g.HasMoreData + " " + $g.id)
if($g)
{
Remove-Job -Name "TestJob"
}
Выход
get-job TestJob is Running
get-job TestJob is Completed
receive-Job='AAA *** BBB'
get-Job TestJob Completed False 45
Remove-Job
Пример с использованием аргументов.Содержимое переменной передается и возвращается как положено
cls
$aLocal = "AAA"
$bLocal = "BBB"
$j = Start-Job -Name "TestJob" -ScriptBlock {
return ($args[0] + " *** " + $args[1])
} -ArgumentList ($aLocal, $bLocal)
while ($true)
{
$g = get-job -name "TestJob"
write-host ("get-job " + $g.Name + " is " + $g.State)
if ($g.State -ne "Running")
{
break
}
start-sleep -Seconds 1
}
write-host ("receive-Job='" + (receive-Job -Name "TestJob") +"'")
$g = get-Job -Name "TestJob"
Write-Host ("get-Job "+$g.name + " " + $g.state + " " + $g.HasMoreData + " " + $g.id)
if($g)
{
Remove-Job -Name "TestJob"
}
Выход
get-job TestJob is Running
get-job TestJob is Completed
receive-Job='AAA *** BBB'
get-Job TestJob Completed False 49
Пример с использованием именованных аргументов.Содержимое переменной передается и возвращается, как и ожидалось
cls
$aLocal = "AAA"
$bLocal = "BBB"
$j = Start-Job -Name "TestJob" -ScriptBlock {
param($a, $b)
return ($a + " *** " + $b)
} -ArgumentList ($aLocal, $bLocal)
while ($true)
{
$g = get-job -name "TestJob"
write-host ("get-job " + $g.Name + " is " + $g.State)
if ($g.State -ne "Running")
{
break
}
start-sleep -Seconds 1
}
write-host ("receive-Job='" + (receive-Job -Name "TestJob") +"'")
$g = get-Job -Name "TestJob"
Write-Host ("get-Job "+$g.name + " " + $g.state + " " + $g.HasMoreData + " " + $g.id)
if($g)
{
Remove-Job -Name "TestJob"
}
Вывод
get-job TestJob is Running
get-job TestJob is Completed
receive-Job='AAA *** BBB'
get-Job TestJob Completed False 55