Search code examples
powershelljobsscriptblock

Remote variable


I am having an issue with passing variables to a remote powershell session and I've searched everywhere on the internet I can think of so I'm hoping someone out there can help. I have a function calling a job which is telling it to start a scriptblock

What I'm trying to do is write a script to allow me to failover clusters from one VM. It works fine if everything is hardcoded but that means I have to change the script for every failover and that just won't save me anytime at all.

$Computer = Server1
$Clustergrp = Cluster1


function FAILOVER(){
$job = Start-Job -scriptblock $JobScript
do {[System.Windows.Form.Application]::DoEvent() } until ($Job.State -eq "Completed")


$JobScript = 
{
Invoke-Command -ComputerName $using:Computer -ScriptBlock {Move-ClusterGroup -Name $using:Clustergrp}
}

What am I missing here? Help please!

I've tried using arguments and $using:variable but nothing seems to work. Yet if I hardcode everything in the scriptblock it works everytime.

I've also tried just using -ComputerName $Computer -ScriptBlock{.....} but that didn't work either.


Solution

  • General points:

    • Invoke-Command has an -AsJob parameter, so there's no need for creating a job with Start-Job first.

    • To wait for a job's completion, use the Wait-Job cmdlet.

    • If you want to wait right away, i.e. if you want synchronous execution to begin with, simply omit -AsJob.

      • Note that Invoke-Command's -ComputerName parameter accepts an array of computer names that are then targeted in parallel.

    As for what you tried:

    You're nesting two out-of-runspace (out-of-process) scopes, which also requires nesting the use of the $using: scope:

    $Computer = 'Server1'
    $Clustergrp = 'Cluster1'
    
    $JobScript = {
      # Create a *local* variable from the caller's
      # $Clustergrp value, so it can again be referenced with
      # $using: in the remotely executing Invoke-Command script block.
      $Clustergrp = $using:Clustergrp
      Invoke-Command -ComputerName $using:Computer -ScriptBlock { 
        Move-ClusterGroup -Name $using:Clustergrp
      }
    }
    
    function FAILOVER {
      $job = Start-Job -ScriptBlock $JobScript
      $job | Wait-Job
    }