Public/Tools/Invoke-DiagnosticsTool.ps1

function Invoke-DiagnosticsTool {
    <#
    .SYNOPSIS
        Invokes the Milestone Diagnostics Tool utility used for log collection as well as configuration of log levels
    .DESCRIPTION
        The Diagnostics Tool is included in Milestone product installations and a version is also bundled with with
        this module. An attempt is made to ensure the latest version of the Diagnostics Tool is included with this
        module at the time it is published.
 
        The purpose of this cmdlet is to assist those who have a need to automate log collection and is effectively
        a wrapper for the existing Diagnostics Tool command-line parameters.
 
        To simplify the
    .EXAMPLE
        PS C:\> Invoke-DiagnosticsTool -Days 7 -IncludeMiniDumps
        Gather the last 7 days of logs, all the event viewer logs for that period, and any mini memory dumps produced by
        a crashing Milestone software component.
    .EXAMPLE
        PS C:\> $path = Invoke-DiagnosticsTool -EventLog System, Application -PassThru
        Gather the last 30-days of logs, the system and application event logs, and store the fileinfo object representing
        the new ZIP file containing the logs in the $path variable.
    #>

    [CmdletBinding()]
    [OutputType([System.IO.FileInfo])]
    param (
        # Specifies the number of days worth of logs to retrieve, starting from today and going backward. Default is 30 days.
        [Parameter(ParameterSetName = "GetLogs")]
        [ValidateRange(1,([int]::MaxValue))]
        [int]
        $Days = 30,

        # Specifies which Event Viewer logs to collect
        [Parameter()]
        [ValidateSet("All", "Application", "Security", "Setup", "System")]
        [string[]]
        $EventLog = "All",

        # Include a SQL database backup of the Surveillance database. This is only valid when running on a Management Server or Event Server.
        [Parameter(ParameterSetName = "GetLogs")]
        [switch]
        $IncludeDatabase,

        # Include memory dumps of Milestone processes. This can be useful when troubleshooting a problem with crashing, hanging, performance, or high resource utilization.
        [Parameter(ParameterSetName = "GetLogs")]
        [switch]
        $IncludeMiniDumps,

        # Pass the [System.IO.FileInfo] object representing the newly-generated zip file
        [Parameter(ParameterSetName = "GetLogs")]
        [switch]
        $PassThru,

        # Launch the Diagnostics Tool UI instead of running it from the command-line
        [Parameter(ParameterSetName = "ShowUI")]
        [switch]
        $ShowUI,

        # Use the bundled Diagnostics Tool instead of attempting to find the tool in a local product installation
        [Parameter()]
        [switch]
        $UseBundledTool
    )
    
    process {
        # Find Diagnostics Tool.exe by locating either the Management Server or Recording Server installation path
        # And use the bundled version if necessary
        $module = Get-Module -Name MilestonePSTools | Sort-Object Version -Descending | Select-Object -First 1
        $configurationInfo = [pscustomobject]@{ InstallationPath = Join-Path $module.ModuleBase $module.RootModule }
        if (-not $UseBundledTool) {
            $configurationInfo = try {
                $config = Get-ManagementServerConfig
                if ([string]::IsNullOrWhiteSpace($config.InstallationPath)) {
                    throw
                }
                $config
            }
            catch {
                try {
                    $config = Get-RecorderConfig
                    if ([string]::IsNullOrWhiteSpace($config.InstallationPath)) {
                        throw
                    }
                    $config
                }
                catch {
                    $configurationInfo
                }
            }
        }
        if ($null -eq $configurationInfo) {
            Write-Error "Could not find a Management Server or Recording Server installation"
            return
        }
        Write-Verbose "Searching for Diagnostics Tool starting from $($configurationInfo.InstallationPath)"
        $fileInfo = [io.fileinfo]::new($configurationInfo.InstallationPath)
        $exePath = Join-Path $fileInfo.Directory.Parent.FullName "Tools\DiagnosticsTool\Diagnostics Tool.exe"
        if (-not (Test-Path $exePath)) {
            Write-Error "Expected to find Diagnostics Tool at '$exePath'"
            return
        }
        $fileInfo = [io.fileinfo]::new($exePath)
        Write-Verbose "Using Diagnostics Tool located at $($exePath); version $($fileInfo.VersionInfo.FileVersion)"


        if ($ShowUI) {
            Start-Process -FilePath $exePath
            return
        }

        $eventLogOptions = [string]::Join(',', $EventLog)
        $includeDatabaseYN = if ($IncludeDatabase) { "yes" } else { "no" }
        $includeMiniDumpsYN = if ($IncludeDatabase) { "yes" } else { "no" }
        $arguments = @(
            "/logs:$($Days)d",
            "/eventviewer:$($eventLogOptions)",
            "/db:$($includeDatabaseYN)",
            "/includeminidumps:$($includeMiniDumpsYN)"
        )
        $output = Get-ProcessOutput -FilePath $exePath -ArgumentList $arguments
        if ($output.ExitCode -ne 0) {
            Write-Error "Diagnostics Tool exited with code $($output.ExitCode)"
        }
        else {
            $desktop = [io.directoryinfo]::new(([environment]::GetFolderPath(([environment+specialfolder]::Desktop))))
            $diagnosticsPackage = $desktop.GetFiles("Diagnostics*.zip") | Sort-Object -Property CreationTime -Descending | Select-Object -First 1
            if ([environment]::UserInteractive) {
                Write-Verbose "Opening explorer.exe to '$($diagnosticsPackage.FullName)'"
                Start-Process -FilePath explorer.exe -ArgumentList "/e, /select, `"$($diagnosticsPackage.FullName)`""
            }

            if ($PassThru) {
                Write-Output $diagnosticsPackage
            }
        }
    }
}