AmbiguousParameterSet with ForEach-Object -parallel

Contributor

Hello,

 

I have this error when trying to use parallele tasks. Can anybody help on this please?

 

 

 

 

$TimeDuration = [System.Diagnostics.Stopwatch]::StartNew()

[System.Collections.ArrayList]$ArrayWithHeader = @()
$Date = Get-date -Format "yyyy_MM_dd HH-mm"
$ListOldOSesPath = ".\ListOldOSes\$date"
#Check backup folder
if (-Not(Test-Path -Path $ListOldOSesPath)) {New-Item -ItemType Directory $ListOldOSesPath -Force }


$complist = Get-ADComputer -Filter * -Property OperatingSystem,name,enabled,Description,distinguishedname #| Where-Object -Property name -EQ "SRVCOPWDC02P"
$total = $complist.count
$count = 1

#Workflow TestParallel{
$complist | ForEach-Object -parallel{
 #foreach ($comp in $complist){
          $PC = $_.name
          write-host "working on $PC $count/$total"
 
          #write-host "working on $_ "

            $pingtest = Test-Connection -ComputerName $PC -Quiet -Count 1 -ErrorAction SilentlyContinue
            #$Result = [pscustomobject]@{'OS'=$($_.OperatingSystem);'Computer_Name'=$($_.name);'DN'=$($_.distinguishedname);'enabled'=$($_.enabled);'Description'=$($_.Description);'Reacheable'=$($pingtest)}

            $ArrayWithHeader.add([pscustomobject]@{'OS'=$_.OperatingSystem;'Computer_Name'=$_.name;'DN'=$_.distinguishedname;'enabled'=$_.enabled;'Description'=$_.Description;'Reacheable'=$pingtest}) | Out-Null

            #$ArrayWithHeader.add($Result) | Out-Null

            #$Result=$null
            $count += 1
       }
#}

#TestParallel

$ArrayWithHeader | export-csv -path "$ListOldOSesPath\_ListOldOSes.csv" -NoTypeInformation -Append -delimiter ";"
Invoke-Item "$ListOldOSesPath"

#Show script processing time
$TimeElapsed = $TimeDuration.elapsed.ToString('dd\.hh\:mm\:ss')
$TimeDuration.stop
$TimeElapsed

pause

 

 

 

 

 

ForEach-Object : Parameter set cannot be resolved using the specified named parameters.
At XXXXXXXXXXXXXX\ListOldOSes-OtherVersion.ps1:15 char:13
+ $complist | ForEach-Object -parallel{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.ForEachObjectCommand

 

I'm using PS 7.

 

Thank you.

12 Replies
Are you running the script in a PowerShell ISE editor perhaps?

"I ran into this issue when trying to test the script in the Windows Powershell ISE script editor, despite pwsh --version telling me that it was 7.2.0.

As Owain Esau points out in the comments, the error is telling you that the current version of ForEach-Object does not support the -Parallel parameter.

But if you open run your script in a dedicated Powershell 7 window, it should execute just fine."

https://stackoverflow.com/questions/62379047/foreach-object-parallel-parameter-set-cannot-be-resolve...

Thank you !!!

I think it was indeed the answer. I use now Visual Studio and PS7 and this error is gone.
I now have an other issue.
InvalidOperation:
Line |
11 | $ArrayWithHeader.add([pscustomobject]@{'OS'=$_.OperatingS …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.

The concerned line is like this :
$ArrayWithHeader.add([pscustomobject]@{'OS'=$_.OperatingSystem;'Computer_Name'=$_.name;'DN'=$_.distinguishedname;'enabled'=$_.enabled;'Description'=$_.Description;'Reacheable'=$pingtest}) | Out-Null

I was doing something very similar in PS v5 with a foreach ($var in $...) and it was working fine, though very slow.
Also, if I remove the -parallel then it's working again.

And your $complist and $pingtest variables are filled?
Normally $pingtest always is at true or false
[DBG]: PS C:\Users\xxx> $pingtest
True
Regarding $complist it is indeed filled. BUT, sometimes one of the property can be empty sometimes.
[DBG]: PS C:\Users\xxxx> $complist
Description : WS2016 - DC
DistinguishedName : CN=XXX,OU=Domain Controllers,DC=unich,DC=net
DNSHostName : XXX
Enabled : True
Name : XXX
ObjectClass : computer
ObjectGUID : 2b85de89-1886-409c-92e0-1c7a97a6be48
OperatingSystem :
SamAccountName : XXX$
SID : S-1-5-21-1128282684-3729639265-1475195819-26153
UserPrincipalName :

Could that explain the problem ? Again without the -parallel the values of pingtest and the emptiness of properties is still the same, but seems to work.
You could put in a check for the values before adding them to the array. Certain values are always present in AD but things like Description is a free text field. Perhaps something like
if ($Null -eq $_.Description) {$_.Description='Empty'}
I just modified my script to only test on 1 computer. I made sure this computer has all values filled.
Still, without the -parallel it works but with it it fails. Could it be that I can't use $_. with -parralel, from what I saw it should be feasible.

Details :
$complist = Get-ADComputer -Filter * -Property OperatingSystem,name,enabled,Description,distinguishedname | Select-Object OperatingSystem,name,enabled,Description,distinguishedname | Where-Object -Property name -EQ "PCNAME"

F8 on $complist :
[DBG]: PS C:\Users\bodig-adm> $complist

OperatingSystem : Windows Server 2008 R2 Standard
name : PCNAME
enabled : True
Description : UVS - File & Print
distinguishedname : CN=PCNAME,OU=CH - Servers,OU=CH,OU=XXX,DC=XXX,DC=XXX

So the properties have value.

Then foreach-object works but -parrallel fails
8 | $ArrayWithHeader.add([pscustomobject]@{'OS'=$_.OperatingS …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.

I will try to use intermediate variables...
$complist | ForEach-Object {

$PC = $_.name
$OS = $_.OperatingSystem
$DN = $_.distinguishedname
$enable = $_.enabled
$desc = $_.Description
Write-Host "test"
write-host "working on $PC, $OS, $DN, $Enable, $desc, $count/$total"

$pingtest = Test-Connection -ComputerName $PC -Quiet -Count 1 -ErrorAction SilentlyContinue
write-host "$pingtest"
#$ArrayWithHeader.add([pscustomobject]@{'OS'=$_.OperatingSystem;'Computer_Name'=$_.name;'DN'=$_.distinguishedname;'enabled'=$_.enabled;'Description'=$_.Description;'Reacheable'=$pingtest})
$tutu = [pscustomobject]@{'OS'=$OS;'Computer_Name'=$PC;'DN'=$DN;'enabled'=$enable;'Description'=$desc;'Reacheable'=$pingtest}
Write-Host $tutu
$ArrayWithHeader.add($tutu)
$count += 1
}

In both cases my variables are filled, but -parrallel gives an error. I know that in PS5 I had an error when trying to use ArrayWithHeader.add($tutu) (though it was with foreach -parrallel (not foreachobject)

 

Put $using:sheet inside the loop, like with jobs and invoke-command.

https://stackoverflow.com/questions/63502924/error-while-executing-in-powershell7-0-you-cannot-call-...

In your case $using:_.Description I guess for example? Not sure how to format that in this case...

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=pow...

"Parallel running script block. Beginning with PowerShell 7.0, a third parameter set is available that runs each script block in parallel. The ThrottleLimit parameter limits the number of parallel scripts running at a time. As before, use the $_ variable to represent the current input object in the script block. Use the $using: keyword to pass variable references to the running script."

 

Then https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=pow...

I don't think it's gonna work and I don't see how I would use it.
Also, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=pow...
This suggest that my $_. should work.

 

I think I'm lost in translation :D

$using is variable references that you have set before starting the foreach -parallel loop, so that's not going to help.. So yeah, that's not it.. I think I have to experiment with this myself :)
thank you for your help anyway, I'll just let my script run 45mins for now.
No problem and if you do manage to fix it, please report back :)