powershellcomobject

How to Close excel ComObject in Powershell Constrained mode


I couldn't find anything online about how to close the ComObject after making it in constrained mode. The normal procedure is to use $com.Quit(), however that is not allowed in constrained mode. Also, [System.Runtime.InteropServices.Marshal]::ReleaseComObject() is not allowed in constrained mode.

It was suggested I pose a new question by mklement0 in the following thread: Can't get all excel processes to stop when closing through Powershell


Solution

  • Let me offers a more PowerShell-idiomatic solution that should also perform better:

    # Capture the PIDs (process IDs) of all *preexisting* Excel processes
    # In PowerShell 7+, you can simplify to (see bottom section for a discussion):
    #    $exelPidsBefore = (Get-Process -ErrorAction Ignore Excel).Id ?? @()
    $excelPidsBefore = @(
      Get-Process -ErrorAction Ignore Excel | Select-Object -ExpandProperty Id
    )
    
    # Perform the desired programmatic Excel operations:
    
    # Create an Excel COM Automation object, which
    # invariably creates a *new* Excel process.
    $excel = New-Object -ComObject Excel.Application
    
    # Determine the PID of the just-launched new Excel process.
    # Note: This assumes that no *other* processes on your system have 
    #       simultaneously launched Excel processes (which seems unlikely).
    $excelComPid = 
      Compare-Object -PassThru $excelPidsBefore (Get-Process -ErrorAction Ignore Excel).Id
    
    # Work with the Excel Automation object.
    # ...
    
    # Clean up by terminating the COM-created Excel process.
    # NOTE: 
    #  * As stated in your question, you would normally use $excel.Quit()
    #    but given that your running in *constrained language mode*, you
    #    are not permitted to invoke *methods*.
    Stop-Process -Id $excelComPid
    

    As an - entirely optional - aside: