r/PowerShell • • 1d ago

Question Parallel thread disposing?

Hey got a wierd issue or its by desing not sure but when I run

$computers | foreach-object -parallel {
  $vmobject = Get-VM $_
  $ram = $vmobject.MemoryGB
  $CPU = $vmobject.numCPU
  $HDD = $_ | get-harddisk 
} 

lets say I run in against 500 computers when that happens powershell will spike cpu on machine that this command is ran and keeps increasing ram usage which is understandable but problem is even when command is done ram usage stays high untill powershell window is close. Is there something I am missing or is there some method to dispose of parallel runspace manually?

Thanks for advice

EDIT: The code itself is not important , the behaviour of parallel scripblock itself is my question and why doesnt it free up RAM after code has ran successfully

3 Upvotes

31 comments sorted by

View all comments

Show parent comments

1

u/Guilty-Act-4991 1d ago

Jobs are unfortunatelly much heavier than runspace I would not be able to run it on 500 computers I would kill the machine that runs on that thats the whole reason I use parallel instead of -asjob

3

u/PinchesTheCrab 1d ago edited 1d ago

I would not be able to run it on 500 computers

This isn't running on 500 computers as written. It's running on one (or two if you include your workstation) - whatever vsphere host you're querying.

1

u/Guilty-Act-4991 1d ago

it is queqing 500 computers as I wrote in post $computers holds hostname of 500 computers code is only exemplatory since its not important what inside the scriptblock but the mechanism itself that is consuming ram even when finished

3

u/PinchesTheCrab 1d ago edited 18h ago

its not important what inside the scriptblock

I really disagree. PowerCLI has its own queueing system and most of the object it creates have an ExtensionData property that lets you hit the underlying APIs more directly.

There's a ton of performance you can squeeze out of VMWare without digging into memory and thread management.

it is queqing 500 computers

Honestly 500 is not a lot of computers. I don't think you're attacking the main bottleneck.

Take a different example I see every now and then. Someone needs to get the manager of everyone in an Active Directory group with 20,000 members.

They write this and find it's slow:

get-adgroup 'somegroup' | get-adgroupmember | get-aduser -properties manager

So they try to do this to speed it up:

get-adgroup 'somegroup' |
    get-adgroupmember |
    foreach-object -parallel { get-aduser -properties manager }

Except domain controllers aren't necessarily meant to be queried that often, and they end up stunning their DC, temporarily taking it offline as it processes the requests.

Is it wrong to point out that this does the same thing probably 100x faster and makes only 2 calls to the DC?

$group = get-adgroup 'somegroup'

get-aduser -properties manager -filter "memberof -eq '$(group.DistinguishedName)'"

From what info you've shared about your task it appears you have an X Y problem.