Você não precisa expandir a variável passada para o job em segundo plano; você só precisa armazená-lo em uma matriz ou hashtable para referência subseqüente.
Brinquei com o seu exemplo simplificado e descobri que variáveis locais podem não se expandir em um bloco de script Start-Job
- a menos que o modificador Using
seja utilizado (veja Get-Help about_Remote_Variables
- mesmo para trabalhos que serão executados no computador local). Para ilustrar, o exemplo a seguir cria quatro tarefas em segundo plano sem Using
e mais quatro com Using
.
$JobArray = @()
foreach ( $n in 1..4 ) {
$JobName = $n.ToString()
Write-Host ("Starting job " + $JobName + "...")
$JobArray += Start-Job -Name $JobName -ScriptBlock { Write-Host ("Background job " + $JobName) }
}
foreach ( $n in 5..8 ) {
$JobName = $n.ToString()
Write-Host ("Starting job " + $JobName + "...")
$JobArray += Start-Job -Name $JobName -ScriptBlock { Write-Host ("Background job " + $Using:JobName) }
}
Write-Host ("'nWaiting for all jobs to complete...")
Start-Sleep -Seconds 2
$InProgress = $false
do {
$InProgress = $false
foreach ( $Job in $JobArray ) {
if ($Job.JobStateInfo.State -eq "Running") {
$InProgress = $true
Start-Sleep -Seconds 1
}
}
} while ($InProgress -eq $true)
foreach ( $Job in $JobArray ) {
Write-Host ("'nJob Name: " + $Job.Name + " Job ID: " + $Job.ID + " State: " + $Job.JobStateInfo.state + " Results on next line...")
Receive-Job -Job $Job -Keep
}
Write-Host ("'nComplete. To remove expired jobs run:'n Remove-Job -State Completed")
O exemplo acima, armazena cada trabalho em uma matriz, assim o trabalho nº 4 pode ser acessado como $ JobArray [4]. Além disso, cada trabalho é nomeado de acordo com o número do trabalho (o foreach
contador do iterador $n
, não o ID do trabalho atribuído pelo PowerShell, que pode variar). Isso permite o acesso a um trabalho específico pelo número / nome que você atribuiu a ele.
Uma abordagem semelhante pode ser aplicável ao cenário de snapshot da sua VM. O seguinte é UNTESTED e não deve ser tentado em produção até ser verificado em um ambiente de teste:
$VmArray = @(get-vm | Where-Object -FilterScript { $_.Name -match "TRU-JDF-CMTEST[1-5]"})
ForEach ($vm in $VmArray) {
$vmname = $vm.Name
$snapshot = Get-VMSnapshot -VMName $vmname
$snapshotname = $snapshot.Name
Start-Job -Name ($vmname + "-" + $snapshotname) -ScriptBlock { Remove-VMSnapshot -VM $Using:vmname -Name $Using:snapshotname }
}
Ao dividir as coisas em blocos de código de várias linhas, você tem mais oportunidade de atribuir variáveis locais intermediárias. Eu não preservei o trabalho retornado por Start-Job
em uma matriz, como fiz no meu primeiro exemplo, mas você poderia fazer isso se desejar. Você também pode armazenar cada trabalho em um hashtable, em vez de em um array. No hashtable, a chave pode ser o nome do trabalho que você atribuiu e o valor pode ser o próprio objeto de trabalho.