Private/wordFunctions.ps1

$wdAlignPageNumberLeft   = 0
$wdAlignPageNumberCenter = 1
$wdAlignPageNumberRight  = 2

$wdPageNumberStyleArabic = 0
$wdPageNumberStyleUppercaseRoman = 1
$wdPageNumberStyleLowercaseRoman = 2
$wdPageNumberStyleUppercaseLetter = 3
$wdPageNumberStyleLowercaseLetter = 4

$wdAlignParagraphLeft    = 0
$wdAlignParagraphCenter  = 1
$wdAlignParagraphRight   = 2
$wdAlignParagraphJustify = 3

function Set-WordFormatting {
    Write-Log -Message "function... Set-WordFormatting ****" -LogFile $logfile
    if ($WordVersion -ge "16.0") {
        Write-Log -Message "setting styles for Word 2016" -LogFile $logfile
        $x1 = "Grid Table 4 - Accent 1"
        $x2 = "Grid Table 4 - Accent 1"
    } elseif ($WordVersion -eq "15.0") {
        Write-Log -Message "setting styles for Word 2013" -LogFile $logfile
        $x1 = "Grid Table 4 - Accent 1"
        $x2 = "Grid Table 4 - Accent 1"
    } elseif ($WordVersion -eq "14.0") {
        Write-Log -Message "setting styles for Word 2010" -LogFile $logfile
        $x1 = "Medium Shading 1 - Accent 1"
        $x2 = "Light Grid - Accent 1"
    }
    Write-Output @($x1, $x2)
}
function Set-WordAbstract {
    $absText1 = "This document provides a point-in-time report of the current state of the "
    $absText1 += "System Center Configuration Manager site environment for $CustomerName. "
    $absText1 += "For questions, concerns or comments, please consult the author of this "
    $absText1 += "assessment report."
    $absText2 = "This report was generated using CMHealthCheck $ModuleVer on $(Get-Date)."

    Write-WordText -WordSelection $selection -Text "Abstract" -Style "Heading 1" -NewLine $true
    Write-WordText -WordSelection $selection -Text $absText1 -NewLine $true
    Write-WordText -WordSelection $selection -Text $absText2 -NewLine $true
}

function Set-WordOptions {
    Write-Log -Message "configuring word options for current session" -LogFile $logfile
    $Word.Options.CheckGrammarAsYouType  = $False
    $Word.Options.CheckSpellingAsYouType = $False
    $Doc.Styles("Normal").Font.Size = $NormalFontSize
}

function Set-WordTOC {
    Write-Log -Message "inserting table of contents" -LogFile $logfile
    $toc = $BuildingBlocks.BuildingBlockEntries.Item("Automatic Table 2")
    $toc.Insert($selection.Range,$True) | Out-Null
}

function Set-WordFooter {
    Write-Log -Message "writing document footer content..."
    if ($Template -eq "") {
        $selection.HeaderFooter.Range.Text= "Copyright $([char]0x00A9) $((Get-Date).Year) - $CopyrightName"
    }
    $selection.HeaderFooter.PageNumbers.Add($wdAlignPageNumberRight) | Out-Null
}

function Write-WordText {
    param (
        [parameter()] $WordSelection,
        [parameter()][string] $Text = "",
        [parameter()][string] $Style = "Normal",
        [parameter()] $Bold    = $false,
        [parameter()] $NewLine = $false,
        [parameter()] $NewPage = $false
    )
    Write-Log -Message "(Write-WordText)" -LogFile $logfile
    $texttowrite = ""
    $wordselection.Style = $Style
    if ($bold) {
        $wordselection.Font.Bold = 1
    } else {
        $wordselection.Font.Bold = 0
    }
    $texttowrite += $text
    $wordselection.TypeText($text)
    If ($newline) { $wordselection.TypeParagraph() }
    If ($newpage) { $wordselection.InsertNewPage() }
}

function Set-WordDocumentProperty {
    param (
        [parameter(Mandatory)] $Document,
        [parameter(Mandatory)] [string] $Name,
        [parameter(Mandatory)] [string] $Value
    )
    Write-Log -Message "info: document property [$Name] set to [$Value]" -LogFile $logfile
    $document.BuiltInDocumentProperties($Name) = $Value
}

function Set-DocAppendix {
    param ()
    Write-Log -Message "(Set-DocAppendix)" -LogFile $logfile
    $appendix = @(
        ("ConfigMgr Hardware Recommendations", "https://technet.microsoft.com/en-us/library/mt589500.aspx#bkmk_ScaleSieSystems"),
        ("ConfigMgr Supported Operating Systems", "https://docs.microsoft.com/en-us/sccm/core/plan-design/configs/supported-operating-systems-for-site-system-servers"),
        ("ConfigMgr Supported SQL Server Versions", "https://docs.microsoft.com/en-us/sccm/core/plan-design/configs/support-for-sql-server-versions"),
        ("ConfigMgr Internet-Based Client Management", "https://docs.microsoft.com/en-us/sccm/core/clients/manage/plan-internet-based-client-management"),
        ("ConfigMgr Site Size and Scale Information", "https://docs.microsoft.com/en-us/sccm/core/plan-design/configs/size-and-scale-numbers"),
        ("ConfigMgr Support Lifecycle Information", "https://support.microsoft.com/en-us/lifecycle/search?alpha=Microsoft%20System%20Center%202012%20Configuration%20Manager"),
        ("ConfigMgr Client Installation Properties", "https://docs.microsoft.com/en-us/sccm/core/clients/deploy/about-client-installation-properties"),
        ("Best Practices for Managing Software Updates", "https://docs.microsoft.com/en-us/sccm/sum/plan-design/software-updates-best-practices"),
        ("Deploy Windows 10 with MDT", "https://docs.microsoft.com/en-us/windows/deployment/deploy-windows-mdt/deploy-windows-10-with-the-microsoft-deployment-toolkit"),
        ("Blogs - WindowsNoob", "https://www.windows-noob.com/forums/portal"),
        ("Blogs - Deployment Research", "https://deploymentresearch.com/"),
        ("Blogs - SC ConfigMgr", "https://www.scconfigmgr.com")
    )
    
    Write-Log -Message "inserting document Appendix..." -LogFile $logfile
    Write-WordText -WordSelection $selection -Text "Appendix A - Resource References" -Style "Heading 1" -NewLine $true
    $selection.TypeParagraph()

    foreach ($app in $appendix) {
        $caption = $app[0]
        $link = $app[1]
        Write-WordText -WordSelection $selection -Text $caption -NewLine $true
        Write-WordText -WordSelection $selection -Text $link -NewLine $true
        $selection.TypeParagraph()
    }
}

function Set-DocProperties {
    Write-Log -Message "(Set-DocProperties)" -LogFile $logfile
    if ($bAutoProps -eq $True) {
        Write-Log -Message "setting document properties" -LogFile $logfile
        $doc.BuiltInDocumentProperties("Title")    = "System Center Configuration Manager HealthCheck"
        $doc.BuiltInDocumentProperties("Subject")  = "Prepared for $CustomerName"
        $doc.BuiltInDocumentProperties("Author")   = $AuthorName
        $doc.BuiltInDocumentProperties("Company")  = $CopyrightName
        $doc.BuiltInDocumentProperties("Category") = "REPORTS"
        $doc.BuiltInDocumentProperties("Keywords") = "sccm,healthcheck,systemcenter,configmgr,$CustomerName"
    }
}

function Write-DocReportSections {
    Write-Log -Message "(Write-DocReportSections)" -LogFile $logfile 
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -section '1' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -section '2' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -section '3' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -section '4' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -section '5' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    
    if ($detailed -eq $true) {
        Write-WordReportSection -HealthCheckXML $HealthCheckXML -Section '5' -Detailed $true -Doc $doc -Selection $selection -LogFile $logfile 
        Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
    }
    
    Write-WordReportSection -HealthCheckXML $HealthCheckXML -Section '6' -Doc $doc -Selection $selection -LogFile $logfile 
    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
}

Function Write-WordReportSection {
    param (
        [parameter()] $HealthCheckXML,
        [parameter()] $Section,
        [parameter()] $Detailed = $false,
        [parameter()] $Doc,
        [parameter()] $Selection,
        [parameter()] $LogFile
    )
    Write-Log -Message "(Write-WordReportSection)" -LogFile $logfile
    Write-Log -Message "section....... $section" -LogFile $logfile
    Write-Log -Message "detail........ $($detailed.ToString())" -LogFile $logfile

    foreach ($healthCheck in $HealthCheckXML.dtsHealthCheck.HealthCheck) {
        if ($healthCheck.Section.ToLower() -ne $Section) { continue }
        $Description = $healthCheck.Description -replace("@@NumberOfDays@@", $NumberOfDays)
        if ($healthCheck.IsActive.ToLower() -ne 'true') { continue }
        if ($healthCheck.IsTextOnly.ToLower() -eq 'true') {
            if ($Section -eq 5) {
                if ($detailed -eq $false) {
                    $Description += " - Overview"
                } else {
                    $Description += " - Detailed"
                }
            }
            Write-WordText -WordSelection $selection -Text $Description -Style $healthCheck.WordStyle -NewLine $true
            Continue;
        }
        Write-Log -Message "description... $Description" -LogFile $logfile
        Write-WordText -WordSelection $selection -Text $Description -Style $healthCheck.WordStyle -NewLine $true
        $bFound = $false
        $tableName = $healthCheck.XMLFile
        if ($Section -eq 5) {
            if (!($detailed)) {
                $tablename += "summary"
            } else {
                $tablename += "detail"
            }
        }
        foreach ($rp in $ReportTable) {
            if ($rp.TableName -eq $tableName) {
                $bFound = $true
                $filename = $rp.XMLFile
                Write-Log -Message "xmlfile....... $filename" -LogFile $logfile
                if ($filename.IndexOf("_") -gt 0) {
                    $xmltitle = $filename.Substring(0,$filename.IndexOf("_"))
                    $xmltile = ($rp.TableName.Substring(0,$rp.TableName.IndexOf("_")).Replace("@","")).Tolower()
                    switch ($xmltile) {
                        "sitecode"   { $xmltile = "Site Code: " }
                        "servername" { $xmltile = "Server Name: " }
                    }
                    switch ($healthCheck.WordStyle) {
                        "Heading 1" { $newstyle = "Heading 2" }
                        "Heading 2" { $newstyle = "Heading 3" }
                        "Heading 3" { $newstyle = "Heading 4" }
                        default { $newstyle = $healthCheck.WordStyle }
                    }
                    $xmltile += $filename.Substring(0,$filename.IndexOf("_"))
                    Write-WordText -WordSelection $selection -Text $xmltile -Style $newstyle -NewLine $true
                }
                if (!(Test-Path ($reportFolder + $filename))) {
                    Write-WordText -WordSelection $selection -Text $healthCheck.EmptyText -NewLine $true
                    Write-Log -Message "Table does not exist" -LogFile $logfile -Severity 2
                    $selection.TypeParagraph()
                } else {
                    #Write-Log -Message "importing XML file: $filename" -LogFile $logfile
                    $datatable = Import-CliXml -Path ($reportFolder + $filename)
                    $count = 0
                    $datatable | Where-Object { $count++ }
                    if ($count -eq 0) {
                        Write-WordText -WordSelection $selection -Text $healthCheck.EmptyText -NewLine $true
                        Write-Log -Message "Table......... 0 rows" -LogFile $logfile -Severity 2
                        $selection.TypeParagraph()
                        continue
                    }
                    switch ($healthCheck.PrintType.ToLower()) {
                        "table" {
                            Write-Log -Message "table type.... table" -LogFile $logfile
                            $Table = $Null
                            $TableRange = $Null
                            $TableRange = $doc.Application.Selection.Range
                            $Columns = 0
                            foreach ($field in $HealthCheck.Fields.Field) {
                                if ($section -eq 5) {
                                    if (($detailed) -and ($field.groupby -notin ('1','2'))) { continue }
                                    elseif ((!($detailed)) -and ($field.groupby -notin ('2','3'))) { continue }
                                }
                                $Columns++
                            } # foreach
                            $Table = $doc.Tables.Add($TableRange, $count+1, $Columns)
                            Write-Log -Message "table style... $TableStyle" -LogFile $logfile
                            $table.Style = $TableStyle
                            # added to force table width consistency in 1.0.4 (Issue 13)
                            $table.PreferredWidthType = 2
                            $table.PreferredWidth = 100
                            $i = 1;
                            Write-Log -Message "structure..... $count rows and $Columns columns" -LogFile $logfile
                            Write-Log -Message "writing table column headings..." -LogFile $logfile
                            foreach ($field in $HealthCheck.Fields.Field) {
                                if ($section -eq 5) {
                                    if (($detailed) -and ($field.groupby -notin ('1','2'))) { continue }
                                    elseif ((!($detailed)) -and ($field.groupby -notin ('2','3'))) { continue }
                                }
                                $Table.Cell(1, $i).Range.Font.Bold = $True
                                $Table.Cell(1, $i).Range.Text = $field.Description
                                #Write-Log -Message "--column: $($field.Description)" -LogFile $logfile
                                $i++
                            } # foreach
                            $xRow = 2
                            $records = 1
                            $y=0
                            Write-Log -Message "writing data rows for table body..." -LogFile $logfile
                            foreach ($row in $datatable) {
                                if ($records -ge 500) {
                                    Write-Log -Message ("Exported..... $(500*($y+1)) records") -LogFile $logfile
                                    $records = 1
                                    $y++
                                }
                                $i = 1;
                                foreach ($field in $HealthCheck.Fields.Field) {
                                    if ($section -eq 5) {
                                        if (($detailed) -and ($field.groupby -notin ('1','2'))) { continue }
                                        elseif ((!($detailed)) -and ($field.groupby -notin ('2','3'))) { continue }
                                    }
                                    $Table.Cell($xRow, $i).Range.Font.Bold = $false
                                    $TextToWord = "";
                                    switch ($field.Format.ToLower()) {
                                        "message" {
                                            $TextToWord = Get-MessageInformation -MessageID ($row.$($field.FieldName))
                                        }
                                        "messagesolution" {
                                            $TextToWord = Get-MessageSolution -MessageID ($row.$($field.FieldName))
                                        }
                                        default {
                                            $TextToWord = $row.$($field.FieldName);
                                        }
                                    }
                                    #Write-Log -Message "--value: $($TextToWord.ToString())" -LogFile $logfile
                                    if ([string]::IsNullOrEmpty($TextToWord)) {
                                        $TextToWord = " "
                                        $val = " "
                                    } elseif (Test-Numeric $TextToWord) {
                                        #Write-Log -Message "rounding numeric value precision" -LogFile $logfile
                                        $val = ([math]::Round($TextToWord,2)).ToString()
                                    } else {
                                        $val = $TextToWord.ToString()
                                    }
                                    $Table.Cell($xRow, $i).Range.Text = $val
                                    $i++
                                } # foreach
                                $xRow++
                                $records++
                            } # foreach
                            $selection.EndOf(15) | Out-Null
                            $selection.MoveDown() | Out-Null
                            $doc.ActiveWindow.ActivePane.view.SeekView = 0
                            $selection.EndKey(6, 0) | Out-Null
                            if ($count -gt 2) {
                                Write-Verbose "SORT OPERATION - SORTING TABLE"
                                $Tables.Sort
                                Write-Log -Message "NEW: appending row count label below table" -LogFile $logfile
                                Write-WordText -WordSelection $selection -Text "$count items found" -Style "Normal" -NewLine $true
                                $selection.TypeParagraph()
                            }
                            $selection.TypeParagraph()
                        }
                        "simpletable" {
                            Write-Log -Message "table type.... simpletable" -LogFile $logfile
                            $Table = $Null
                            $TableRange = $Null
                            $TableRange = $doc.Application.Selection.Range
                            $Columns = 0
                            foreach ($field in $HealthCheck.Fields.Field) {
                                if ($section -eq 5) {
                                    if (($detailed) -and ($field.groupby -notin ('1','2'))) { continue }
                                    elseif ((!($detailed)) -and ($field.groupby -notin ('2','3'))) { continue }
                                }
                                $Columns++
                            } # foreach
                            $Table = $doc.Tables.Add($TableRange, $Columns, 2)
                            $table.Style = $TableSimpleStyle
                            # added to force table width consistency in 1.0.4 (Issue 13)
                            $table.PreferredWidthType = 2
                            $table.PreferredWidth = 100
                            $i = 1;
                            Write-Log -Message "structure..... $Columns rows and 2 columns" -LogFile $logfile
                            $records = 1
                            $y=0
                            foreach ($field in $HealthCheck.Fields.Field) {
                                if ($section -eq 5) {
                                    if (($detailed) -and ($field.groupby -notin ('1','2'))) { continue }
                                    elseif ((!($detailed)) -and ($field.groupby -notin ('2','3'))) { continue }
                                }
                                if ($records -ge 500) {
                                    Write-Log -Message ("Exported..... $(500*($y+1)) records") -LogFile $logfile
                                    $records = 1
                                    $y++
                                }
                                $Table.Cell($i, 1).Range.Font.Bold = $true
                                $Table.Cell($i, 1).Range.Text = $field.Description
                                $Table.Cell($i, 2).Range.Font.Bold = $false
                                if ($poshversion -ne 3) {
                                    $TextToWord = "";
                                    switch ($field.Format.ToLower()) {
                                        "message" {
                                            $TextToWord = Get-MessageInformation -MessageID ($datatable.Rows[0].$($field.FieldName))
                                        }
                                        "messagesolution" {
                                            $TextToWord = Get-MessageSolution -MessageID ($datatable.Rows[0].$($field.FieldName))
                                        }
                                        default {
                                            $TextToWord = $datatable.Rows[0].$($field.FieldName)
                                        }
                                    } # switch
                                    if ([string]::IsNullOrEmpty($TextToWord)) { $TextToWord = " " }
                                    $Table.Cell($i, 2).Range.Text = $TextToWord.ToString()
                                } else {
                                    $TextToWord = "";
                                    switch ($field.Format.ToLower()) {
                                        "message" {
                                            $TextToWord = Get-MessageInformation -MessageID ($datatable.$($field.FieldName))
                                        }
                                        "messagesolution" {
                                            $TextToWord = Get-MessageSolution -MessageID ($datatable.$($field.FieldName))
                                        }
                                        default {
                                            $TextToWord = $datatable.$($field.FieldName)
                                        }
                                    } # switch
                                    if ([string]::IsNullOrEmpty($TextToWord)) { $TextToWord = " " }
                                    $Table.Cell($i, 2).Range.Text = $TextToWord.ToString()
                                }
                                $i++
                                $records++
                            } # foreach
                            $selection.EndOf(15) | Out-Null
                            $selection.MoveDown() | Out-Null
                            $doc.ActiveWindow.ActivePane.View.SeekView = 0
                            $selection.EndKey(6, 0) | Out-Null
                            $selection.TypeParagraph()
                        }
                        default {
                            Write-Log -Message "table type.... default" -LogFile $logfile
                            $records = 1
                            $y=0
                            foreach ($row in $datatable) {
                                if ($records -ge 500) {
                                    Write-Log -Message ("Exported...... $(500*($y+1)) records") -LogFile $logfile
                                    $records = 1
                                    $y++
                                }
                                foreach ($field in $HealthCheck.Fields.Field) {
                                    $TextToWord = "";
                                    switch ($field.Format.ToLower()) {
                                        "message" {
                                            $TextToWord = ($field.Description + " : " + (Get-MessageInformation -MessageID ($row.$($field.FieldName))))
                                        }
                                        "messagesolution" {
                                            $TextToWord = ($field.Description + " : " + (Get-MessageSolution -MessageID ($row.$($field.FieldName))))
                                        }
                                        default {
                                            $TextToWord = ($field.Description + " : " + $row.$($field.FieldName))
                                        }
                                    } # switch
                                    if ([string]::IsNullOrEmpty($TextToWord)) { $TextToWord = " " }
                                    Write-WordText -WordSelection $selection -Text ($TextToWord.ToString()) -NewLine $true
                                } # foreach
                                $selection.TypeParagraph()
                                $records++
                            } # foreach
                        } # end of default switch case
                    } # switch
                    Write-WordTableGrid -Caption "Review Comments" -Rows 3 -ColumnHeadings $ReviewTableCols -StyleName $ReviewTableStyle
                }
            }
        } # foreach
        if ($bFound -eq $false) {
            Write-WordText -WordSelection $selection -Text $healthCheck.EmptyText -NewLine $true
            Write-Log -Message ("Table does not exist") -LogFile $logfile -Severity 2
            $selection.TypeParagraph()
        }
    } # foreach
}

function Write-WordTableGrid {
    param (
        [parameter(Mandatory)][string] $Caption,
        [parameter(Mandatory)][int] $Rows,
        [parameter(Mandatory)][string[]] $ColumnHeadings,
        [parameter()][string] $StyleName = $DefaultTableStyle
    )
    Write-Log -Message "(Write-WordTableGrid) Caption = $Caption" -LogFile $logfile
    $Selection.TypeText($Caption)
    if ($Caption -eq 'Review Comments') {
        $Selection.Style = "Heading 3"
    } else {
        $Selection.Style = "Heading 1"
    }
    $Selection.TypeParagraph()
    $Cols  = $ColumnHeadings.Length
    $Table = $doc.Tables.Add($Selection.Range, $rows, $cols)
    Write-Log -Message "table style: $StyleName" -LogFile $logfile
    $Table.Style = $StyleName
    for ($col = 1; $col -le $cols; $col++) {
        $Table.Cell(1, $col).Range.Text = $ColumnHeadings[$col-1]
    }
    for ($row = 1; $row -lt $rows; $row++) {
        $Table.Cell($row+1, 1).Range.Text = $row.ToString()
    }
    # set table width to 100%
    $Table.PreferredWidthType = 2
    $Table.PreferredWidth = 100
    # set column widths for more than 2 columns
    if ($cols -gt 2) {
        $Table.Columns.First.PreferredWidthType = 2
        if ($ColumnHeadings[0].length -lt 5) {
            # squeeze first column if heading is "No.", etc.
            $Table.Columns.First.PreferredWIdth = 5
        } else {
            $Table.Columns.First.PreferredWIdth = 7
        }
        $Table.Columns(2).PreferredWidthType = 2
        $Table.Columns(2).PreferredWIdth = 7
    } else {
        # set column widths for 1 or 2 columns only
        $Table.Columns.First.PreferredWidthType = 2
        $Table.Columns.First.PreferredWidth = 7
    }
    $Selection.EndOf(15) | Out-Null
    $Selection.MoveDown() | Out-Null
    $doc.ActiveWindow.ActivePane.view.SeekView = 0
    $Selection.EndKey(6, 0) | Out-Null
    $Selection.TypeParagraph()
}

function Get-WordTempSource {
    <#
    .SYNOPSIS
    Copy Source Document File to Destination
    
    .DESCRIPTION
    Copies a source DOCX file to a temporary name and returns the new filename
    
    .PARAMETER SourceFile
    Path and name of source document file
    
    .EXAMPLE
    $newfile = Get-WordTempSource -SourceFile "c:\files\myfile.docx"
    $newfile == "c:\users\johndoe\documents\cmhealthreport.docx"
    
    .NOTES
    #>

    param (
        [parameter(Mandatory=$True, HelpMessage="Name of Template File")]
        [ValidateNotNullOrEmpty()]
        [string] $SourceFile
    )
    if (Test-Path -Path $SourceFile) {
        $newFile = Join-Path -Path $OutputFolder -ChildPath $TempFilename
        Write-Log -Message "copying source [$Template] to temp file [$newFile]..." -LogFile $logfile
        try {
            Copy-Item -Path $Template -Destination $newFile -ErrorAction Stop
            $result = $True
        } catch {
            Write-Log -Message "ERROR: Failed to clone template from $Template" -Severity 3 -LogFile $logfile
            break
        }
    }
    Write-Output $newFile
}