plaman
Enthusiast
Enthusiast

run powercli function as job

I have multi vCenters I need to run yum update to all Linux servers, on all sites, so I have written an update function

I need to run that inside a job script, and return the result, the job is stuck at running

 

function Update-VM {

 

   [CmdletBinding()]

   Param(

       [Parameter(Mandatory = $true, ValueFromPipeline = $true)]

        $vm

   )

 

   Import-Module VMware.VimAutomation.Core

   # Take a snapshot of the virtual machine

   Write-Host "Taking a Sbapshot For $vm..." -ForegroundColor Green

  

   $snapshot = New-Snapshot -VM $vm -Name $snapshotName -Description "Snapshot taken before update" -Confirm:$false

  

   # Update the virtual machine using yum

   $updateCommand = " yum update -y"

   $Push=(Invoke-VMScript -VM $vm -GuestCredential $LinCredentials -ScriptText $updateCommand -ScriptType Bash).ScriptOutput

   # Restart the virtual machine

   Restart-VMGuest -VM $vm -Confirm:$false

 Write-Host "passed 3"

   # Wait for VMware Tools to start

 

  

   do {

         $CheckPower=Check-Connection -IP $Ip -vmname $vm -vCentre $vCentre -ConnectionRequest "STARTINGUP"                                                                          

         $PingStatus    =$CheckPower[0]

         $VMPowerStatus =$CheckPower[1]

  

   } until ($PingStatus -eq "Reachable")

 

   # Check if the virtual machine is running

   if ((Get-VM -Name $vm).PowerState -eq "PoweredOn") {

       # Create a test directory on the virtual machine

       $testDir = "/etc/checkarcher"

       $testCommand = "mkdir $testDir"

       Invoke-VMScript -VM $vm -GuestCredential $LinCredentials -ScriptText $testCommand -ScriptType Bash

 

       # Check if the test directory exists

       $testDirExists = Invoke-VMScript -VM $vm -GuestCredential $LinCredentials -ScriptText " ls -d $testDir >/dev/null 2>&1 && echo ""Directory exists"" || echo ""Directory does not exist"""  -ScriptType Bash | Select-Object -ExpandProperty ScriptOutput

 

        $testDirExists= $testDirExists.Trim()

       # Remove the test directory if it exists

       if ($testDirExists -eq "Directory exists") {

           $removeCommand = "rm -r $testDir"

           Invoke-VMScript -VM $vm -GuestCredential $LinCredentials -ScriptText $removeCommand -Server  $vCentre -ScriptType Bash

           Write-Host "Virtual machine $($vm) successfully updated and restarted."

       } else {

           Write-Warning "Virtual machine $($vm) failed to start after update."

       }

   } else {

       Write-Warning "Virtual machine $($vm) failed to restart after update."

   }

 

}

Reply
0 Kudos
LucD
Leadership
Leadership

How do you start the jobs?
And how do you pass that function in the jobs?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
plaman
Enthusiast
Enthusiast

 

 Start-Job -Name $vm.Name -Argument List $vm.Name -Script Block ${function: Update-VM}
 

Reply
0 Kudos
LucD
Leadership
Leadership

Why do you have those blanks in -ArgumentList and function:Update-VM?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership

Also, if the $vm variable is not defined inside your Start-Job script, you will have to use the using: qualifier.
The Start-Job creates a new PS environment, your current local variables are not known in that environment.

Start-Job -Name $vm.Name -ArgumentList $using:vm.Name -ScriptBlock ${function: Update-VM}

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
plaman
Enthusiast
Enthusiast

this is the loop where call the vm and pass the the info to the Job,  i ca not see where it is passing blank, 

$jobs = @()

foreach ($vmName in $vmNames) {

Write-Host " Processing $vmName Vm...." -ForegroundColor Green

$vm = Get-VM -Name $vmName -server $vCentre

$job = Start-Job -Name $vm.Name -ArgumentList $vm.Name -ScriptBlock ${function:Update-VM}

$jobs += $job

}

 

Reply
0 Kudos
plaman
Enthusiast
Enthusiast

is there anyway where avoid adding Connect-VIServer $vCentre in the function ? use a $Globale one 

Reply
0 Kudos
LucD
Leadership
Leadership

No, you can use the Session parameter to connect to an existing session in the Start-Job codeblock.
See for example Solved: Re: Pass vCenter connection to a Job - VMware Technology Network VMTN


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
plaman
Enthusiast
Enthusiast

Using the using: qualifier worked thank you, my challenge now I  need to return more that one item in an object 

 

$UpdateHistory=@"
yum updateinfo list
"@

Invoke-VMScript -VM $Using:VMName -GuestCredential $Using:LinCredentials -ScriptText $UpdateHistory -ScriptType Bash).ScriptOutput

Reply
0 Kudos
LucD
Leadership
Leadership

I often format the output (in the function) as a CSV file.
When the function returns I then convert the text (ScriptOutput) with ConvertFrom-Csv

See for example Re: Invoke-VMscript (Network) - VMware Technology Network VMTN


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos