Hey, Scripting Guy! Can I Add a New Slide to an Existing Microsoft PowerPoint Presentation?

Hey, Scripting Guy! Can I Add a New Slide to an Existing Microsoft PowerPoint Presentation?

  • Comments 1
  • Likes

Bookmark and Share

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have been enjoying reading your Microsoft PowerPoint articles this week. I am curious however; can you use Windows PowerShell to add a slide to an existing presentation? I have searched on the Internet and can’t find an example of doing that. Is it not possible, or just too tough?

-- YF

 

Hey, Scripting Guy! AnswerHello YF,

Microsoft Scripting Guy Ed Wilson here. I am listening to Stevie Ray Vaughan on my Zune HD, and sipping a cup of Lady Grey tea this afternoon. Lady Grey tea is similar to Earl Grey tea, but it is more subtle. I like to sip it after I have my afternoon snack. I have been enjoying reading through the Microsoft PowerPoint object model documentation on MSDN this week. I have been surprised at how rich it actually is. It is also beginning to make sense to me after having spent the week poring over the documentation.

YF, I decided to write a script to add a slide to an existing Microsoft PowerPoint presentation. In fact, it will add the same slide to all of the Microsoft PowerPoint presentations in a specified folder. This could be rather useful in certain circumstances. For example, when I gave my presentation on Windows PowerShell at Tech·Ed 2009 in Los Angeles last year, there were several slides that each presentation was required to incorporate. Rather than relying on the speakers to add these slides, the slides could have been added via script.

The complete AddPowerPointSlide.ps1 script is shown here.

AddPowerPointSlide.ps1

Add-type -AssemblyName office
$Application = New-Object -ComObject powerpoint.application
$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
$slideType = "microsoft.office.interop.powerpoint.ppSlideLayout" -as [type]
$path = "c:\fso"
Get-ChildItem -Path $path -Include "*.ppt", "*.pptx" -Recurse |
ForEach-Object {
 $presentation = $application.Presentations.open($_.fullname)
 $customLayout = $presentation.Slides.item(2).customLayout
 $slide = $presentation.slides.addSlide(2,$customLayout)
 $slide.layout = $slideType::ppLayoutTitleOnly
 $slide.Shapes.title.TextFrame.TextRange.Text = "New Title Text"
 $presentation.Save()
 $presentation.Close()
 "Modifying $_.FullName"
}

$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()

The first thing that must be done is to add the office assembly, create the PowerPoint application object, and make the application visible. This was discussed in Monday’s Hey, Scripting Guy! post. The code that does this is shown here:

Add-type -AssemblyName office
$Application = New-Object -ComObject powerpoint.application
$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue

To configure the slide layout, you will need to use an instance of the ppSlideLayout enumeration. The  PpSlideLayout enumeration is documented on MSDN, and contains all of the different slide layout styles that are available from within Microsoft PowerPoint. One thing to keep in mind is that all layout styles will not be available for all slide themes and templates. The code that creates the slide layout enumeration is shown here:

$slideType = "microsoft.office.interop.powerpoint.ppSlideLayout" -as [type]

After you have created the ppSlideLayout enumeration, you will want to retrieve the Microsoft PowerPoint presentations that you wish to modify. In this script, all of the Microsoft PowerPoint files in the c:\fso folder will be modified. The Get-ChildItem cmdlet is used to retrieve files that have either a .ppt or a .pptx extension. The fileinfo objects are then passed via the pipeline to the ForEach-Object cmdlet:

$path = "c:\fso"
Get-ChildItem -Path $path -Include "*.ppt", "*.pptx" -Recurse |
ForEach-Object {

Next the fullname of the fileinfo object contains the complete path to the file. This is passed to the Open method of the Presentations collection object that is retrieved from the Presentations property of the Application object. The open method returns a Presentation object. Using the Slides property from the presentation object retrieves a Slides collection object. The item method from the collections object is used to obtain a specific Slide object. In this example, we retrieve the second slide in the deck. Because the slides begin numbering at 1, there is no need to add an offset number. The CustomLayout property from the slide object returns a CustomLayout object that is stored in the $customLayout variable. This section of the script is shown here:

 $presentation = $application.Presentations.open($_.fullname)
 $customLayout = $presentation.Slides.item(2).customLayout

The current Microsoft PowerPoint presentation is shown in the following image.

Image of current Microsoft PowerPoint presentation

 

Retrieving the customLayout object was necessary because the AddSlide method from the slides collection object requires two parameters. The first is the index number that tells the script where to add the new slide, and the second is a customLayout object. The addSlide method returns a slide object that is stored in the $slide variable, as shown here:

 $slide = $presentation.slides.addSlide(2,$customLayout)

The Layout property of the slide object is used to modify the layout of the newly added slide. This is where the PpSlideLayout enumeration stored in the $slideType variable comes into play. To modify the layout of the new slide to a title-only slide, use the PpLayoutTitleOnly static property as shown here:

 $slide.layout = $slideType::ppLayoutTitleOnly

It is time to add some text to the title block of the slide. To do this, you need to retrieve the Shapes collection object from the Shapes property of the slide object. The shapes collection object has a Title property that returns a Shape object. The TextFrame property returns a TextFrame object that contains alignment and anchoring properties for the shape. The textFrame object represents the text frame in a shape object. It contains the text, as well as the properties and methods that control alignment of the text frame. The TextRange property of the TextFrame object returns a TextRange object that represents the text in the TextFrame. Finally, we get to the text property of the TextRange object. The TextRange object has a number of very interesting methods and properties that allow you to manipulate the text in the TextFrame. Here we simply assign a string to the Text property of the TextRange object. The code that adds the title to the slide is shown here:

 $slide.Shapes.title.TextFrame.TextRange.Text = "New Title Text"

After you have added the new slide, set the format of the slide, and added a title to it, it is time to save the modified presentation. To do this, you use the save method from the presentation object:

 $presentation.Save()

After the presentation has been saved, it is time to close it by calling the close method from the presentation object. A string is displayed that indicates the name of the presentation that was modified:

 $presentation.Close()
 "Modifying $_.FullName"
}

To clean up after the script, the quit method from the application object is called. The application variable is set to null and garbage collection is called:

$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()

 

After the script has run, the Microsoft PowerPoint presentation with the new slide is displayed, as shown in the following image.

Image of Microsoft PowerPoint presentation with new slide

 

YF, that is all there is to using Windows PowerShell to add a new slide to a Microsoft PowerPoint presentation. Microsoft PowerPoint Week will continue tomorrow.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment