#Requires -Version 3.0 #This File is in Unicode format. Do not edit in an ASCII editor. #region help text <# .SYNOPSIS Creates a XenMobile List of Users with Multiple Enrolled Devices report. .DESCRIPTION Creates a XenMobile List of Users with Multiple Enrolled Devices report using Microsoft Word, PDF, formatted text or HTML and PowerShell. This script is based on Carl Webster Template Script and user XenMobile REST API. Creates a document named XMS-Multiple-Users-Devices.docx (or .PDF or .TXT or .HTML). Word and PDF documents include a Cover Page, Table of Contents and Footer. Includes support for the following language versions of Microsoft Word: Catalan Chinese Danish Dutch English Finnish French German Norwegian Portuguese Spanish Swedish .PARAMETER CompanyName Company Name to use for the Cover Page. Default value is contained in HKCU:\Software\Microsoft\Office\Common\UserInfo\CompanyName or HKCU:\Software\Microsoft\Office\Common\UserInfo\Company, whichever is populated on the computer running the script. This parameter has an alias of CN. If either registry key does not exist and this parameter is not specified, the report will not contain a Company Name on the cover page. This parameter is only valid with the MSWORD and PDF output parameters. .PARAMETER CompanyAddress Company Address to use for the Cover Page, if the Cover Page has the Address field. The following Cover Pages have an Address field: Sideline Contrast Exposure Filigree Ion (Dark) Retrospect Semaphore Tiles ViewMaster This parameter is only valid with the MSWORD and PDF output parameters. This parameter has an alias of CA. .PARAMETER CompanyEmail Company Email to use for the Cover Page, if the Cover Page has the Email field. The following Cover Pages have an Email field: Facet This parameter is only valid with the MSWORD and PDF output parameters. This parameter has an alias of CE. .PARAMETER CompanyFax Company Fax to use for the Cover Page, if the Cover Page has the Fax field. The following Cover Pages have a Fax field: Contrast Exposure This parameter is only valid with the MSWORD and PDF output parameters. This parameter has an alias of CF. .PARAMETER CompanyPhone Company Phone to use for the Cover Page, if the Cover Page has the Phone field. The following Cover Pages have a Phone field: Contrast Exposure This parameter is only valid with the MSWORD and PDF output parameters. This parameter has an alias of CPh. .PARAMETER CoverPage What Microsoft Word Cover Page to use. Only Word 2010, 2013 and 2016 are supported. (default cover pages in Word en-US) Valid input is: Alphabet (Word 2010. Works) Annual (Word 2010. Doesn't work well for this report) Austere (Word 2010. Works) Austin (Word 2010/2013/2016. Doesn't work in 2013 or 2016, mostly works in 2010 but Subtitle/Subject & Author fields need to be moved after title box is moved up) Banded (Word 2013/2016. Works) Conservative (Word 2010. Works) Contrast (Word 2010. Works) Cubicles (Word 2010. Works) Exposure (Word 2010. Works if you like looking sideways) Facet (Word 2013/2016. Works) Filigree (Word 2013/2016. Works) Grid (Word 2010/2013/2016. Works in 2010) Integral (Word 2013/2016. Works) Ion (Dark) (Word 2013/2016. Top date doesn't fit; box needs to be manually resized or font changed to 8 point) Ion (Light) (Word 2013/2016. Top date doesn't fit; box needs to be manually resized or font changed to 8 point) Mod (Word 2010. Works) Motion (Word 2010/2013/2016. Works if top date is manually changed to 36 point) Newsprint (Word 2010. Works but date is not populated) Perspective (Word 2010. Works) Pinstripes (Word 2010. Works) Puzzle (Word 2010. Top date doesn't fit; box needs to be manually resized or font changed to 14 point) Retrospect (Word 2013/2016. Works) Semaphore (Word 2013/2016. Works) Sideline (Word 2010/2013/2016. Doesn't work in 2013 or 2016, works in 2010) Slice (Dark) (Word 2013/2016. Doesn't work) Slice (Light) (Word 2013/2016. Doesn't work) Stacks (Word 2010. Works) Tiles (Word 2010. Date doesn't fit unless changed to 26 point) Transcend (Word 2010. Works) ViewMaster (Word 2013/2016. Works) Whisp (Word 2013/2016. Works) Default value is Sideline. This parameter has an alias of CP. This parameter is only valid with the MSWORD and PDF output parameters. .PARAMETER UserName User name to use for the Cover Page and Footer. Default value is contained in $env:username This parameter has an alias of UN. This parameter is only valid with the MSWORD and PDF output parameters. .PARAMETER PDF SaveAs PDF file instead of DOCX file. This parameter is disabled by default. The PDF file is roughly 5X to 10X larger than the DOCX file. This parameter requires Microsoft Word to be installed. This parameter uses the Word SaveAs PDF capability. .PARAMETER Text Creates a formatted text file with a .txt extension. This parameter is disabled by default. .PARAMETER MSWord SaveAs DOCX file This parameter is set True if no other output format is selected. .PARAMETER HTML Creates an HTML file with an .html extension. This parameter is disabled by default. This parameter is reserved for a future update and no output is created at this time. .PARAMETER AddDateTime Adds a date time stamp to the end of the file name. Time stamp is in the format of yyyy-MM-dd_HHmm. June 1, 2017 at 6PM is 2017-06-01_1800. Output filename will be ReportName_2017-06-01_1800.docx (or .pdf). This parameter is disabled by default. .PARAMETER Folder Specifies the optional output folder to save the output report. .PARAMETER SmtpServer Specifies the optional email server to send the output report. .PARAMETER SmtpPort Specifies the SMTP port. Default is 25. .PARAMETER UseSSL Specifies whether to use SSL for the SmtpServer. Default is False. .PARAMETER From Specifies the username for the From email address. If SmtpServer is used, this is a required parameter. .PARAMETER To Specifies the username for the To email address. If SmtpServer is used, this is a required parameter. .PARAMETER Dev Clears errors at the beginning of the script. Outputs all errors to a text file at the end of the script. This is used when the script developer requests more troubleshooting data. Text file is placed in the same folder from where the script is run. This parameter is disabled by default. .PARAMETER ScriptInfo Outputs information about the script to a text file. Text file is placed in the same folder from where the script is run. This parameter is disabled by default. This parameter has an alias of SI. .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 Will use all default values. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. .EXAMPLE PS C:\PSScript > .\XMS--List-Inactive-Devices.ps1 -PDF Will use all default values and save the document as a PDF file. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -TEXT Will use all default values and save the document as a formatted text file. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -HTML This parameter is reserved for a future update and no output is created at this time. Will use all default values and save the document as an HTML file. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. .EXAMPLE PS C:\PSScript .\XMS-Multiple-Users-Devices.ps1 -CompanyName "Arnaud Pain Consulting" -CoverPage "Mod" -UserName "Arnaud Pain" Will use: Arnaud Pain Consulting for the Company Name. Mod for the Cover Page format. Arnaud Pain for the User Name. .EXAMPLE PS C:\PSScript .\XMS-Multiple-Users-Devices.ps1 -CompanyName "Sherlock Holmes Consulting" ` -CoverPage Exposure -UserName "Dr. Watson" ` -CompanyAddress "221B Baker Street, London, England" ` -CompanyFax "+44 1753 276600" ` -CompanyPhone "+44 1753 276200" Will use: Sherlock Holmes Consulting for the Company Name. Exposure for the Cover Page format. Dr. Watson for the User Name. 221B Baker Street, London, England for the Company Address. +44 1753 276600 for the Company Fax. +44 1753 276200 for the Compnay Phone. .EXAMPLE PS C:\PSScript .\XMS-Multiple-Users-Devices.ps1 -CompanyName "Sherlock Holmes Consulting" ` -CoverPage Facet -UserName "Dr. Watson" ` -CompanyEmail SuperSleuth@SherlockHolmes.com Will use: Sherlock Holmes Consulting for the Company Name. Facet for the Cover Page format. Dr. Watson for the User Name. SuperSleuth@SherlockHolmes.com for the Compnay Email. .EXAMPLE PS C:\PSScript .\XMS-Multiple-Users-Devices.ps1 -CN "Arnaud Pain Consulting" -CP "Mod" -UN "Arnaud Pain" Will use: Arnaud Pain Consulting for the Company Name (alias CN). Mod for the Cover Page format (alias CP). Arnaud Pain for the User Name (alias UN). .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -AddDateTime Will use all default values. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. Adds a date time stamp to the end of the file name. Time stamp is in the format of yyyy-MM-dd_HHmm. June 1, 2017 at 6PM is 2017-06-01_1800. Output filename will be Script_Template_2017-06-01_1800.docx .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -PDF -AddDateTime Will use all default values and save the document as a PDF file. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. Adds a date time stamp to the end of the file name. Time stamp is in the format of yyyy-MM-dd_HHmm. June 1, 2017 at 6PM is 2017-06-01_1800. Output filename will be Script_Template_2017-06-01_1800.PDF .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -Folder \\FileServer\ShareName Will use all default values. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. Output file will be saved in the path \\FileServer\ShareName .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -SmtpServer mail.domain.tld -From XDAdmin@domain.tld -To ITGroup@domain.tld Will use all Default values. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. Script will use the email server mail.domain.tld, sending from XDAdmin@domain.tld, sending to ITGroup@domain.tld. Script will use the default SMTP port 25 and will not use SSL. If the current user's credentials are not valid to send email, the user will be prompted to enter valid credentials. .EXAMPLE PS C:\PSScript > .\XMS-Multiple-Users-Devices.ps1 -SmtpServer smtp.office365.com -SmtpPort 587 -UseSSL -From Arnaud@ArnaudPain.com -To ITGroup@ArnaudPain.com Will use all Default values. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\CompanyName="Arnaud Pain" or HKEY_CURRENT_USER\Software\Microsoft\Office\Common\UserInfo\Company="Arnaud Pain" $env:username = Administrator Arnaud Pain for the Company Name. Sideline for the Cover Page format. Administrator for the User Name. Script will use the email server smtp.office365.com on port 587 using SSL, sending from Arnaud@ArnaudPain.com, sending to ITGroup@ArnaudPain.com. If the current user's credentials are not valid to send email, the user will be prompted to enter valid credentials. .INPUTS None. You cannot pipe objects to this script. .OUTPUTS No objects are output from this script. This script creates a Word, PDF, Formatted Text or HTML document. .NOTES NAME: XMS-Multiple-Users-Devices_V1.03.ps1 VERSION: 1.03 AUTHOR: Arnaud Pain, Carl Webster, Michael B. Smith, Iain Brighton, Jeff Wouters, Barry Schiffer, Jim Moyle LASTEDIT: December 13, 2017 #> #endregion #region script parameters #thanks to @jeffwouters and Michael B. Smith for helping Carl Webster with these parameters [CmdletBinding(SupportsShouldProcess = $False, ConfirmImpact = "None", DefaultParameterSetName = "Word") ] Param( [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Switch]$MSWord=$False, [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Switch]$PDF=$False, [parameter(ParameterSetName="Text",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Switch]$Text=$False, [parameter(ParameterSetName="HTML",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Switch]$HTML=$False, [parameter(Mandatory=$False)] [Switch]$AddDateTime=$False, [parameter(Mandatory=$False)] [string]$Folder="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CN")] [ValidateNotNullOrEmpty()] [string]$CompanyName="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CA")] [ValidateNotNullOrEmpty()] [string]$CompanyAddress="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CE")] [ValidateNotNullOrEmpty()] [string]$CompanyEmail="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CF")] [ValidateNotNullOrEmpty()] [string]$CompanyFax="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CPh")] [ValidateNotNullOrEmpty()] [string]$CompanyPhone="", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("CP")] [ValidateNotNullOrEmpty()] [string]$CoverPage="Sideline", [parameter(ParameterSetName="Word",Mandatory=$False)] [parameter(ParameterSetName="PDF",Mandatory=$False)] [parameter(ParameterSetName="SMTP",Mandatory=$False)] [Alias("UN")] [ValidateNotNullOrEmpty()] [string]$UserName=$env:username, [parameter(ParameterSetName="SMTP",Mandatory=$True)] [string]$SmtpServer="", [parameter(ParameterSetName="SMTP",Mandatory=$False)] [int]$SmtpPort=25, [parameter(ParameterSetName="SMTP",Mandatory=$False)] [switch]$UseSSL=$False, [parameter(ParameterSetName="SMTP",Mandatory=$True)] [string]$From="", [parameter(ParameterSetName="SMTP",Mandatory=$True)] [string]$To="", [parameter(Mandatory=$False)] [Switch]$Dev=$False, [parameter(Mandatory=$False)] [Alias("SI")] [Switch]$ScriptInfo=$False ) #endregion #region script change log #arnaud.pain@arnaud.biz #@arnaud_pain on Twitter #http://arnaudpain.com #Created on February 10, 2018 # #endregion #region initial variable testing and setup Set-StrictMode -Version 2 #force on $PSDefaultParameterValues = @{"*:Verbose"=$True} $SaveEAPreference = $ErrorActionPreference $ErrorActionPreference = 'SilentlyContinue' If($Dev) { $Error.Clear() $Script:DevErrorFile = "$($pwd.Path)\XMS-Multiple-Users-DevicesScriptErrors_$(Get-Date -f yyyy-MM-dd_HHmm).txt" } If($Null -eq $MSWord) { If($Text -or $HTML -or $PDF) { $MSWord = $False } Else { $MSWord = $True } } If($MSWord -eq $False -and $PDF -eq $False -and $Text -eq $False -and $HTML -eq $False) { $MSWord = $True } Write-Verbose "$(Get-Date): Testing output parameters" If($MSWord) { Write-Verbose "$(Get-Date): MSWord is set" } ElseIf($PDF) { Write-Verbose "$(Get-Date): PDF is set" } ElseIf($Text) { Write-Verbose "$(Get-Date): Text is set" } ElseIf($HTML) { Write-Verbose "$(Get-Date): HTML is set" } Else { $ErrorActionPreference = $SaveEAPreference Write-Verbose "$(Get-Date): Unable to determine output parameter" If($Null -eq $MSWord) { Write-Verbose "$(Get-Date): MSWord is Null" } ElseIf($Null -eq $PDF) { Write-Verbose "$(Get-Date): PDF is Null" } ElseIf($Null -eq $Text) { Write-Verbose "$(Get-Date): Text is Null" } ElseIf($Null -eq $HTML) { Write-Verbose "$(Get-Date): HTML is Null" } Else { Write-Verbose "$(Get-Date): MSWord is $($MSWord)" Write-Verbose "$(Get-Date): PDF is $($PDF)" Write-Verbose "$(Get-Date): Text is $($Text)" Write-Verbose "$(Get-Date): HTML is $($HTML)" } Write-Error "Unable to determine output parameter. Script cannot continue" Exit } If($Folder -ne "") { Write-Verbose "$(Get-Date): Testing folder path" #does it exist If(Test-Path $Folder -EA 0) { #it exists, now check to see if it is a folder and not a file If(Test-Path $Folder -pathType Container -EA 0) { #it exists and it is a folder Write-Verbose "$(Get-Date): Folder path $Folder exists and is a folder" } Else { #it exists but it is a file not a folder Write-Error "Folder $Folder is a file, not a folder. Script cannot continue" Exit } } Else { #does not exist Write-Error "Folder $Folder does not exist. Script cannot continue" Exit } } #endregion #region initialize variables for word html and text [string]$Script:RunningOS = (Get-WmiObject -class Win32_OperatingSystem -EA 0).Caption If($MSWord -or $PDF) { #try and fix the issue with the $CompanyName variable $Script:CoName = $CompanyName Write-Verbose "$(Get-Date): CoName is $($Script:CoName)" #the following values were attained from #http://groovy.codehaus.org/modules/scriptom/1.6.0/scriptom-office-2K3-tlb/apidocs/ #http://msdn.microsoft.com/en-us/library/office/aa211923(v=office.11).aspx [int]$wdAlignPageNumberRight = 2 [long]$wdColorGray15 = 14277081 [long]$wdColorGray15 = 14277081 [long]$wdColorRoyalBlue = 13459258 [int]$wdMove = 0 [int]$wdSeekMainDocument = 0 [int]$wdSeekPrimaryFooter = 4 [int]$wdStory = 6 [long]$wdColorRed = 255 [long]$wdColorWhite = 16777215 [int]$wdColorBlack = 0 [int]$wdWord2007 = 12 [int]$wdWord2010 = 14 [int]$wdWord2013 = 15 [int]$wdWord2016 = 16 [int]$wdFormatDocumentDefault = 16 [int]$wdFormatPDF = 17 #http://blogs.technet.com/b/heyscriptingguy/archive/2006/03/01/how-can-i-right-align-a-single-column-in-a-word-table.aspx #http://msdn.microsoft.com/en-us/library/office/ff835817%28v=office.15%29.aspx [int]$wdAlignParagraphLeft = 0 [int]$wdAlignParagraphCenter = 1 [int]$wdAlignParagraphRight = 2 #http://msdn.microsoft.com/en-us/library/office/ff193345%28v=office.15%29.aspx [int]$wdCellAlignVerticalTop = 0 [int]$wdCellAlignVerticalCenter = 1 [int]$wdCellAlignVerticalBottom = 2 #http://msdn.microsoft.com/en-us/library/office/ff844856%28v=office.15%29.aspx [int]$wdAutoFitFixed = 0 [int]$wdAutoFitContent = 1 [int]$wdAutoFitWindow = 2 #http://msdn.microsoft.com/en-us/library/office/ff821928%28v=office.15%29.aspx [int]$wdAdjustNone = 0 [int]$wdAdjustProportional = 1 [int]$wdAdjustFirstColumn = 2 [int]$wdAdjustSameWidth = 3 [int]$PointsPerTabStop = 36 [int]$Indent0TabStops = 0 * $PointsPerTabStop [int]$Indent1TabStops = 1 * $PointsPerTabStop [int]$Indent2TabStops = 2 * $PointsPerTabStop [int]$Indent3TabStops = 3 * $PointsPerTabStop [int]$Indent4TabStops = 4 * $PointsPerTabStop # http://www.thedoctools.com/index.php?show=wt_style_names_english_danish_german_french [int]$wdStyleHeading1 = -2 [int]$wdStyleHeading2 = -3 [int]$wdStyleHeading3 = -4 [int]$wdStyleHeading4 = -5 [int]$wdStyleNoSpacing = -158 [int]$wdTableGrid = -155 #http://groovy.codehaus.org/modules/scriptom/1.6.0/scriptom-office-2K3-tlb/apidocs/org/codehaus/groovy/scriptom/tlb/office/word/WdLineStyle.html [int]$wdLineStyleNone = 0 [int]$wdLineStyleSingle = 1 [int]$wdHeadingFormatTrue = -1 [int]$wdHeadingFormatFalse = 0 #portrait and landscape $wdOrientLandscape = 1 $wdOrientPortrait = 0 } If($HTML) { Set htmlredmask -Option AllScope -Value "#FF0000" 4>$Null Set htmlcyanmask -Option AllScope -Value "#00FFFF" 4>$Null Set htmlbluemask -Option AllScope -Value "#0000FF" 4>$Null Set htmldarkbluemask -Option AllScope -Value "#0000A0" 4>$Null Set htmllightbluemask -Option AllScope -Value "#ADD8E6" 4>$Null Set htmlpurplemask -Option AllScope -Value "#800080" 4>$Null Set htmlyellowmask -Option AllScope -Value "#FFFF00" 4>$Null Set htmllimemask -Option AllScope -Value "#00FF00" 4>$Null Set htmlmagentamask -Option AllScope -Value "#FF00FF" 4>$Null Set htmlwhitemask -Option AllScope -Value "#FFFFFF" 4>$Null Set htmlsilvermask -Option AllScope -Value "#C0C0C0" 4>$Null Set htmlgraymask -Option AllScope -Value "#808080" 4>$Null Set htmlblackmask -Option AllScope -Value "#000000" 4>$Null Set htmlorangemask -Option AllScope -Value "#FFA500" 4>$Null Set htmlmaroonmask -Option AllScope -Value "#800000" 4>$Null Set htmlgreenmask -Option AllScope -Value "#008000" 4>$Null Set htmlolivemask -Option AllScope -Value "#808000" 4>$Null Set htmlbold -Option AllScope -Value 1 4>$Null Set htmlitalics -Option AllScope -Value 2 4>$Null Set htmlred -Option AllScope -Value 4 4>$Null Set htmlcyan -Option AllScope -Value 8 4>$Null Set htmlblue -Option AllScope -Value 16 4>$Null Set htmldarkblue -Option AllScope -Value 32 4>$Null Set htmllightblue -Option AllScope -Value 64 4>$Null Set htmlpurple -Option AllScope -Value 128 4>$Null Set htmlyellow -Option AllScope -Value 256 4>$Null Set htmllime -Option AllScope -Value 512 4>$Null Set htmlmagenta -Option AllScope -Value 1024 4>$Null Set htmlwhite -Option AllScope -Value 2048 4>$Null Set htmlsilver -Option AllScope -Value 4096 4>$Null Set htmlgray -Option AllScope -Value 8192 4>$Null Set htmlolive -Option AllScope -Value 16384 4>$Null Set htmlorange -Option AllScope -Value 32768 4>$Null Set htmlmaroon -Option AllScope -Value 65536 4>$Null Set htmlgreen -Option AllScope -Value 131072 4>$Null Set htmlblack -Option AllScope -Value 262144 4>$Null } If($TEXT) { $global:output = "" } #endregion #region word specific functions Function SetWordHashTable { Param([string]$CultureCode) #optimized by Michael B. Smith # DE and FR translations for Word 2010 by Vladimir Radojevic # Vladimir.Radojevic@Commerzreal.com # DA translations for Word 2010 by Thomas Daugaard # Citrix Infrastructure Specialist at edgemo A/S # CA translations by Javier Sanchez # CEO & Founder 101 Consulting #ca - Catalan #da - Danish #de - German #en - English #es - Spanish #fi - Finnish #fr - French #nb - Norwegian #nl - Dutch #pt - Portuguese #sv - Swedish #zh - Chinese [string]$toc = $( Switch ($CultureCode) { 'ca-' { 'Taula automática 2'; Break } 'da-' { 'Automatisk tabel 2'; Break } 'de-' { 'Automatische Tabelle 2'; Break } 'en-' { 'Automatic Table 2'; Break } 'es-' { 'Tabla automática 2'; Break } 'fi-' { 'Automaattinen taulukko 2'; Break } 'fr-' { 'Table Automatique 2'; Break } 'nb-' { 'Automatisk tabell 2'; Break } 'nl-' { 'Automatische inhoudsopgave 2'; Break } 'pt-' { 'Sumário Automático 2'; Break } 'sv-' { 'Automatisk innehållsförteckning2'; Break } 'zh-' { '自动目录 2'; Break } } ) $Script:myHash = @{} $Script:myHash.Word_TableOfContents = $toc $Script:myHash.Word_NoSpacing = $wdStyleNoSpacing $Script:myHash.Word_Heading1 = $wdStyleheading1 $Script:myHash.Word_Heading2 = $wdStyleheading2 $Script:myHash.Word_Heading3 = $wdStyleheading3 $Script:myHash.Word_Heading4 = $wdStyleheading4 $Script:myHash.Word_TableGrid = $wdTableGrid } Function GetCulture { Param([int]$WordValue) #codes obtained from http://support.microsoft.com/kb/221435 #http://msdn.microsoft.com/en-us/library/bb213877(v=office.12).aspx $CatalanArray = 1027 $ChineseArray = 2052,3076,5124,4100 $DanishArray = 1030 $DutchArray = 2067, 1043 $EnglishArray = 3081, 10249, 4105, 9225, 6153, 8201, 5129, 13321, 7177, 11273, 2057, 1033, 12297 $FinnishArray = 1035 $FrenchArray = 2060, 1036, 11276, 3084, 12300, 5132, 13324, 6156, 8204, 10252, 7180, 9228, 4108 $GermanArray = 1031, 3079, 5127, 4103, 2055 $NorwegianArray = 1044, 2068 $PortugueseArray = 1046, 2070 $SpanishArray = 1034, 11274, 16394, 13322, 9226, 5130, 7178, 12298, 17418, 4106, 18442, 19466, 6154, 15370, 10250, 20490, 3082, 14346, 8202 $SwedishArray = 1053, 2077 #ca - Catalan #da - Danish #de - German #en - English #es - Spanish #fi - Finnish #fr - French #nb - Norwegian #nl - Dutch #pt - Portuguese #sv - Swedish #zh - Chinese Switch ($WordValue) { {$CatalanArray -contains $_} {$CultureCode = "ca-"} {$ChineseArray -contains $_} {$CultureCode = "zh-"} {$DanishArray -contains $_} {$CultureCode = "da-"} {$DutchArray -contains $_} {$CultureCode = "nl-"} {$EnglishArray -contains $_} {$CultureCode = "en-"} {$FinnishArray -contains $_} {$CultureCode = "fi-"} {$FrenchArray -contains $_} {$CultureCode = "fr-"} {$GermanArray -contains $_} {$CultureCode = "de-"} {$NorwegianArray -contains $_} {$CultureCode = "nb-"} {$PortugueseArray -contains $_} {$CultureCode = "pt-"} {$SpanishArray -contains $_} {$CultureCode = "es-"} {$SwedishArray -contains $_} {$CultureCode = "sv-"} Default {$CultureCode = "en-"} } Return $CultureCode } Function ValidateCoverPage { Param([int]$xWordVersion, [string]$xCP, [string]$CultureCode) $xArray = "" Switch ($CultureCode) { 'ca-' { If($xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "En bandes", "Faceta", "Filigrana", "Integral", "Ió (clar)", "Ió (fosc)", "Línia lateral", "Moviment", "Quadrícula", "Retrospectiu", "Sector (clar)", "Sector (fosc)", "Semàfor", "Visualització principal", "Whisp") } ElseIf($xWordVersion -eq $wdWord2013) { $xArray = ("Austin", "En bandes", "Faceta", "Filigrana", "Integral", "Ió (clar)", "Ió (fosc)", "Línia lateral", "Moviment", "Quadrícula", "Retrospectiu", "Sector (clar)", "Sector (fosc)", "Semàfor", "Visualització", "Whisp") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alfabet", "Anual", "Austin", "Conservador", "Contrast", "Cubicles", "Diplomàtic", "Exposició", "Línia lateral", "Mod", "Mosiac", "Moviment", "Paper de diari", "Perspectiva", "Piles", "Quadrícula", "Sobri", "Transcendir", "Trencaclosques") } } 'da-' { If($xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "BevægElse", "Brusen", "Facet", "Filigran", "Gitter", "Integral", "Ion (lys)", "Ion (mørk)", "Retro", "Semafor", "Sidelinje", "Stribet", "Udsnit (lys)", "Udsnit (mørk)", "Visningsmaster") } ElseIf($xWordVersion -eq $wdWord2013) { $xArray = ("BevægElse", "Brusen", "Ion (lys)", "Filigran", "Retro", "Semafor", "Visningsmaster", "Integral", "Facet", "Gitter", "Stribet", "Sidelinje", "Udsnit (lys)", "Udsnit (mørk)", "Ion (mørk)", "Austin") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("BevægElse", "Moderat", "Perspektiv", "Firkanter", "Overskrid", "Alfabet", "Kontrast", "Stakke", "Fliser", "Gåde", "Gitter", "Austin", "Eksponering", "Sidelinje", "Enkel", "Nålestribet", "Årlig", "Avispapir", "Tradionel") } } 'de-' { If($xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Bewegung", "Facette", "Filigran", "Gebändert", "Integral", "Ion (dunkel)", "Ion (hell)", "Pfiff", "Randlinie", "Raster", "Rückblick", "Segment (dunkel)", "Segment (hell)", "Semaphor", "ViewMaster") } ElseIf($xWordVersion -eq $wdWord2013) { $xArray = ("Semaphor", "Segment (hell)", "Ion (hell)", "Raster", "Ion (dunkel)", "Filigran", "Rückblick", "Pfiff", "ViewMaster", "Segment (dunkel)", "Verbunden", "Bewegung", "Randlinie", "Austin", "Integral", "Facette") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alphabet", "Austin", "Bewegung", "Durchscheinend", "Herausgestellt", "Jährlich", "Kacheln", "Kontrast", "Kubistisch", "Modern", "Nadelstreifen", "Perspektive", "Puzzle", "Randlinie", "Raster", "Schlicht", "Stapel", "Traditionell", "Zeitungspapier") } } 'en-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Banded", "Facet", "Filigree", "Grid", "Integral", "Ion (Dark)", "Ion (Light)", "Motion", "Retrospect", "Semaphore", "Sideline", "Slice (Dark)", "Slice (Light)", "ViewMaster", "Whisp") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alphabet", "Annual", "Austere", "Austin", "Conservative", "Contrast", "Cubicles", "Exposure", "Grid", "Mod", "Motion", "Newsprint", "Perspective", "Pinstripes", "Puzzle", "Sideline", "Stacks", "Tiles", "Transcend") } } 'es-' { If($xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Con bandas", "Cortar (oscuro)", "Cuadrícula", "Whisp", "Faceta", "Filigrana", "Integral", "Ion (claro)", "Ion (oscuro)", "Línea lateral", "Movimiento", "Retrospectiva", "Semáforo", "Slice (luz)", "Vista principal", "Whisp") } ElseIf($xWordVersion -eq $wdWord2013) { $xArray = ("Whisp", "Vista principal", "Filigrana", "Austin", "Slice (luz)", "Faceta", "Semáforo", "Retrospectiva", "Cuadrícula", "Movimiento", "Cortar (oscuro)", "Línea lateral", "Ion (oscuro)", "Ion (claro)", "Integral", "Con bandas") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alfabeto", "Anual", "Austero", "Austin", "Conservador", "Contraste", "Cuadrícula", "Cubículos", "Exposición", "Línea lateral", "Moderno", "Mosaicos", "Movimiento", "Papel periódico", "Perspectiva", "Pilas", "Puzzle", "Rayas", "Sobrepasar") } } 'fi-' { If($xWordVersion -eq $wdWord2016) { $xArray = ("Filigraani", "Integraali", "Ioni (tumma)", "Ioni (vaalea)", "Opastin", "Pinta", "Retro", "Sektori (tumma)", "Sektori (vaalea)", "Vaihtuvavärinen", "ViewMaster", "Austin", "Kuiskaus", "Liike", "Ruudukko", "Sivussa") } ElseIf($xWordVersion -eq $wdWord2013) { $xArray = ("Filigraani", "Integraali", "Ioni (tumma)", "Ioni (vaalea)", "Opastin", "Pinta", "Retro", "Sektori (tumma)", "Sektori (vaalea)", "Vaihtuvavärinen", "ViewMaster", "Austin", "Kiehkura", "Liike", "Ruudukko", "Sivussa") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Aakkoset", "Askeettinen", "Austin", "Kontrasti", "Laatikot", "Liike", "Liituraita", "Mod", "Osittain peitossa", "Palapeli", "Perinteinen", "Perspektiivi", "Pinot", "Ruudukko", "Ruudut", "Sanomalehtipaperi", "Sivussa", "Vuotuinen", "Ylitys") } } 'fr-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("À bandes", "Austin", "Facette", "Filigrane", "Guide", "Intégrale", "Ion (clair)", "Ion (foncé)", "Lignes latérales", "Quadrillage", "Rétrospective", "Secteur (clair)", "Secteur (foncé)", "Sémaphore", "ViewMaster", "Whisp") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alphabet", "Annuel", "Austère", "Austin", "Blocs empilés", "Classique", "Contraste", "Emplacements de bureau", "Exposition", "Guide", "Ligne latérale", "Moderne", "Mosaïques", "Mots croisés", "Papier journal", "Perspective", "Quadrillage", "Rayures fines", "Transcendant") } } 'nb-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "BevegElse", "Dempet", "Fasett", "Filigran", "Integral", "Ion (lys)", "Ion (mørk)", "Retrospekt", "Rutenett", "Sektor (lys)", "Sektor (mørk)", "Semafor", "Sidelinje", "Stripet", "ViewMaster") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alfabet", "Årlig", "Avistrykk", "Austin", "Avlukker", "BevegElse", "Engasjement", "Enkel", "Fliser", "Konservativ", "Kontrast", "Mod", "Perspektiv", "Puslespill", "Rutenett", "Sidelinje", "Smale striper", "Stabler", "Transcenderende") } } 'nl-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Beweging", "Facet", "Filigraan", "Gestreept", "Integraal", "Ion (donker)", "Ion (licht)", "Raster", "Segment (Light)", "Semafoor", "Slice (donker)", "Spriet", "Terugblik", "Terzijde", "ViewMaster") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Aantrekkelijk", "Alfabet", "Austin", "Bescheiden", "Beweging", "Blikvanger", "Contrast", "Eenvoudig", "Jaarlijks", "Krantenpapier", "Krijtstreep", "Kubussen", "Mod", "Perspectief", "Puzzel", "Raster", "Stapels", "Tegels", "Terzijde") } } 'pt-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Animação", "Austin", "Em Tiras", "Exibição Mestra", "Faceta", "Fatia (Clara)", "Fatia (Escura)", "Filete", "Filigrana", "Grade", "Integral", "Íon (Claro)", "Íon (Escuro)", "Linha Lateral", "Retrospectiva", "Semáforo") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alfabeto", "Animação", "Anual", "Austero", "Austin", "Baias", "Conservador", "Contraste", "Exposição", "Grade", "Ladrilhos", "Linha Lateral", "Listras", "Mod", "Papel Jornal", "Perspectiva", "Pilhas", "Quebra-cabeça", "Transcend") } } 'sv-' { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Band", "Fasett", "Filigran", "Integrerad", "Jon (ljust)", "Jon (mörkt)", "Knippe", "Rutnät", "RörElse", "Sektor (ljus)", "Sektor (mörk)", "Semafor", "Sidlinje", "VisaHuvudsida", "Återblick") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alfabetmönster", "Austin", "Enkelt", "Exponering", "Konservativt", "Kontrast", "Kritstreck", "Kuber", "Perspektiv", "Plattor", "Pussel", "Rutnät", "RörElse", "Sidlinje", "Sobert", "Staplat", "Tidningspapper", "Årligt", "Övergående") } } 'zh-' { If($xWordVersion -eq $wdWord2010 -or $xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("奥斯汀", "边线型", "花丝", "怀旧", "积分", "离子(浅色)", "离子(深色)", "母版型", "平面", "切片(浅色)", "切片(深色)", "丝状", "网格", "镶边", "信号灯", "运动型") } } Default { If($xWordVersion -eq $wdWord2013 -or $xWordVersion -eq $wdWord2016) { $xArray = ("Austin", "Banded", "Facet", "Filigree", "Grid", "Integral", "Ion (Dark)", "Ion (Light)", "Motion", "Retrospect", "Semaphore", "Sideline", "Slice (Dark)", "Slice (Light)", "ViewMaster", "Whisp") } ElseIf($xWordVersion -eq $wdWord2010) { $xArray = ("Alphabet", "Annual", "Austere", "Austin", "Conservative", "Contrast", "Cubicles", "Exposure", "Grid", "Mod", "Motion", "Newsprint", "Perspective", "Pinstripes", "Puzzle", "Sideline", "Stacks", "Tiles", "Transcend") } } } If($xArray -contains $xCP) { $xArray = $Null Return $True } Else { $xArray = $Null Return $False } } Function CheckWordPrereq { If((Test-Path REGISTRY::HKEY_CLASSES_ROOT\Word.Application) -eq $False) { $ErrorActionPreference = $SaveEAPreference Write-Host "`n`n`t`tThis script directly outputs to Microsoft Word, please install Microsoft Word`n`n" Exit } #find out our session (usually "1" except on TS/RDC or Citrix) $SessionID = (Get-Process -PID $PID).SessionId #Find out if winword is running in our session [bool]$wordrunning = ((Get-Process 'WinWord' -ea 0)|?{$_.SessionId -eq $SessionID}) -ne $Null If($wordrunning) { $ErrorActionPreference = $SaveEAPreference Write-Host "`n`n`tPlease close all instances of Microsoft Word before running this report.`n`n" Exit } } Function ValidateCompanyName { [bool]$xResult = Test-RegistryValue "HKCU:\Software\Microsoft\Office\Common\UserInfo" "CompanyName" If($xResult) { Return Get-RegistryValue "HKCU:\Software\Microsoft\Office\Common\UserInfo" "CompanyName" } Else { $xResult = Test-RegistryValue "HKCU:\Software\Microsoft\Office\Common\UserInfo" "Company" If($xResult) { Return Get-RegistryValue "HKCU:\Software\Microsoft\Office\Common\UserInfo" "Company" } Else { Return "" } } } Function Set-DocumentProperty { <# .SYNOPSIS Function to set the Title Page document properties in MS Word .DESCRIPTION Long description .PARAMETER Document Current Document Object .PARAMETER DocProperty Parameter description .PARAMETER Value Parameter description .EXAMPLE Set-DocumentProperty -Document $Script:Doc -DocProperty Title -Value 'MyTitle' .EXAMPLE Set-DocumentProperty -Document $Script:Doc -DocProperty Company -Value 'MyCompany' .EXAMPLE Set-DocumentProperty -Document $Script:Doc -DocProperty Author -Value 'Jim Moyle' .EXAMPLE Set-DocumentProperty -Document $Script:Doc -DocProperty Subject -Value 'MySubjectTitle' .NOTES Function Created by Jim Moyle June 2017 Twitter : @JimMoyle #> param ( [object]$Document, [String]$DocProperty, [string]$Value ) try { $binding = "System.Reflection.BindingFlags" -as [type] $builtInProperties = $Document.BuiltInDocumentProperties $property = [System.__ComObject].invokemember("item", $binding::GetProperty, $null, $BuiltinProperties, $DocProperty) [System.__ComObject].invokemember("value", $binding::SetProperty, $null, $property, $Value) } catch { Write-Warning "Failed to set $DocProperty to $Value" } } Function FindWordDocumentEnd { #return focus to main document $Script:Doc.ActiveWindow.ActivePane.view.SeekView = $wdSeekMainDocument #move to the end of the current document $Script:Selection.EndKey($wdStory,$wdMove) | Out-Null } Function SetupWord { Write-Verbose "$(Get-Date): Setting up Word" # Setup word for output Write-Verbose "$(Get-Date): Create Word comObject." $Script:Word = New-Object -comobject "Word.Application" -EA 0 4>$Null If(!$? -or $Null -eq $Script:Word) { Write-Warning "The Word object could not be created. You may need to repair your Word installation." $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tThe Word object could not be created. You may need to repair your Word installation.`n`n`t`tScript cannot continue.`n`n" Exit } Write-Verbose "$(Get-Date): Determine Word language value" If( ( validStateProp $Script:Word Language Value__ ) ) { [int]$Script:WordLanguageValue = [int]$Script:Word.Language.Value__ } Else { [int]$Script:WordLanguageValue = [int]$Script:Word.Language } If(!($Script:WordLanguageValue -gt -1)) { $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tUnable to determine the Word language value.`n`n`t`tScript cannot continue.`n`n" AbortScript } Write-Verbose "$(Get-Date): Word language value is $($Script:WordLanguageValue)" $Script:WordCultureCode = GetCulture $Script:WordLanguageValue SetWordHashTable $Script:WordCultureCode [int]$Script:WordVersion = [int]$Script:Word.Version If($Script:WordVersion -eq $wdWord2016) { $Script:WordProduct = "Word 2016" } ElseIf($Script:WordVersion -eq $wdWord2013) { $Script:WordProduct = "Word 2013" } ElseIf($Script:WordVersion -eq $wdWord2010) { $Script:WordProduct = "Word 2010" } ElseIf($Script:WordVersion -eq $wdWord2007) { $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tMicrosoft Word 2007 is no longer supported.`n`n`t`tScript will end.`n`n" AbortScript } Else { $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tYou are running an untested or unsupported version of Microsoft Word.`n`n`t`tScript will end.`n`n`t`tPlease send info on your version of Word to webster@carlwebster.com`n`n" AbortScript } #only validate CompanyName if the field is blank If([String]::IsNullOrEmpty($Script:CoName)) { Write-Verbose "$(Get-Date): Company name is blank. Retrieve company name from registry." $TmpName = ValidateCompanyName If([String]::IsNullOrEmpty($TmpName)) { Write-Warning "`n`n`t`tCompany Name is blank so Cover Page will not show a Company Name." Write-Warning "`n`t`tCheck HKCU:\Software\Microsoft\Office\Common\UserInfo for Company or CompanyName value." Write-Warning "`n`t`tYou may want to use the -CompanyName parameter if you need a Company Name on the cover page.`n`n" } Else { $Script:CoName = $TmpName Write-Verbose "$(Get-Date): Updated company name to $($Script:CoName)" } } If($Script:WordCultureCode -ne "en-") { Write-Verbose "$(Get-Date): Check Default Cover Page for $($WordCultureCode)" [bool]$CPChanged = $False Switch ($Script:WordCultureCode) { 'ca-' { If($CoverPage -eq "Sideline") { $CoverPage = "Línia lateral" $CPChanged = $True } } 'da-' { If($CoverPage -eq "Sideline") { $CoverPage = "Sidelinje" $CPChanged = $True } } 'de-' { If($CoverPage -eq "Sideline") { $CoverPage = "Randlinie" $CPChanged = $True } } 'es-' { If($CoverPage -eq "Sideline") { $CoverPage = "Línea lateral" $CPChanged = $True } } 'fi-' { If($CoverPage -eq "Sideline") { $CoverPage = "Sivussa" $CPChanged = $True } } 'fr-' { If($CoverPage -eq "Sideline") { If($Script:WordVersion -eq $wdWord2013 -or $Script:WordVersion -eq $wdWord2016) { $CoverPage = "Lignes latérales" $CPChanged = $True } Else { $CoverPage = "Ligne latérale" $CPChanged = $True } } } 'nb-' { If($CoverPage -eq "Sideline") { $CoverPage = "Sidelinje" $CPChanged = $True } } 'nl-' { If($CoverPage -eq "Sideline") { $CoverPage = "Terzijde" $CPChanged = $True } } 'pt-' { If($CoverPage -eq "Sideline") { $CoverPage = "Linha Lateral" $CPChanged = $True } } 'sv-' { If($CoverPage -eq "Sideline") { $CoverPage = "Sidlinje" $CPChanged = $True } } 'zh-' { If($CoverPage -eq "Sideline") { $CoverPage = "边线型" $CPChanged = $True } } } If($CPChanged) { Write-Verbose "$(Get-Date): Changed Default Cover Page from Sideline to $($CoverPage)" } } Write-Verbose "$(Get-Date): Validate cover page $($CoverPage) for culture code $($Script:WordCultureCode)" [bool]$ValidCP = $False $ValidCP = ValidateCoverPage $Script:WordVersion $CoverPage $Script:WordCultureCode If(!$ValidCP) { $ErrorActionPreference = $SaveEAPreference Write-Verbose "$(Get-Date): Word language value $($Script:WordLanguageValue)" Write-Verbose "$(Get-Date): Culture code $($Script:WordCultureCode)" Write-Error "`n`n`t`tFor $($Script:WordProduct), $($CoverPage) is not a valid Cover Page option.`n`n`t`tScript cannot continue.`n`n" AbortScript } ShowScriptOptions $Script:Word.Visible = $False #http://jdhitsolutions.com/blog/2012/05/san-diego-2012-powershell-deep-dive-slides-and-demos/ #using Jeff's Demo-WordReport.ps1 file for examples Write-Verbose "$(Get-Date): Load Word Templates" [bool]$Script:CoverPagesExist = $False [bool]$BuildingBlocksExist = $False $Script:Word.Templates.LoadBuildingBlocks() #word 2010/2013/2016 $BuildingBlocksCollection = $Script:Word.Templates | Where {$_.name -eq "Built-In Building Blocks.dotx"} Write-Verbose "$(Get-Date): Attempt to load cover page $($CoverPage)" $part = $Null $BuildingBlocksCollection | ForEach{ If ($_.BuildingBlockEntries.Item($CoverPage).Name -eq $CoverPage) { $BuildingBlocks = $_ } } If($Null -ne $BuildingBlocks) { $BuildingBlocksExist = $True Try { $part = $BuildingBlocks.BuildingBlockEntries.Item($CoverPage) } Catch { $part = $Null } If($Null -ne $part) { $Script:CoverPagesExist = $True } } If(!$Script:CoverPagesExist) { Write-Verbose "$(Get-Date): Cover Pages are not installed or the Cover Page $($CoverPage) does not exist." Write-Warning "Cover Pages are not installed or the Cover Page $($CoverPage) does not exist." Write-Warning "This report will not have a Cover Page." } Write-Verbose "$(Get-Date): Create empty word doc" $Script:Doc = $Script:Word.Documents.Add() If($Null -eq $Script:Doc) { Write-Verbose "$(Get-Date): " $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tAn empty Word document could not be created.`n`n`t`tScript cannot continue.`n`n" AbortScript } $Script:Selection = $Script:Word.Selection If($Null -eq $Script:Selection) { Write-Verbose "$(Get-Date): " $ErrorActionPreference = $SaveEAPreference Write-Error "`n`n`t`tAn unknown error happened selecting the entire Word document for default formatting options.`n`n`t`tScript cannot continue.`n`n" AbortScript } #set Default tab stops to 1/2 inch (this line is not from Jeff Hicks) #36 = .50" $Script:Word.ActiveDocument.DefaultTabStop = 36 #Disable Spell and Grammar Check to resolve issue and improve performance (from Pat Coughlin) Write-Verbose "$(Get-Date): Disable grammar and spell checking" #bug reported 1-Apr-2014 by Tim Mangan #save current options first before turning them off $Script:CurrentGrammarOption = $Script:Word.Options.CheckGrammarAsYouType $Script:CurrentSpellingOption = $Script:Word.Options.CheckSpellingAsYouType $Script:Word.Options.CheckGrammarAsYouType = $False $Script:Word.Options.CheckSpellingAsYouType = $False If($BuildingBlocksExist) { #insert new page, getting ready for table of contents Write-Verbose "$(Get-Date): Insert new page, getting ready for table of contents" $part.Insert($Script:Selection.Range,$True) | Out-Null $Script:Selection.InsertNewPage() #table of contents Write-Verbose "$(Get-Date): Table of Contents - $($Script:MyHash.Word_TableOfContents)" $toc = $BuildingBlocks.BuildingBlockEntries.Item($Script:MyHash.Word_TableOfContents) If($Null -eq $toc) { Write-Verbose "$(Get-Date): " Write-Verbose "$(Get-Date): Table of Content - $($Script:MyHash.Word_TableOfContents) could not be retrieved." Write-Warning "This report will not have a Table of Contents." } Else { $toc.insert($Script:Selection.Range,$True) | Out-Null } } Else { Write-Verbose "$(Get-Date): Table of Contents are not installed." Write-Warning "Table of Contents are not installed so this report will not have a Table of Contents." } #set the footer Write-Verbose "$(Get-Date): Set the footer" [string]$footertext = "Report created by $username" #get the footer Write-Verbose "$(Get-Date): Get the footer and format font" $Script:Doc.ActiveWindow.ActivePane.view.SeekView = $wdSeekPrimaryFooter #get the footer and format font $footers = $Script:Doc.Sections.Last.Footers ForEach ($footer in $footers) { If($footer.exists) { $footer.range.Font.name = "Calibri" $footer.range.Font.size = 8 $footer.range.Font.Italic = $True $footer.range.Font.Bold = $True } } #end ForEach Write-Verbose "$(Get-Date): Footer text" $Script:Selection.HeaderFooter.Range.Text = $footerText #add page numbering Write-Verbose "$(Get-Date): Add page numbering" $Script:Selection.HeaderFooter.PageNumbers.Add($wdAlignPageNumberRight) | Out-Null FindWordDocumentEnd Write-Verbose "$(Get-Date):" #end of Jeff Hicks } Function UpdateDocumentProperties { Param([string]$AbstractTitle, [string]$SubjectTitle) #Update document properties If($MSWORD -or $PDF) { If($Script:CoverPagesExist) { Write-Verbose "$(Get-Date): Set Cover Page Properties" #8-Jun-2017 put these 4 items in alpha order Set-DocumentProperty -Document $Script:Doc -DocProperty Author -Value $UserName Set-DocumentProperty -Document $Script:Doc -DocProperty Company -Value $Script:CoName Set-DocumentProperty -Document $Script:Doc -DocProperty Subject -Value $SubjectTitle Set-DocumentProperty -Document $Script:Doc -DocProperty Title -Value $Script:title #Get the Coverpage XML part $cp = $Script:Doc.CustomXMLParts | Where {$_.NamespaceURI -match "coverPageProps$"} #get the abstract XML part $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "Abstract"} #set the text If([String]::IsNullOrEmpty($Script:CoName)) { [string]$abstract = $AbstractTitle } Else { [string]$abstract = "$($AbstractTitle) for $($Script:CoName)" } $ab.Text = $abstract $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "CompanyAddress"} #set the text [string]$abstract = $CompanyAddress $ab.Text = $abstract $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "CompanyEmail"} #set the text [string]$abstract = $CompanyEmail $ab.Text = $abstract $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "CompanyFax"} #set the text [string]$abstract = $CompanyFax $ab.Text = $abstract $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "CompanyPhone"} #set the text [string]$abstract = $CompanyPhone $ab.Text = $abstract $ab = $cp.documentelement.ChildNodes | Where {$_.basename -eq "PublishDate"} #set the text [string]$abstract = (Get-Date -Format d).ToString() $ab.Text = $abstract Write-Verbose "$(Get-Date): Update the Table of Contents" #update the Table of Contents $Script:Doc.TablesOfContents.item(1).Update() $cp = $Null $ab = $Null $abstract = $Null } } } #endregion #region registry functions #http://stackoverflow.com/questions/5648931/test-if-registry-value-exists # This Function just gets $True or $False Function Test-RegistryValue($path, $name) { $key = Get-Item -LiteralPath $path -EA 0 $key -and $Null -ne $key.GetValue($name, $Null) } # Gets the specified registry value or $Null if it is missing Function Get-RegistryValue($path, $name) { $key = Get-Item -LiteralPath $path -EA 0 If($key) { $key.GetValue($name, $Null) } Else { $Null } } #endregion #region word, text and html line output functions Function line #function created by Michael B. Smith, Exchange MVP #@essentialexchange on Twitter #http://TheEssentialExchange.com #for creating the formatted text report { Param( [int]$tabs = 0, [string]$name = '', [string]$value = '', [string]$newline = "`r`n", [switch]$nonewline ) While( $tabs -gt 0 ) { $Global:Output += "`t"; $tabs--; } If( $nonewline ) { $Global:Output += $name + $value } Else { $Global:Output += $name + $value + $newline } } Function WriteWordLine #Function created by Ryan Revord #@rsrevord on Twitter #Function created to make output to Word easy in this script { Param([int]$style=0, [int]$tabs = 0, [string]$name = '', [string]$value = '', [string]$fontName=$Null, [int]$fontSize=0, [bool]$italics=$False, [bool]$boldface=$False, [Switch]$nonewline) #Build output style [string]$output = "" Switch ($style) { 0 {$Script:Selection.Style = $Script:MyHash.Word_NoSpacing} 1 {$Script:Selection.Style = $Script:MyHash.Word_Heading1} 2 {$Script:Selection.Style = $Script:MyHash.Word_Heading2} 3 {$Script:Selection.Style = $Script:MyHash.Word_Heading3} 4 {$Script:Selection.Style = $Script:MyHash.Word_Heading4} Default {$Script:Selection.Style = $Script:MyHash.Word_NoSpacing} } #build # of tabs While($tabs -gt 0) { $output += "`t"; $tabs--; } If(![String]::IsNullOrEmpty($fontName)) { $Script:Selection.Font.name = $fontName } If($fontSize -ne 0) { $Script:Selection.Font.size = $fontSize } If($italics -eq $True) { $Script:Selection.Font.Italic = $True } If($boldface -eq $True) { $Script:Selection.Font.Bold = $True } #output the rest of the parameters. $output += $name + $value $Script:Selection.TypeText($output) #test for new WriteWordLine 0. If($nonewline) { # Do nothing. } Else { $Script:Selection.TypeParagraph() } } #*********************************************************************************************************** # WriteHTMLLine #*********************************************************************************************************** <# .Synopsis Writes a line of output for HTML output .DESCRIPTION This function formats an HTML line .USAGE WriteHTMLLine