No output when using multiple COM-object requests within PowerShell
When trying to get information from a webpage, the invoke-webrequest isn’t always sufficient. Especially when the webpage uses Ajax or other fancy javascript frameworks. If this is the case, you most likely will be using a .NET com object to get the requested information of a webpage. With such a com object you can open and control an internet explorer window. Using com objects can be a little bit long-winded, but it works and sometimes you do not have any other option. In PowerShell you can start a new internet explorer object like – $ie = new-object -ComObject "InternetExplorer.Application".
As I was making a script to get the status of the environment and as there are many different systems, eventually I ran into systems that couldn’t be queried using the REST API or an Invoke-webrequest. So I used the internetexplorer.application object to get the information needed and everything seemed to work fine. But after putting the scripts (all com objects) together in one script, suddenly the second use of the com object came up empty. This was very strange because separately the scripts ran fine. To make the problem even stranger, when the script was run in an elevated prompt or in PowerShell ISE, there was no problem.
Initially I thought about permissions as the elevated PowerShell did work, but what permissions? And secondly, how can I make this work with as little configuration changes as needed? I wanted to share the script with my co-workers and I didn’t want them to have to do all sorts of additional actions before they had a working script. This script has to work out of-the-box.
After some investigation I came across something called the COM threading model. In this model the execution context of the initialized COM objects is associated with either a single thread (Single Thread Apartment) or many threads (Multi Thread Apartment). Apparently PowerShell’s STA/MTA default setting changed between PowerShell v2.0 and v3.0 and now MTA is the standard threading model for PowerShell. While this is a good thing, in this case I needed the STA model because when multiple treads are started the COM object can’t synchronize over multiple threads resulting in only the first thread to work.
Knowing about this threading model, the solution to my problem was fairly simple. I had to start PowerShell in STA mode, which would result in processing all the com object requests. There are different ways to start PowerShell in STA mode, but as I wanted to keep it simple I created a new PowerShell script with a one-liner that starts a new PowerShell process in STA mode and runs the actual script in that process. The one-liner looks something like this:
powershell.exe -sta -file D:\Scripts\ActualScript.ps1

Started his working life as a system manager at a health care organization. Is now a dedicated technical consultant at PepperByte. Specialist in virtualization and security.
Core qualities
Eager to learn, punctual, fun, loyal, patient
Hobbies
Socializing, watching television series and sports
Job description
Technical Consultant
Leave a Reply
Want to join the discussion?Feel free to contribute!