Create and Print a Word Document with PowerShell

I was working with a client that had a requirement where each computer that was deployed needed to be paired with a physical document that had information about the computer. The solution I used to automate this process was to use a PowerShell script to take information from a running task sequence, then write and print a Word document.

  • Here is a high level outline of the process.
    • Information about the computer and deployment is collected by a PowerShell script during the task sequence
    • The same PowerShell script then copies that information to a network share as a CSV file
    • A separate computer or server has a Windows Scheduled Task set to run a second PowerShell script on a schedule
    • The second PowerShell script takes any CSV files in the network location as input. It uses the data from the CSV files to build a Word document and then sends that document to a printer.

This is the script that runs during the task sequence to collect information and write it to a CSV file on a network share. This example script is collecting the Serial Number, Asset Tag, and Computer Model.

A network share needs to be specified as the destination for the CSV file. Credentials for a user account with write access to the network share also need to be specified.

#Set account credentials to connect to network share
$pass="Password"|ConvertTo-SecureString -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PsCredential('user@domain.local',$pass)

#Set network share used for CSV storage
$netpath = '\\server.domain.local\csv'

#Connect to network drive
New-PSDrive -name R -Root $netpath -Credential $cred -PSProvider filesystem -ErrorAction SilentlyContinue

#Set variables
$sn = Get-WmiObject Win32_ComputerSystemProduct | Select-Object -ExpandProperty IdentifyingNumber
$asset = Get-WmiObject Win32_SystemEnclosure | Select-Object -ExpandProperty SmbiosAssetTag
$model = Get-WmiObject Win32_ComputerSystem | Select-Object -ExpandProperty Model

#Write data to the CSV and export to a file
$data = @(
  [pscustomobject]@{
    sn  = $sn
    asset  = $asset
    model = $model
  }
)
$data | Export-Csv -Path "$netpath\$sn.csv" -NoTypeInformation

#Remove quotes from the CSV
(Get-Content "$netpath\$sn.csv") | ForEach-Object {$_ -Replace '"', ""} | Out-File "$netpath\$sn.csv" -Force -Encoding ascii

This is the script that takes the CSV files as input, creates a Word document, and then prints the document. I had this script running as a scheduled task on the server every 10 mintues. This example shows some examples of basic formatting (making a list, injecting an image file, changing font size, etc.)

The location of the CSV files to take as input needs to be specified.

#Script to create a word document based on variables from a computer running the deploy task sequence.

#Set the path where the CSV files are stored
$csvpath = 'C:\CSV'

#Get CSV files in the specified path
$csvs = Get-ChildItem "$csvpath\*.csv"

#Run a loop to import CSV files and data
ForEach ($csv in $csvs) {

    $csvdata = Import-Csv "$csv"
    ForEach ($data in $csvdata)
        {
            $SN = $data.sn
            $Asset = $data.asset
            $Model = $data.model
        }

    #-----------------------------------------------
    #-----------------------------------------------

    #Create a new Word document
    $word = New-Object -ComObject Word.Application
    $Document = $Word.Documents.Add()
    $Selection = $Word.Selection
    #Uncomment to make the Word Document visible
    #$Word.Visible = $True 

    #-----------------------------------------------
    #-----------------------------------------------

    #Format the Word document
    #Set margins
    $Selection.PageSetup.LeftMargin = 36
    $Selection.PageSetup.RightMargin = 36
    $Selection.PageSetup.TopMargin = 36
    $Selection.PageSetup.BottomMargin = 36

    #Title
    $Selection.Style = 'Title'
    $Selection.ParagraphFormat.Alignment = 1
    $Selection.Borders.OutsideLineStyle = 1
    $Selection.TypeText("New Computer Information")
    $Selection.TypeParagraph()
    $Selection.TypeParagraph()
 
    #Numbered List
    $Selection.Style = 'List Number'
    $Selection.Font.Size = 12
    $Selection.TypeText("The computer model is: ")
    $Selection.Font.Bold = 1
    $Selection.TypeText("$model")
    $Selection.Font.Bold = 0
    $Selection.TypeParagraph()
    $Selection.TypeText("The computer serial number is: ")
    $Selection.Font.Bold = 1
    $Selection.TypeText("$SN")
    $Selection.Font.Bold = 0
    $Selection.TypeParagraph()
    $Selection.TypeText("The computer asset tag is: ")
    $Selection.Font.Bold = 1
    $Selection.TypeText("$asset")
    $Selection.Font.Bold = 0
    $Selection.TypeParagraph()
    $Selection.Style = 'No Spacing'

    #Insert and center image
    $Selection.ParagraphFormat.Alignment = 1
	$Selection.InlineShapes.AddPicture("C:\CSV\Images\Image.png")
    $Selection.TypeParagraph()
    $Selection.TypeParagraph()

    #Inser date imaged and add a line for the technician to sign
    $Selection.Font.Size = 12
    $Selection.ParagraphFormat.Alignment = 0
    $date = Get-Date -UFormat "%m / %d / %Y"
    $Selection.TypeText("Imaged Date: $date  -  ")
    $Selection.TypeText("Imaging Technician:_________________")
    $Selection.TypeParagraph()

    #-----------------------------------------------
    #-----------------------------------------------

    #Save the Word document
    $SaveLoc = "$csvpath\$SN.docx"
    $Document.SaveAs([ref]$SaveLoc,[ref]$SaveFormat::wdFormatDocument)
    $word.Quit()

    #-----------------------------------------------
    #-----------------------------------------------

    #Print the Word document
    Start-Process -Filepath "$csvpath\$SN.docx" -verb print
    Start-Sleep -Seconds 10

    #-----------------------------------------------
    #-----------------------------------------------

    #Move the Word document and delete the CSV file
    Move-Item -Path "$csvpath\$SN.docx" -Destination "$csvpath\Completed Documents\$SN.docx" -Force
    Remove-Item "$csv"

    #-----------------------------------------------
    #-----------------------------------------------

}

#Cleanup the Word COM Object
$null = [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$word)
[gc]::Collect()
[gc]::WaitForPendingFinalizers()
Remove-Variable word

This script uses the the Microsoft Word COM object to write the document line by line. More detailed information on all the available objects can be found Here.

This script example creates the Word document silently in the background. If you want the document to be visiable (useful for initially building the document and troubleshooting) uncomment this line in the script.

 $Word.Visible = $True 

I have made these scripts available for download on my GitHub page.