0

Please help to get Invoke-Command working. It says -ScriptBlock parameter is null. It seems RegHomePage() function is not available in InlineScript{}.

function RegHomePage (){
get-item -path Registry::"HKEY_USERS\*\Software\Microsoft\Internet Explorer\Main" | `
Get-ItemProperty | Where-Object {$_."Start Page" -ne $null} | Set-ItemProperty -Name "Start Page" -Value "about:blank"
}

$creds = Get-Credential -Credential value\wadmin
workflow foreachtest
{
    param([Parameter(mandatory=$true)][string[]]$computers)

    foreach -parallel -throttlelimit 20 ($computer in $computers)
    {
        sequence
        {
            $isPing = Test-Connection -count 1 $computer -quiet
            if($isPing){                
                $isWSMan  = [bool](Test-WSMan $computer -ErrorAction SilentlyContinue)
            }
            if($isWSMan){
                InlineScript{
                    Invoke-Command -ComputerName $USING:computer -ScriptBlock ${function:RegHomePage}
                    } -PSComputerName $computer
                echo "$computer OK"
            }
            Else{
                $Workflow:out += "$computer`r`n"
                echo "$computer FAILED"
            }       

        }

    }
    Out-File .\offline.txt -InputObject $out
}

foreachtest -computers (Get-Content .\comps.txt)

2 Answers 2

1

Seems to have a few issues with this inlineScript block.

  • Dont provide the PSComputerName parameter since you are already running a job on each computer. There is no need to reference other systems here.
  • I would suggest using Write-Output instead of echo (use powershell native commands)
  • Move the function within the inlinescript to bring it in scope of each iteration.
workflow testing {
    foreach -parallel ($computer in $computers) {
        sequence {
            inlinescript {
                function RegHomePage {
                    Get-Item -path Registry::"HKEY_USERS\*\Software\Microsoft\Internet Explorer\Main" | `
                    Get-ItemProperty | Where-Object {$_."Start Page" -ne $null} | Set-ItemProperty -Name "Start Page" -Value "about:blank"
                }
                Invoke-Command -ComputerName $using:computer -ScriptBlock ${Function:RegHomePage}
            }
        }
    }
}

Following is what I tested with.

workflow testingWF {
    Param ([string[]] $computers)

    foreach -parallel ($computer in $computers) {
        sequence {
            InlineScript {
                function testFunc {
                  Param($comp)
                  Write-Output "$($comp.split('.')[0]) == TestFunc"
                }

                Invoke-Command -ComputerName $Using:computer -ScriptBlock ${Function:testFunc} -ArgumentList $using:computer

            }
        }
    }
}

testingWF serverFQDN1,serverFQDN2

#Prints
server1 == TestFunc
server2 == TestFunc

Suggestion on how to re-write the above code

Instead of using a workflow to run a parallel foreach loop, i would recommend replacing the functionality with -AsJob.

foreach($computer in $computers) {
    Invoke-Command -ComputerName $computer -ScriptBlock ${Function:RegHomePage} -AsJob
}

# Remove Jobs when done
Get-Job | Wait-Job | Remove-Job
Sign up to request clarification or add additional context in comments.

2 Comments

I've tried to remove $ and function word but the script returns the error: The term 'RegHomePage' is not recognized as the name of a cmdlet, function, script file.
@user2978216 see updated answer above along with Suggestion on how to run async jobs.
1

InlineScript dont support $using:function , try nested workflow nested work You can move your function inside InlineScript block . Are you sure that key -PSComputerName must have value $Computers instead $computer

Adding

Only one way to call function at inlinescriptblock, it's a put it inside. But may you can use nested workflow to call few times invoke comand. Example nested:

workflow Test-Workflow { 
function mess{"get ready"} 
   workflow nest-test{  
   mess 
   } 
nest-test 
} 
Test-Workflow

You can also read why you can't use import it to inline script in this tutorial: tutorial

1 Comment

Yes, it must be $computer. Sure I can move function into -ScriptBlock{}. If you can give me an example of how to use remote nested work instead of InlineScript that would be great.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.