What I want to do:
So here is my powershell code:
$excel = New-Object -ComObject Excel.Application
$excel.Workbooks.Open($filepath) | Out-Null
$macro = $excel.ActiveWorkbook.VBProject.VBComponents.Import($MacroFilepath)
$Excel.ActiveWorkbook.Application.Run("HoursSumCounter.main") | Out-Null
$excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro)
(Naturally I enabled accessing the VBA project in the trust center settings of Excel in order to be able to import a module dynamically)
Now the error that I get is the following:
Cannot find an overload for "Remove" and the argument count: "1".
At line:1 char:1
+ $excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
This whole thing actually works if I do this within Excel (no powershell).
But here is what I found out already...
I checked the overload of the Remove function:
[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $excel.ActiveWorkbook.VBProject.VBComponents.Remove
OverloadDefinitions                                                                                                                                                                           
-------------------                                                                                                                                                                           
void Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                                                                                                                                    
void _VBComponents.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                                                                                                                      
void _VBComponents_Old.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent) 
It turned out that I actually should pass an object of type Microsoft.Vbe.Interop.VBComponent VBComponent however my $macro object is of type System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6}
[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $macro | Get-Member
   TypeName: System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6}
Name            MemberType Definition                        
----            ---------- ----------                        
Activate        Method     void Activate ()                  
DesignerWindow  Method     Window DesignerWindow ()          
Export          Method     void Export (string)         
...
...Even though the Remove function actually returns a type of VBComponent, during this OLE automation process it gets converted to a COM object. 
I'm just suspecting that I have to somehow convert this COM object to an actual VBComponent object, how ever I cannot cast it explicitly.
had to do something similar recently, this how i did it.
$Code = @'
your code here
Make sure this guy is public
@'
$Excel = new-object -com Excel.Application
#Need to change security settings
New-ItemProperty -Path `
"HKCU:\Software\Microsoft\Office\$($Excel.Version)\excel\Security" -Name ` 
AccessVBOM -Value 1 -Force | Out-Null
New-ItemProperty -Path `
"HKCU:\Software\Microsoft\Office\$($Excel.Version)\excel\Security" -Name `
VBAWarnings -Value 1 -Force | Out-Null
$Workbook = $Excel.Workbooks.open("Insert Path to file here",$true)
$xlModule = $Workbook.VBProject.VBComponents.Add(1)
$Module = $xlmodule.CodeModule.AddFromString($Code)
$Excel.Run("Name of Module here, make sure that the sub is public")
$Workbook.VBProject.VBComponents.Remove($xlmodule)
$Workbook.Close($True)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With