简体   繁体   中英

Powershell Runspace - New-Object not recognized

Given the following...

  1. Powershell script that implements a runspace pool
  2. A HashTable of named scriptblocks
  3. Scriptblocks that call New-Object to create SQL related objects (SMO, SqlClient, etc)

My script iterates through a list of servers and adds every scriptblock and their parameters from the hashtable to the runspace pool. Some of the scriptblocks call New-Object to instantiate instances of various .net objects.

Code is something like this (updated to more accurately reflect the problem)...

# add, configure and execute runspace script block
$_ps                = [Powershell]::Create()
$_ps.RunspacePool   = $this._pool

$_script_block = {
   $_obj = New-Object Microsoft.SqlServer.Management.Smo.Server($InstanceName) 
}

$_wrapper_script_block = { &$_script_block }  # returns cmdlet not found error
$_wrapper_script_block = { Invoke-Command -ScriptBlock $_script_block } # works

$null = $_ps.AddScript($_wrapper_script_block)
$null = $_ps.AddParameters($Parms)

# syntax may be off - just for demonstration
[ArrayList] $jobs += @{process = $_ps; handle = $_ps.BeginInvoke()}

Problem...

Scriptblocks return "New-Object is not recognized..." error when multiple runspaces are in the pool. If I use the exact same code but submit only one scriptblock containing a New-Object call (same scriptblock fails with multiple runspaces) to the runspace pool, it works fine.

Microsoft's documentation ( https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7 ) says "The call operator does not parse strings. This means that you cannot use command parameters within a string when you use the call operator." I changed from & to Invoke-Command and it seems to be working fine now. I'm not entirely sure what is happening.

I think I found my problem.

According to https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7 , "The call operator does not parse strings. This means that you cannot use command parameters within a string when you use the call operator". The example they give describes the behavior in my script.

In short, one cannot use cmdlet parameters in script blocks invoked with the & operator. For example, something like &"get-command -Verb 'get'" will throw an error indicating get-command cannot be found.

I apologize for not including it in my code example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM