Question:
Trying to string the title together was enough of a challenge…
I am trying to run some PowerPoint macros from PowerShell. I have gotten quite good at running macros from Powershell for Excel. When I run the macros on Excel, the Run() method from the COM object will take a variety of arguments, depending if the macro has any parameters. However on the other hand, the PowerPoint Run() method expects parameters, and I cannot work out how to pass them.
My macro is expecting one string to be passed through, I’ve googled profusely and come up short. I always get this error:
Error:
1 2 |
type must not be ByRef |
I have put together a very basic PoC for PowerPoint in PowerShell:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# PowerPoint test Add-type -AssemblyName office $PowerPoint = New-Object -comobject PowerPoint.Application $PowerPoint.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue $presentation2 = $PowerPoint.Presentations.open("C:\macros.pptm") $presentation = $PowerPoint.Presentations.open("C:\Test For Macros.pptx") $PowerPoint.run("macros.pptm!IAM",[ref]"Feb") $presentation.save() $presentation.close() $presentation2.close() $PowerPoint.quit() # extra clean up omitted |
The macro itself just moves some text across boxes, it works fine when run from PowerPoint.
Requirement:
I now want to automate this across multiple files and slides.
Documentation on the PowerPoint COM object Run method, showing the requirement for two parameters.
Answer:
Great question and not a lot of examples online as you say. I managed to strip your example down even further and successfully pass some text to a MsgBox in a PowerPoint Macro without really changing what you had.
The Macro in the file PowerShellTest.pptm saved in C:\Temp
1 2 3 4 |
Sub DisplayMessage(myText As String) MsgBox myText End Sub |
The PowerShell script:
1 2 3 4 5 6 7 8 9 10 |
# PowerPoint test Add-type -AssemblyName office $PowerPoint = New-Object -comobject PowerPoint.Application $PowerPoint.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue $presentation = $PowerPoint.Presentations.open("C:\Temp\PowerShellTest.pptm") $PowerPoint.run("PowerShellTest.pptm!DisplayMessage",[ref]"Feb") |
The Run method documentation link you provided mentions that the module name may be included so this worked for me too:
1 2 |
$PowerPoint.run("PowerShellTest.pptm!Module1.DisplayMessage",[ref]"Feb") |