Hey, Scripting Guy! We have received our summer student interns, and I asked them to create some Microsoft PowerPoint presentations for me. Unfortunately, the theme they used was not something I can use in the business world. I hate to have the students go back through all of the presentations they created and apply a new theme because I sort of feel like it is my fault. I guess I should not have told an 18-year-old summer student to pick out themes that “look nice.” Is there a script that can be written to change the theme of a Microsoft PowerPoint presentation?
— GS
Hello GS,
Microsoft Scripting Guy Ed Wilson here. I have been going through the posts on the Official Scripting Guys Forum and answering a few of the questions that have been lingering for a while. One of the really cool things about the forum is the number of extremely dedicated and smart moderators we have. I enjoy reading their answers because often I learn new techniques that will be useful to me later. The answers received from the forum are generally pretty quick because we have so many moderators. I have also been checking the e-mail sent to scripter@microsoft.com, and that’s when I ran across your question and thought it would make a pretty cool script. The complete FindPowerPointAndApplyTheme.ps1 is shown here.
FindPowerPointAndApplyTheme.ps1
Add-type -AssemblyName office
$Application = New-Object -ComObject powerpoint.application
$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
$parentPath = $Application.Path | Split-Path -Parent
$themePath = Join-Path -Path $parentPath -childPath “Document Themes 14”
$path = “c:fso”
Get-ChildItem -Path $path -Include “*.ppt”, “*.pptx” -Recurse |
ForEach-Object {
$presentation = $application.Presentations.open($_.fullname)
$presentation.ApplyTemplate($(Join-Path -Path $themePath -ChildPath “angles.thmx”))
$presentation.Save()
$presentation.Close()
“Modifying $_.FullName”
}
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
The first thing you need to do is to use the Add-Type cmdlet to add the Office core assembly to our Windows PowerShell session. For more information about this, see yesterday’s Hey, Scripting Guy post. You also need to create an instance of the powerpoint application object, and set it to visible by using the msoTrue value from the MsoTriState enumeration:
Add-type -AssemblyName office
$Application = New-Object -ComObject powerpoint.application
$application.visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
Now it is time to retrieve the folder containing the Microsoft Office installation. This location is normally c:Program Files, but on my computer, the installation directory is on an E drive:
PS C:> $Application = New-Object -ComObject powerpoint.application
PS C:> $Application.Path
E:Program FilesMicrosoft OfficeOffice14
PS C:>
With Office 2010, the themes are in a folder called “Document Themes 14”:
There is no way to directly retrieve the location for the theme files (.thmx file extension); therefore, it is necessary to build up the path. To do this, the Microsoft PowerPoint application path parent folder is split using the Split-Path cmdlet and stored in the $parentPath variable. On my computer, this parent path is shown here:
PS C:> $Application.Path | Split-Path -Parent
E:Program FilesMicrosoft Office
PS C:>
Next, the Join-Path cmdlet is used to build up the location for the theme templates. The parent path is joined with the “Document Themes 14” folder. The code that does this is shown here:
$parentPath = $Application.Path | Split-Path -Parent
$themePath = Join-Path -Path $parentPath -childPath “Document Themes 14”
After getting the prelimina ries out of the way, the next thing to do is to use the Get-ChildItem cmdlet to retrieve all of the Microsoft PowerPoint presentations in a specific folder. I chose the c:fso folder, but you will probably need to modify the value of the $path variable to meet your specific needs. The resulting FIleInfo objects are piped to the ForEach-Object cmdlet:
$path = “c:fso”
Get-ChildItem -Path $path -Include “*.ppt”, “*.pptx” -Recurse |
The ForEach-Object cmdlet accepts the FileInfo objects that were returned by the Get-ChildItem cmdlet, and it uses the $_ automatic variable to refer to the current item on the pipeline. The fullname property contains the complete path to the Microsoft PowerPoint files that were found by the Get-ChildItem cmdlet. The open method is used to open the presentation. The presentations that are returned on my computer do not have a theme or a template applied to them. As shown in the following image, the presentations are relatively plain.
The returned presentation object is stored in the $presentation variable:
ForEach-Object {
$presentation = $application.Presentations.open($_.fullname)
Now it is time to apply the template to the presentation. The ApplyTemplate method needs a complete path to the specific theme or template to be applied. In this example, the angles theme is applied:
$presentation.ApplyTemplate($(Join-Path -Path $themePath -ChildPath “angles.thmx”))
After applying the theme to the Microsoft PowerPoint presentation, the slides now appear to be more colorful, as shown in the following image.
As the script is running, the presentations will open and flash on the screen until the script has finished processing all of the files. Each presentation is saved and closed before the script moves to the next presentation:
$presentation.Save()
$presentation.Close()
“Modifying $_.FullName”
}
Now it is time to clean up after running the script. These commands were discussed in yesterday’s script:
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
GS, that is all there is to using Windows PowerShell to apply themes 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
0 comments