Hello everyone!
I create script which convert VM to template, then run converted VMs, then Invoke-VMScript. After this my script reboot, shutdown this VMs and convert VMs to templates.
All this operations I run in powershell parallel mode.
But when my script try to run Invoke-VMScript in parallel mode, my script freezes on this operation. I see only - "Inline Script runniung"
But If I open one of VMs, I see command run my local script on VM and it's done.
In VM events I see the same, command Invoke-VMScript done.
How to fix this? What I do wrong?
Thanks in advance!
My script:
function Load-PowerCLI
{
Add-PSSnapin VMware.VimAutomation.Core
Add-PSSnapin VMware.VimAutomation.Vds
}
Load-PowerCLI
# Connect to Vcenter
$vcenter="vcenter.domain.local"
function Connect-Vcenter
{
Connect-VIServer -Server $vcenter
}
Connect-Vcenter
function Unload-PowerCLI
{
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
Remove-PSSnapin VMware.VimAutomation.Vds -ErrorAction SilentlyContinue
}
# Get template List
function Get-FolderFromPath
{
param(
[String] $Path
)
$chunks = $Path.Split('\')
$root = Get-View -VIObject (Get-Folder -Name $chunks[0])
if (-not $?){return}
$chunks[1..$chunks.Count] | % {
$chunk = $_
$child = $root.ChildEntity | ? {$_.Type -eq 'Folder'} | ? { (Get-Folder -id ("{0}-{1}" -f ($_.Type, $_.Value))).Name -eq $chunk}
if ($child -eq $null) { throw "Folder '$chunk' not found"}
$root = Get-View -VIObject (Get-Folder -Id ("{0}-{1}" -f ($child.Type, $child.Value)))
if (-not $?){return}
}
return (Get-Folder -Id ("{0}-{1}" -f ($root.MoRef.Type, $root.MoRef.Value)))
}
$Templateslist=(Get-FolderFromPath -Path 'DC\Templates\Windows' | Get-Template | ? {$_.name -eq 'TEST'}).name
$Templateslist
# Convert Templates to VMs
workflow convert-templates-to-vm {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$user,
[string]$pass
)
foreach -parallel ($template in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Set-Template -Template $Using:template -ToVM
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
convert-templates-to-vm -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret
# PowerOn VMs
workflow poweron-vms {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$user,
[string]$pass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Start-VM -VM $Using:vm | Wait-Tools
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
poweron-vms -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret
# Wait 1 minute
sleep 60s
# Run Update Command Script
workflow run-update {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$script,
[string]$guestuser,
[string]$guestpass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Invoke-VMScript -ScriptText "$Using:script" -VM "$Using:vm" -Server "$Using:vcenter" -GuestUser "$Using:guestuser" -GuestPassword "$Using:guestpass"
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
$script = 'c:\update.ps1'
$guestuser="Administrator"
$guestpass="myPASS"
run-update -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret -script $script -guestuser $guestuser -guestpass $guestpass
# Restart VMs
workflow restart-vms {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$user,
[string]$pass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Restart-VMGuest -VM $Using:vm | Wait-Tools
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
restart-vms -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret
# shutdown VMs
workflow shutdown-vms {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$user,
[string]$pass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Shutdown-VMGuest -VM "$Using:vm" -Confirm:$false
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
shutdown-vms -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret
sleep 120
# Convert VMs to Templates
workflow convert-vm-to-templates {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$user,
[string]$pass
)
foreach -parallel ($template in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Set-VM -VM "$Using:template" -ToTemplate -Confirm:$false
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
convert-vm-to-templates -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret
Unload-PowerCLI
Problem in this part:
workflow run-update {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$script,
[string]$guestuser,
[string]$guestpass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Invoke-VMScript -ScriptText "$Using:script" -VM "$Using:vm" -Server "$Using:vcenter" -GuestUser "$Using:guestuser" -GuestPassword "$Using:guestpass"
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
$script = 'c:\update.ps1'
$guestuser="Administrator"
$guestpass="myPASS"
run-update -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret -script $script -guestuser $guestuser -guestpass $guestpass
I found solution!
I just add this string - $WarningPreference = "SilentlyContinue" in inline script
Like this:
workflow run-update {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$script,
[string]$guestuser,
[string]$guestpass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
$WarningPreference = "SilentlyContinue"
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Invoke-VMScript -ScriptText "$Using:script" -VM "$Using:vm" -Server "$Using:vcenter" -GuestUser "$Using:guestuser" -GuestPassword "$Using:guestpass"
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
$script = 'c:\update.ps1'
$guestuser="Administrator"
$guestpass="myPASS"
run-update -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret -script $script -guestuser $guestuser -guestpass $guestpass
I suspect there is a common component that is used by all invocations of Invoke-VMScript.
And possibly the 1st cmdlet that returns cleans this up, and hence freezes the others.
But that is just a guess, we would need some feedback from the PowerCLI Dev Team.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I found solution!
I just add this string - $WarningPreference = "SilentlyContinue" in inline script
Like this:
workflow run-update {
param(
[string[]]$templates,
[string]$vcenter,
[string]$session,
[string]$script,
[string]$guestuser,
[string]$guestpass
)
foreach -parallel ($vm in $templates)
{
$run = InlineScript{
$WarningPreference = "SilentlyContinue"
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $Using:vcenter -Session $Using:session
Invoke-VMScript -ScriptText "$Using:script" -VM "$Using:vm" -Server "$Using:vcenter" -GuestUser "$Using:guestuser" -GuestPassword "$Using:guestpass"
Remove-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
$run
}
}
$script = 'c:\update.ps1'
$guestuser="Administrator"
$guestpass="myPASS"
run-update -templates $Templateslist -vcenter $vcenter -session $global:DefaultVIServer.SessionSecret -script $script -guestuser $guestuser -guestpass $guestpass
Great find, thanks for sharing.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference