Foreach-Object -Parallel doesn't recognize available commands when imported using the WindowsCompatibility module. This likely has to do with how those commands are imported using local remoting, but I haven't dug into the -Parallel implementation yet to see where the failure is.
# Import a windows module, doesn't matter which one. Here I'm importing WMI commands
Import-WinModule Microsoft.Powershell.Management -Force
# Can validate that commands imported with 'Get-Command Get-WMIObject'
Get-Command Get-WMIObject
CommandType Name Version Source
----------- ---- ------- ------
Function Get-WmiObject 1.0 Microsoft.PowerShell.Management.WinModule
# Set a variable to iterate through
$service = 'W32Time','WManSvc','PlugPlay'
# Attempt to use new -Parallel flag
$service | ForEach-Object -Parallel {Get-WmiObject -Class win32_service -Filter ("Name = '{0}'" -f $_)}
# Output error (repeated 3 times)
Get-WmiObject : The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-WmiObject -Class win32_service -Filter ("Name = '{0}'" -f $_)
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WmiObject:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
# Should work like it does with the -Process flag:
$service | ForEach-Object -Process {Get-WmiObject -Class win32_service -Filter ("Name = '{0}'" -f $_)}
ExitCode : 0
Name : W32Time
ProcessId : 1736
StartMode : Manual
State : Running
Status : OK
ExitCode : 1077
Name : WManSvc
ProcessId : 0
StartMode : Manual
State : Stopped
Status : OK
ExitCode : 0
Name : PlugPlay
ProcessId : 1036
StartMode : Manual
State : Running
Status : OK
# Returns an error stating the command doesn't exist-
Get-WmiObject : The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-WmiObject -Class win32_service -Filter ("Name = '{0}'" -f $_)
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WmiObject:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Name Value
---- -----
PSVersion 7.0.0-preview.3
PSEdition Core
GitCommitId 7.0.0-preview.3
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
ForEach-Object -Parallel is akin to using Start-Job to run the commands - it's run in a totally separate process. You'll need to run the import command _inside_ the -Parallel scriptblock; the module being available in the parent session is not sufficient for -Parallel 馃檪
/cc @PaulHigin for information.
Perhaps we could add this in the cmdlet docs..
@iSazonov Thanks, yes I agree this needs to be documented. We can also think about adding common initialization for the parallel script blocks including module import. I actually thought about adding it but decided it was something we could add later as needed.
BTW I will publish a blog article soon on this feature, and will use some of the information for cmdlet documentation.
This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.
Most helpful comment
ForEach-Object -Parallelis akin to usingStart-Jobto run the commands - it's run in a totally separate process. You'll need to run the import command _inside_ the-Parallelscriptblock; the module being available in the parent session is not sufficient for-Parallel馃檪