- Reading Azure VM name, IP address, and hostname with PowerShell - Fri, Jul 28 2017
- Automating WSUS with PowerShell - Thu, Jul 13 2017
- Disable SSL and TLS 1.0/1.1 on IIS with PowerShell - Tue, Jun 27 2017
To manipulate Word documents with PowerShell, you first have to create a Word Application COM object.
As you can see below there are a lot of options to work with:
To create a new Word document with PowerShell, you can use the commands below:
$word = New-Object -ComObject "Word.application" $word.Visible = $true $document = $word.documents.Add()
I assign $true to the $word.Visible property, so I can see the document I'm working on in Word.
Now let's add a "nice" title to the document:
$word = New-Object -ComObject "Word.application" $word.Visible = $true $document = $word.documents.Add() $selection = $word.selection $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $selection.typeText("Nice Title") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter"
I used the selection property and its font, typetext, and ParagraphFormat methods to put text into the newly created Word document, set the font size, set the text in bold, change its style, and center the title. Below you can see the result of these PowerShell commands:
Next, I'll add a little calendar in the form of a table to our document:
$selection.TypeParagraph() $Range = $selection.Range $Table = $document.Tables.Add($Range,6,7) $Table.AutoFormat(11) $Table.Borders.InsideLineStyle = 1
I added a new paragraph to my document using the Selection object and read the Range property of the selection, so I know where I'm adding the table. Then I use the Table method of the Word COM application object to add new table.
I am using the AutoFormat property to choose the table format. I just played with the format numbers till I found something I like. Then I'm using the InsideLineStyle property to make the inside borders of my table visible. Finally, I add column captions to my table:
$Column = 1 $Row = 1 $SysDateObject = new-object system.globalization.datetimeformatinfo $DayNames = $SysDateObject.Daynames $DayNames | %{ $Table.Cell($Column,$Row).Range.Text = $_ $Table.Cell($Column,$Row).Range.Font.Name = "Forte" $Row++ }
Since I'm working with a table, I need to establish cell coordinates so I can manipulate the cells. Thus, I add $Row and $Column variables and assign 1 to each of them. Then I get the weekday names from the PowerShell system.globalization.datetimeformatinfo object and assign them to the top cells of my table. To make them look a little better, I change the font. And this is how my Word document looks now:
I have weekday names, but it would be nice to add dates to my little calendar:
$i = 1 $Column = 2 $Row = 2 for($i -eq 1; $i -le [datetime]::DaysInMonth(17,5); $i++){ $Table.Cell($Row,$Column).Range.Text = $i $Table.Cell($Row,$Column).Range.ParagraphFormat.Alignment = "wdAlignParagraphRight" $Column++ if($Column -gt 7){ $Row++ $Column = 1 } }
Firstly, I set up some variables: $i will be my day index, and you already know $Row and $Column. I get the number of days in May from the datetime PowerShell object and then loop from 1 to 31, because May has 31 days. Then I assign the value of $i to the corresponding cell. Because I have only seven columns, I reset the $Column value to 1 every time it becomes greater than 7.
And this is my calendar:
Here is the entire script that adds a title and table to a Word document using PowerShell:
$word = New-Object -ComObject "Word.application" $word.Visible = $true $document = $word.documents.Add() $selection = $word.selection $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $selection.typeText("Nice Title") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter" $selection.TypeParagraph() $Range = $selection.Range $Table = $document.Tables.Add($Range,6,7) $Table.AutoFormat(11) $Table.Borders.InsideLineStyle = 1 $Column = 1 $Row = 1 $SysDateObject = new-object system.globalization.datetimeformatinfo $DayNames = $SysDateObject.Daynames $DayNames | %{ $Table.Cell($Row,$Column).Range.Text = $_ $Table.Cell($Row,$Column).Range.Font.Name = "Forte" $Column++ } $i = 1 $Column = 2 $Row = 2 for($i -eq 1; $i -le [datetime]::DaysInMonth(17,5); $i++){ $Table.Cell($Row,$Column).Range.Text = $i $Table.Cell($Row,$Column).Range.ParagraphFormat.Alignment = "wdAlignParagraphRight" $Column++ if($Column -gt 7){ $Row++ $Column = 1 } } $word = New-Object -ComObject "Word.application" $word.Visible = $true $document = $word.documents.Add() $selection = $word.selection $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $selection.typeText("Nice Title") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter" $selection.TypeParagraph() $Range = $selection.Range $Table = $document.Tables.Add($Range,6,7) $Table.AutoFormat(11) $Table.Borders.InsideLineStyle = 1 $Column = 1 $Row = 1 $SysDateObject = new-object system.globalization.datetimeformatinfo $DayNames = $SysDateObject.Daynames $DayNames | %{ $Table.Cell($Row,$Column).Range.Text = $_ $Table.Cell($Row,$Column).Range.Font.Name = "Forte" $Column++ } $i = 1 $Column = 2 $Row = 2 for($i -eq 1; $i -le [datetime]::DaysInMonth(17,5); $i++){ $Table.Cell($Row,$Column).Range.Text = $i $Table.Cell($Row,$Column).Range.ParagraphFormat.Alignment = "wdAlignParagraphRight" $Column++ if($Column -gt 7){ $Row++ $Column = 1 } }
Now let's do something a bit more complicated. Let's create a calendar for 2018 using PowerShell and Word.
Let's start from the title. There is nothing new here except the $END_OF_STORY variable, which represents the end of the Word document.
$word = New-Object -ComObject "Word.application" $END_OF_STORY = 6 $word.Visible = $true $document = $word.documents.Add() $SysDateObject = new-object system.globalization.datetimeformatinfo $DayNames = $SysDateObject.Daynames $selection = $word.selection $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $selection.typeText("2018 Calendar") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter"
To add a calendar for each month, I will use a loop that iterates through the months from 1 to 12. I'm using the get-date PowerShell function to get the first weekday for each month.
$y = 1 for($y -eq 1; $y -le 12; $y++){ $CURRENTDATE=GET-DATE "$y/1/2018" $FirstDayofMonth = ($CURRENTDATE).DayOfWeek.value__ +1 if($FirstDayofMonth -gt 7){ $FirstDayofMonth = 1 $FirstDayofMonth }
Next I add a new page to the document and create a title for it. Because I'm still inside the for loop, the title will be the name of the current month, which the $CMonth variable represents. Then I'm adding the weekday names to the calendar:
$selection.InsertNewPage() $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $CMonth = (Get-Culture).DateTimeFormat.GetMonthName($CURRENTDATE.Month) $selection.typeText("$CMonth 2018") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter" $selection.TypeParagraph() $Range = $selection.Range $Table = $document.Tables.Add($Range,7,7) $Table.AutoFormat(11) $Table.Borders.InsideLineStyle = 1 $Column = 1 $Row = 1 $DayNames | %{ $Table.Cell($Row,$Column).Range.Text = $_ $Table.Cell($Row,$Column).Range.Font.Name = "Forte" $Column++ }
Now I'm putting days into my table starting at the $FirstDayOfMonth column number, which I calculated before. And when all days are in place, I need to move the cursor to the end of the document, so it will add a new page in the cycle's next iteration at the end of the document.
$i = 1 $Column = $FirstDayofMonth $Row = 2 $DMonth = $CURRENTDATE.Month for($i -eq 1; $i -le [datetime]::DaysInMonth(18,$DMonth); $i++){ $Table.Cell($Row,$Column).Range.Text = $i $Table.Cell($Row,$Column).Range.ParagraphFormat.Alignment = "wdAlignParagraphRight" $Column++ if($Column -gt 7){ $Row++ $Column = 1 } } $selection.EndKey($END_OF_STORY) }
And here is how my calendar for 2018 looks:
Below is the entire script to create a calendar in Word with PowerShell:
Subscribe to 4sysops newsletter!
$word = New-Object -ComObject "Word.application" $END_OF_STORY = 6 $word.Visible = $true $document = $word.documents.Add() $SysDateObject = new-object system.globalization.datetimeformatinfo $DayNames = $SysDateObject.Daynames $selection = $word.selection $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $selection.typeText("2018 Calendar") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter" $y = 1 for($y -eq 1; $y -le 12; $y++){ $CURRENTDATE=GET-DATE "$y/1/2018" $FirstDayofMonth = ($CURRENTDATE).DayOfWeek.value__ +1 if($FirstDayofMonth -gt 7){ $FirstDayofMonth = 1 $FirstDayofMonth } $selection.InsertNewPage() $selection.font.size = 14 $selection.font.bold = 1 $selection.Style ="Title" $CMonth = (Get-Culture).DateTimeFormat.GetMonthName($CURRENTDATE.Month) $selection.typeText("$CMonth 2018") $selection.ParagraphFormat.Alignment = "wdAlignParagraphCenter" $selection.TypeParagraph() $Range = $selection.Range $Table = $document.Tables.Add($Range,7,7) $Table.AutoFormat(11) $Table.Borders.InsideLineStyle = 1 $Column = 1 $Row = 1 $DayNames | %{ $Table.Cell($Row,$Column).Range.Text = $_ $Table.Cell($Row,$Column).Range.Font.Name = "Forte" $Column++ } $i = 1 $Column = $FirstDayofMonth $Row = 2 $DMonth = $CURRENTDATE.Month for($i -eq 1; $i -le [datetime]::DaysInMonth(18,$DMonth); $i++){ $Table.Cell($Row,$Column).Range.Text = $i $Table.Cell($Row,$Column).Range.ParagraphFormat.Alignment = "wdAlignParagraphRight" $Column++ if($Column -gt 7){ $Row++ $Column = 1 } } $selection.EndKey($END_OF_STORY) }
At what point did you create or add a macro to the document?
Why not learn instead of copy pasting vomited scripts you find all over….