@echo off
SETLOCAL EnableDelayedExpansion

set output_dir=send_for_investigation
mkdir %output_dir%
set out_file=%output_dir%\clm_diagnosis.txt
set out_file_wmi_ethernet=%output_dir%\clm_wmic_ethernet.txt
set out_file_wmi_disks=%output_dir%\clm_wmic_disks.txt

if %PROCESSOR_ARCHITECTURE%=="x86" (
  set port_scanner_dir=scanner32
  set program_files_dir=%ProgramFiles(x86)%
) else (
  set port_scanner_dir=scanner64
  set program_files_dir=%ProgramFiles%
)

echo %DATE% %TIME% >> %out_file%
call :get_clm_version
call :check_certificates
call :check_services
call :check_ports
call :check_trusted_storage

call :tee collecting information for CLM analysis
call :license_scanner
REM call :copy_log_files
REM call :copy_events
call :get_system_info
call :get_wmic_info
call :copy_TS

exit /b 0


:tee
echo %*
echo %* >> %out_file%
exit /b 0


:tee_new_line
echo.
echo. >> %out_file%
exit /b 0


:check_services
call :tee "SERVICES STATUS"
for %%A in ("FLEXnet License Server","FlexNet Licensing Service","lgs-clmrdsvr","FlexNet Licensing Service 64", "Winmgmt") do (
	call :check_service %%A
)
call :tee_new_line
exit /b 0


:check_service
set service="%~1"
sc query !service! > nul && (
	for /F "tokens=3 delims=: " %%B in ('sc query !service! ^| findstr "STATE"') do (
		call :tee "%service% is %%B"
		if "%%B" NEQ "RUNNING" ( 
			call :tee ERROR: !SERVICE! is not in running state
		)
	)
) || (
	if !ERRORLEVEL!==1060 (
		call :tee "!service! service is not installed"
	) else (
		call :tee "!service! service - ERROR !ERRORLEVEL! while getting service information information"
	)	
)
exit /b 0


:check_ports
call :tee PORTS STATUS
set used_ports=19701 2700[1-9] 27010
for /f "tokens=3 usebackq delims=: " %%p in (`netstat -na -p tcp ^| findstr /R LISTENING$ ^| findstr /R /C:19701.*[0-9]\. /C:2700[1-9].*[0-9]\. /C:27010.*[0-9]\.`) do (
	set listening_ports=!listening_ports! %%p
)
call :tee "the following ports are in listening state: !listening_ports!"
for %%p in (%used_ports%) do ( 
	echo !listening_ports! | findstr /R /C:%%p > nul || ( call :tee port %%p is not in LISTENING state )
)
call :tee_new_line
exit /b 0


:check_trusted_storage
call :tee checking trusted storage
call :get_log_file_path
for /f "tokens=* usebackq delims= " %%p in (`findstr /C:"Is TS accessed: " c:\Users\Public\Documents\CLM-LogFiles\lgs.log`) do (
 set is_ts_accessed=%%p
 )
call :tee %is_ts_accessed%
call :tee_new_line
exit /b 0


:get_clm_version
call :tee getting CLM version
set clm_installation_path="c:\\%program_files_dir:~1,-1%\\Leica Geosystems\\CLM-Administration\\clmadminsvr.exe"
for /F "usebackq tokens=2 delims==" %%A in (`"WMIC DATAFILE WHERE name='!clm_installation_path:~1,-1!' get Version /format:Textvaluelist | findstr Version"`) do (
	set clm_version=%%A
	call :tee !clm_version!
)
call :tee_new_line
exit /b 0


:check_certificates
call :tee checking digital signatures
set base_path=%ProgramFiles(x86)%\Common Files\Leica Geosystems\License-Server
set lgs_exe=%base_path%\LGS.exe
set updatecheck_exe=%base_path%\UpdateCheck.exe

call :verify_certificate "!lgs_exe!" "LGS.exe"
call :verify_certificate "!updatecheck_exe!" "UpdateCheck.exe"

call :tee_new_line
exit /b 0


:verify_certificate
set exe_path=%~1
set exe_name=%~2

if exist "!exe_path!" (
	call :tee checking %exe_name% certificate
	
	REM Try to use PowerShell to verify certificate
	powershell -NoProfile -ExecutionPolicy Bypass -Command "Import-Module Microsoft.PowerShell.Security; $sig = Get-AuthenticodeSignature -FilePath '!exe_path!'; if ($sig.Status -eq 'Valid') { exit 0 } else { exit 1 }" > nul 2>&1
	
	if !ERRORLEVEL! EQU 0 (
		call :tee Certificate Validation Succeeded for %exe_name%
		powershell -NoProfile -ExecutionPolicy Bypass -Command "Import-Module Microsoft.PowerShell.Security; $sig = Get-AuthenticodeSignature -FilePath '!exe_path!'; Write-Host ('Subject: ' + $sig.SignerCertificate.Subject); Write-Host ('Issuer: ' + $sig.SignerCertificate.Issuer); Write-Host ('NotBefore: ' + $sig.SignerCertificate.NotBefore); Write-Host ('NotAfter: ' + $sig.SignerCertificate.NotAfter); Write-Host ('Thumbprint: ' + $sig.SignerCertificate.Thumbprint)" >> %out_file% 2>&1
		if !ERRORLEVEL! NEQ 0 (
			call :tee Certificate details cannot be retrieved
		)
	) else if !ERRORLEVEL! EQU 1 (
		call :tee Certificate Validation Failed for %exe_name%
		powershell -NoProfile -ExecutionPolicy Bypass -Command "Import-Module Microsoft.PowerShell.Security; $sig = Get-AuthenticodeSignature -FilePath '!exe_path!'; Write-Host ('Status: ' + $sig.Status); Write-Host ('StatusMessage: ' + $sig.StatusMessage)" >> %out_file% 2>&1
	) else (
		call :tee Certification cannot be verified - PowerShell execution failed
		echo Certification cannot be verified - PowerShell execution failed >> %out_file%
	)
	echo.
	echo. >> %out_file%
) else (
	call :tee %exe_name% not found at "!exe_path!"
	echo.
	echo. >> %out_file%
)
exit /b 0


:license_scanner
call :tee running the license scanner
!port_scanner_dir!\LicensingScanner.exe >> %out_file%
echo. >> %out_file%
exit /b 0


:copy_log_files
call :tee copying log files
robocopy /e "c:\Users\Public\Documents\CLM-LogFiles" %output_dir%\CLM-LogFiles_2_x > nul
robocopy /e "c:\Leica Geosystems\CLM\LogFiles" %output_dir%\CLM-LogFiles_1_8 > nul
echo. >> %out_file%
exit /b 0 

:copy_events
call :tee copying event files
wevtutil epl Application %output_dir%\application.evtx
wevtutil epl System %output_dir%\system.evtx
echo. >> %out_file%
exit /b 0 

:copy_TS
call :tee copying TS files
md %output_dir%\TS
robocopy /e "c:\ProgramData\FLEXnet" %output_dir%\TS > nul
echo. >> %out_file%
exit /b 0 


:get_system_info
call :tee getting system info
echo SYSTEM INFORMATION >> %out_file%
systeminfo >> %out_file%
echo. >> %out_file%
exit /b 0

REM NetConnectionStatus:
REM Disconnected (0)
REM Connecting (1)
REM Connected (2)
REM Disconnecting (3)
REM Hardware Not Present (4)
REM Hardware Disabled (5)
REM Hardware Malfunction (6)
REM Media Disconnected (7)
REM Authenticating (8)
REM Authentication Succeeded (9)
REM Authentication Failed (10)
REM Invalid Address (11)
REM Credentials Required (12)

:get_wmic_info
call :tee getting wmic info
call wmic /OUTPUT:%out_file_wmi_disks% diskdrive get model,serialNumber,size,mediaType,deviceID
call wmic /OUTPUT:%out_file_wmi_ethernet% path Win32_NetworkAdapter get name,MacAddress,NetConnectionID,NetConnectionStatus,NetEnabled,PhysicalAdapter
echo. >> %out_file%
exit /b 0