Search code examples
powershellworkflow

Unable to pass variable to Invoke-command


This is my first time using the workflow, could anyone explain me what is wrong with the code ?

Powershell version is 5.1

$Script = {
    return(Get-Service WINRM).Status
}

workflow pushupdate{
##Select OUs
$OUs=
"OU=Workstations,DC=contoso,DC=com",
"OU=Notebooks,DC=contoso,DC=com"

        foreach -parallel ($computer in ($Ous | foreach { Get-ADComputer -Filter {enabled -eq $true} -SearchBase $_} | Select Name)) {
        if ((Test-Connection $computer.name -Quiet) -eq "True") {
            Write-Output "Running update on:" $computer.name

            InlineScript {
                Invoke-Command -ComputerName $computer.name -Script $Script -Verbose
                }
            }
        else{
            Write-Output $computer.name "unreachable!"
        }
    }
}

pushupdate

I keep getting the error:

Invoke-Command : Cannot validate argument on parameter 'ScriptBlock'. The argument is null. Provide a valid value for the argument, and then try running the command again. At pushupdate:245 char:245


Solution

  • Variables defined outside the InlineScript block are unknown to the Invoke-Command cmdlet unless you use them as $using:<varname>. It seems however that you cannot do that with a variable which is actually a scriptblock. That needs to be defined inside the InlineScript itself:

    workflow pushupdate{
        # Select OUs
        $OUs = "OU=Workstations,DC=contoso,DC=com", "OU=Notebooks,DC=contoso,DC=com"
        # get a string array of computerNames
        $computers = ( $Ous | ForEach-Object { Get-ADComputer -Filter "Enabled -eq 'True'" -SearchBase $_ } ).Name
    
        foreach -parallel ($computer in $computers) {
            if (Test-Connection -ComputerName $computer -Quiet -Count 1) {
                Write-Output "Running update on:" $computer
                InlineScript {
                    # define the scriptblock here
                    $script = {(Get-Service WINRM).Status}
                    Invoke-Command -ComputerName $using:computer -ScriptBlock $Script -Verbose
                }
            }
            else{
                Write-Output "$computer unreachable!"
            }
        }
    }
    
    pushupdate