windowspowershellpowershell-7.4

Can't pass scriptblock into foreach-object invoke-command loop


I am trying to create a function for sending a command to all computers on a .txt file list($complist) .

This is what I have:

write-host "enter your administrative credentials" -foregroundcolor blue;

$credential = get-credential ''

$s = read-host "enter your cmd script here"

$complist = Get-Content "C:\PowershellCMDs\Temp\searchresults.txt"

$complist | foreach-object -parallel {icm -cn $_ -credential $using: credential -scriptblock {$s}} -throttlelimit 16

write-host "Task Complete" -backgroundcolor green**

This just continues on without errors but doesn't run. When adding $using:s it generates errors.

When imputing the desired script(using sfc /scannow as my example) directly into the scriptblock it runs perfectly.

For some reason I can't pass the $s parameter into a foreach-object -scriptblock.

After I can do this, I will be trying to create jobs to track progress of each command.


Solution

  • The output from Read-Host is always a string, if you want to create a scriptblock from it you should use ScriptBlock.Create, e.g.:

    $credential = Get-Credential ''
    $s = Read-Host 'enter your cmd script here'
    $complist = Get-Content 'C:\PowershellCMDs\Temp\searchresults.txt'
    
    $complist | ForEach-Object -Parallel {
        $invokeCommandSplat = @{
            ComputerName = $_
            Credential   = $using:credential
            ScriptBlock  = [scriptblock]::Create($using:s)
        }
    
        Invoke-Command @invokeCommandSplat
    } -ThrottleLimit 16
    

    Something you should note, Invoke-Command is already capable of parallelizing the work, you don't really need ForEach-Object -Parallel in this case:

    $credential = Get-Credential ''
    $s = Read-Host 'enter your cmd script here'
    $complist = Get-Content 'C:\PowershellCMDs\Temp\searchresults.txt'
    
    $invokeCommandSplat = @{
        ComputerName  = $complist
        Credential    = $credential
        ScriptBlock   = [scriptblock]::Create($s)
        ThrottleLimit = 16
    }
    
    Invoke-Command @invokeCommandSplat