I have a scheduled task that runs a Powershell script. This Powershell script sends a HTTP request and searches through the returned HTML. As a result of this script, I am left with a bunch of dllhost processes that don't close. If I understand right, this is a result of COM objects.
The only variable related to COM objects is this:
$specifiedDiv = $request.ParsedHtml.Body.getElementsByTagName('div') |
Where-Object{$_.getAttributeNode('class').Value -eq 'results'}
When I run $specifiedDiv.GetType()
, I get this as the result:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False __ComObject System.MarshalByRefObject
My question is how can I close this object or prevent the script from creating the dllhost processes?
Edit:
Function garbageCollect ([object]$ref){
([System.Runtime.Interopservices.Marshal]::ReleaseComObject([System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
$parsedHtml = $request.ParsedHtml
$body = $parsedHtml.Body
$divs = $body.getElementsByTagName('div')
$classAttribute = $divs | Where-Object{$_.getAttributeNode('class').Value -eq 'results-found'}
Remove-Variable -Name classAttribute
Remove-Variable -Name parsedHtml
Remove-Variable -Name body
Remove-Variable -Name divs
garbageCollect($parsedHtml)
garbageCollect($body)
foreach($div in $divs)
{
garbageCollect($div)
}
foreach($thing in $classAttribute)
{
garbageCollect($div)
}
I tried the above but I still get the dllhost process.
Well, it's more complicated than that. There is
[System.Runtime.InteropServices.Marshal]::ReleaseComobject($specifiedDiv)
That might work... however, the way .NET works with COM objects, you might have a bunch of intermediate COM objects getting created all over the place. Such as $request, $request.ParsedHtml, $request.ParsedHtml.Body. Then there might be a whole bunch of other COM objects created in calls to $_.getAttributeNode('class').