Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to make a backup of all Word documents.
Hey, Scripting Guy! I need some help. I routinely edit Microsoft Word documents, but because of the changes I make to the file, I like to keep the original file intact. So what I do is open a Word document, then I use the Save As feature in Word to save a copy of the file into a different folder. I am wondering if I can have Windows PowerShell use the Word automation feature to do a Save As for me. Can you help me?
—GB
Hello GB,
Microsoft Scripting Guy, Ed Wilson, is here. I spent nearly a dozen years in consulting work before I became the Scripting Guy. One of the first things I learned to ask was the question “Why?” It is not that I doubted the customer, but rather because sometimes a customer becomes fixated on a specific solution. When I know what the purpose of the activity is, I can often recommend an easier (and most cases, less expensive) solution.
GB, your question falls directly into this category, and it gives me a reason to begin Word Week.
Sure, I could use the Word automation model. I can open a Word document in a folder, call Save As, give it a new name, then close the Word document and open to the next one. But in this case, the question “Why?” really comes into play. Why do you want to do this?
Well, luckily you included the answer: You want to have a backup copy of a Word document before you begin editing. So, this actually makes it pretty easy. All I need is basic Windows PowerShell.
I can use Get-ChildItem to recurse through your directory structure, New-Item to create your backup folder, and Copy-Item to copy the documents to the backup folder. This will be much faster, and easier to do, than using the Word automation model to open and Save As each document in the folder. Much, much easier. So let's get started.
Create the backup folder
The first thing I do is use the New-Item cmdlet to create a new folder that I will use as the backup folder. To do this, I specify the item type as Directory and provide a path. At the same time, I use a couple of variables to specify the destination path for the source files and the backup folder location. I use –WhatIf now so the command does not actually execute. This will help me make sure the script works completely before I actually run it. These commands are shown here:
$bu = "e:\backup"
$source = "E:\Data\ScriptingGuys\2015"
New-Item -ItemType directory -Path $bu -WhatIf
Find the files
Now I need to find the document files. I have specified my directory starting point as a string that I stored in the $source variable. I filter out only files that have an extension of .docx, and I tell the cmdlet to recurse so that it will find all files in subfolders off of the main directory. I end the command with a pipe character ( | ) because I want each of the file objects that I find to pass to the next command. Here is the command:
Get-ChildItem -Path $source -Filter *.docx -Recurse |
Copy the files and give them a new name
I want to copy each file that I find to the backup destination, and I want to add the letters “bu” to the end of the file name. To do this, I use the Foreach-Object cmdlet and the Copy-Item cmdlet. Once again, because I want to see that the command works properly first, I add the –WhatIf parameter to Copy-Item, as shown here:
ForEach-Object {
Copy-Item -path $_.FullName -Destination ("$bu\{0}.bu.docx" -f $_.basename) -whatif }
I create the new file name based on the BaseName property of the file. The BaseName property is simply the file name without the file extension and without the file path. I pick up the backup location from the $bu variable, and I add .bu to the base file name. I then retain the .docx file extension. The complete script is shown here:
$bu = "e:\backup"
$source = "E:\Data\ScriptingGuys\2015"
New-Item -ItemType directory -Path $bu -WhatIf
Get-ChildItem -Path $source -Filter *.docx -Recurse |
ForEach-Object {
Copy-Item -path $_.FullName -Destination ("$bu\{0}.bu.docx" -f $_.basename) -whatif }
I run it, and examine the output in the Windows PowerShell ISE. This output is shown here:
I pay attention to the second line of the output, and then to the third and following lines. They tell me that the script will work as I expect, so I remove the two –WhatIf parameters. The revised script is shown here:
$bu = "e:\backup"
$source = "E:\Data\ScriptingGuys\2015"
New-Item -ItemType directory -Path $bu
Get-ChildItem -Path $source -Filter *.docx -Recurse |
ForEach-Object {
Copy-Item -path $_.FullName -Destination ("$bu\{0}.bu.docx" -f $_.basename) }
This time, the output is less impressive:
Now I check to see my newly created backup folder. As you can see in the following image, it is full of backup documents:
GB, that is all there is to using Windows PowerShell to back up your Word documents. Word Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
0 comments