{"id":49843,"date":"2010-05-12T00:01:00","date_gmt":"2010-05-12T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/05\/12\/hey-scripting-guy-can-i-add-a-new-slide-to-an-existing-microsoft-powerpoint-presentation\/"},"modified":"2010-05-12T00:01:00","modified_gmt":"2010-05-12T00:01:00","slug":"hey-scripting-guy-can-i-add-a-new-slide-to-an-existing-microsoft-powerpoint-presentation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-can-i-add-a-new-slide-to-an-existing-microsoft-powerpoint-presentation\/","title":{"rendered":"Hey, Scripting Guy! Can I Add a New Slide to an Existing Microsoft PowerPoint Presentation?"},"content":{"rendered":"<p><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">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&rsquo;t find an example of doing that. Is it not possible, or just too tough?<\/p>\n<p class=\"MsoNormal\">&#8212; YF<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello YF, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. I am listening to <a href=\"http:\/\/bit.ly\/d9Xtk1\"><font face=\"Segoe\">Stevie Ray Vaughan<\/font><\/a> on my Zune HD, and sipping a cup of <a href=\"http:\/\/bit.ly\/cvu8MF\"><font face=\"Segoe\">Lady Grey tea<\/font><\/a> 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. <\/p>\n<p class=\"MsoNormal\">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<span>&middot;<\/span>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. <\/p>\n<p class=\"MsoNormal\">The complete AddPowerPointSlide.ps1 script is shown here.<\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>AddPowerPointSlide.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\">Add-type -AssemblyName office<br \/>$Application = New-Object -ComObject powerpoint.application<br \/>$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue<br \/>$slideType = &#8220;microsoft.office.interop.powerpoint.ppSlideLayout&#8221; -as [type]<br \/>$path = &#8220;c:fso&#8221;<br \/>Get-ChildItem -Path $path -Include &#8220;*.ppt&#8221;, &#8220;*.pptx&#8221; -Recurse |<br \/>ForEach-Object {<br \/><span>&nbsp;<\/span>$presentation = $application.Presentations.open($_.fullname)<br \/><span>&nbsp;<\/span>$customLayout = $presentation.Slides.item(2).customLayout<br \/><span>&nbsp;<\/span>$slide = $presentation.slides.addSlide(2,$customLayout)<br \/><span>&nbsp;<\/span>$slide.layout = $slideType::ppLayoutTitleOnly<br \/><span>&nbsp;<\/span>$slide.Shapes.title.TextFrame.TextRange.Text = &#8220;New Title Text&#8221;<br \/><span>&nbsp;<\/span>$presentation.Save()<br \/><span>&nbsp;<\/span>$presentation.Close()<br \/><span>&nbsp;<\/span>&#8220;Modifying $_.FullName&#8221;<br \/>}<\/p>\n<p>$application.quit()<br \/>$application = $null<br \/>[gc]::collect()<br \/>[gc]::WaitForPendingFinalizers()<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">The first thing that must be done is to add the <b>office<\/b> assembly, create the <b>PowerPoint<\/b> application object, and make the application visible. This was discussed in <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/05\/10\/hey-scripting-guy-may-10-2010.aspx\"><font face=\"Segoe\">Monday&rsquo;s Hey, Scripting Guy! post<\/font><\/a>. The code that does this is shown here: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Add-type -AssemblyName office<br \/>$Application = New-Object -ComObject powerpoint.application<br \/>$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">To configure the slide layout, you will need to use an instance of the <b>ppSlideLayout<\/b> enumeration. The&nbsp;<a href=\"http:\/\/bit.ly\/d1EegS\"><font face=\"Segoe\"> PpSlideLayout enumeration<\/font><\/a> 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:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$slideType = &#8220;microsoft.office.interop.powerpoint.ppSlideLayout&#8221; -as [type]<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After you have created the <b>ppSlideLayout<\/b> 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 <b>Get-ChildItem<\/b> cmdlet is used to retrieve files that have either a .ppt or a .pptx extension. The <b>fileinfo<\/b> objects are then passed via the pipeline to the <b>ForEach-Object<\/b> cmdlet:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$path = &#8220;c:fso&#8221;<br \/>Get-ChildItem -Path $path -Include &#8220;*.ppt&#8221;, &#8220;*.pptx&#8221; -Recurse |<br \/>ForEach-Object {<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Next the <b>fullname<\/b> of the <b>fileinfo<\/b> object contains the complete path to the file. This is passed to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265430(v=office.12).aspx\"><font face=\"Segoe\">Open method<\/font><\/a> of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265543(v=office.12).aspx\"><font face=\"Segoe\">Presentations collection object<\/font><\/a> that is retrieved from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb230568(v=office.12).aspx\"><font face=\"Segoe\">Presentations property<\/font><\/a> of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251405(v=office.12).aspx\"><font face=\"Segoe\">Application object<\/font><\/a>. The <b>open<\/b> method returns a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265542(v=office.12).aspx\"><font face=\"Segoe\">Presentation object<\/font><\/a>. Using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb230630(v=office.12).aspx\"><font face=\"Segoe\">Slides property<\/font><\/a> from the <b>presentation<\/b> object retrieves a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265580(v=office.12).aspx\"><font face=\"Segoe\">Slides collection object<\/font><\/a>. The <b>item<\/b> method from the <b>collections<\/b> object is used to obtain a specific <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265578(v=office.12).aspx\"><font face=\"Segoe\">Slide object<\/font><\/a>. 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 <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb231180(v=office.12).aspx\"><font face=\"Segoe\">CustomLayout property<\/font><\/a> from the <b>slide<\/b> object returns a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251512(v=office.12).aspx\"><font face=\"Segoe\">CustomLayout object<\/font><\/a> that is stored in the <b>$customLayout<\/b> variable. This section of the script is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$presentation = $application.Presentations.open($_.fullname)<br \/><span>&nbsp;<\/span>$customLayout = $presentation.Slides.item(2).customLayout<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The current Microsoft PowerPoint presentation is shown in the following image.<\/p>\n<p class=\"Fig-Graphic\"><span><img decoding=\"async\" title=\"Image of current Microsoft PowerPoint presentation\" alt=\"Image of current Microsoft PowerPoint presentation\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0512\/hsg-05-12-10-01.jpg\" width=\"600\" height=\"420\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0512\/hsg-05-12-10-01.jpg\"><font face=\"Segoe\"><\/font><\/a><\/span><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">Retrieving the <b>customLayout<\/b> object was necessary because the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb231120(v=office.12).aspx\"><font face=\"Segoe\">AddSlide method<\/font><\/a> 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 <b>customLayout<\/b> object. The <b>addSlide<\/b> method returns a <b>slide<\/b> object that is stored in the <b>$slide<\/b> variable, as shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$slide = $presentation.slides.addSlide(2,$customLayout)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251279(v=office.12).aspx\"><font face=\"Segoe\">Layout property<\/font><\/a> of the <b>slide<\/b> object is used to modify the layout of the newly added slide. This is where the <b>PpSlideLayout<\/b> enumeration stored in the <b>$slideType<\/b> variable comes into play. To modify the layout of the new slide to a title-only slide, use the <b>PpLayoutTitleOnly<\/b> static property as shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$slide.layout = $slideType::ppLayoutTitleOnly<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">It is time to add some text to the title block of the slide. To do this, you need to retrieve the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265577(v=office.12).aspx\"><font face=\"Segoe\">Shapes collection object<\/font><\/a> from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265822(v=office.12).aspx\"><font face=\"Segoe\">Shapes property<\/font><\/a> of the <b>slide<\/b> object. The shapes collection object has a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb230668(v=office.12).aspx\"><font face=\"Segoe\">Title property<\/font><\/a> that returns a&nbsp;<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251480(v=office.12).aspx\"><font face=\"Segoe\">Shape object<\/font><\/a>. The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265780(v=office.12).aspx\"><font face=\"Segoe\">TextFrame property<\/font><\/a> returns a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265592(v=office.12).aspx\"><font face=\"Segoe\">TextFrame object<\/font><\/a> that contains alignment and anchoring properties for the shape. The <b>textFrame<\/b> 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 <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265866(v=office.12).aspx\"><font face=\"Segoe\">TextRange property<\/font><\/a> of the <b>TextFrame<\/b> object returns a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb265593(v=office.12).aspx\"><font face=\"Segoe\">TextRange object<\/font><\/a> that represents the text in the <b>TextFrame<\/b>. Finally, we get to the <b>text<\/b> property of the <b>TextRange<\/b> object. The <b>TextRange<\/b> object has a number of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251500(v=office.12).aspx\"><font face=\"Segoe\">very interesting methods and properties<\/font><\/a> that allow you to manipulate the text in the <b>TextFrame<\/b>. Here we simply assign a string to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb251306(v=office.12).aspx\"><font face=\"Segoe\">Text property<\/font><\/a> of the <b>TextRange<\/b> object. The code that adds the title to the slide is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$slide.Shapes.title.TextFrame.TextRange.Text = &#8220;New Title Text&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">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 <b>save<\/b> method from the <b>presentation<\/b> object:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$presentation.Save()<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After the presentation has been saved, it is time to close it by calling the <b>close<\/b>\nmethod from the <b>presentation<\/b> object. A string is displayed that indicates the name of the presentation that was modified: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;<\/span>$presentation.Close()<br \/><span>&nbsp;<\/span>&#8220;Modifying $_.FullName&#8221;<br \/>}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">To clean up after the script, the <b>quit<\/b> method from the <b>application<\/b> object is called. The application variable is set to null and garbage collection is called: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$application.quit()<br \/>$application = $null<br \/>[gc]::collect()<br \/>[gc]::WaitForPendingFinalizers()<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">After the script has run, the Microsoft PowerPoint presentation with the new slide is displayed, as shown in the following image.<\/p>\n<p class=\"Fig-Graphic\"><span><img decoding=\"async\" title=\"Image of Microsoft PowerPoint presentation with new slide\" alt=\"Image of Microsoft PowerPoint presentation with new slide\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0512\/hsg-05-12-10-02.jpg\" width=\"600\" height=\"420\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0512\/hsg-05-12-10-02.jpg\"><font face=\"Segoe\"><\/font><\/a><\/span><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">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. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; 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&rsquo;t find an example of doing that. Is it not possible, or just too tough? &#8212; [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[129,49,3,45],"class_list":["post-49843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-powerpoint","tag-office","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; 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&rsquo;t find an example of doing that. Is it not possible, or just too tough? &#8212; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=49843"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=49843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=49843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=49843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}