LANDesk Client Elevated Repair – Proof of Concept

email me

I created a LANDesk Repair tool which can be used by any user to repair, reinstall, and fix issues related to the LANDesk client. The magic part of this is that it uses a public URL to download the LANDesk setup file, and then launches in an elevated mode using Microsoft’s SecureSubstring (the secure part was written in C#).

The advantage of having something like this, versus a package compiled with the LD setup file (172MB), is that the package is much smaller (less than a meg) and—if and when you change the LD setup—there is no need to recompile the package with the updated source file. Just drop the new source file at the URL, and anyone using the Repair Tool will automatically get the updated source file; this works for on site and off site users.

Originally, I just wanted to create a proof-of-concept prototype, but it worked so well, it was implemented.

Screenshot of my HTA

 

' ---------------------------------------------------------------' 
' Author:   Eddie Jackson
' File:     LANDesk_Repair.exe
' Purpose:  To repair or reinstall LANDesk
' Version:  1.0
' Date:     4/11/2017
'
' Usage:    Installed to C:\AFolderOfYourChoice
'           Accessed from Start Menu
' Notes
' Exit codes are 0 success, 1 no source file, 2 failed download
' ---------------------------------------------------------------' 


Option Explicit

'global declarations
Dim varHTTP, varBinaryString, setupFile, setupURL, uninstallFile, ComputerName, CurDir
Dim objShell, oldLANDesk, newLANDesk, msgFile, fso, objWMIService, cmd, colProcesses, Elevate



'Sequencing...
InitializeVariables()
CheckURL()
Download(setupFile)
Verify(setupFile)
Uninstall(oldLANDesk)
Install(newLANDesk)
ExitSequence(0)




sub InitializeVariables()
	on error resume next	
	
	'computer name
	ComputerName = "."

	CurDir = "C:\AFolderOfYourChoice"
	
	'message file
	msgFile = CurDir & "\ldmsg.dat"

	Set objShell = CreateObject("WScript.Shell")
	Set fso = CreateObject("Scripting.FileSystemObject")	
 
	Set varHTTP = CreateObject("Microsoft.XMLHTTP")
	Set varBinaryString = CreateObject("Adodb.Stream")
	
	setupFile = "Client_From_ldlogon_AdvanceAgent_Folder.exe"
	uninstallFile = "UninstallWinClient_From_LANDesk.exe"
	
        'tool I created to do elevation
        Elevate = CurDir & "\Elevate.exe -app" & " "
        'reference: http://eddiejackson.net/wp/?p=13815
	
	oldLANDesk = Elevate & chr(34) & CurDir & "\" & uninstallFile & chr(34) & " " & chr(34) & "/NOREBOOT /FORCECLEAN" & chr(34)
	newLANDesk = Elevate & chr(34) & CurDir & "\" & setupFile & chr(34)
	setupURL = "http://YourGateway_CSA_or_DMZ/" & setupFile

	varHTTP.Open "GET", setupURL, False
	varHTTP.Send
end sub


sub CheckURL()
    on error resume next
	'launch splash	
	Msg("Searching for download file...")	
	Splash()
	
	Select Case Cint(varHTTP.status)		
		Case 200, 202, 302			
			Msg("Found LANDesk download file!")			
			Exit Sub
		Case Else			
			Msg("LANDesk setup could not be found!")			
			ExitSequence(1)
	End Select
end sub


sub Download(dFile)
		on error resume next
		Msg("Downloading LANDesk file...")	
		With varBinaryString
			.Type = 1 'my type has been set to binary
			.Open
			.Write varHTTP.responseBody
			.SaveToFile ".\" & dFile, 2 'if exist, overwrite
		End With
		varBinaryString.close		
		Msg("LANDesk setup has been downloaded...")		
end sub


sub Uninstall(uCommand)
		on error resume next
		Msg("Removing old LANDesk setup...")	
		
		objShell.Run uCommand,0,True
		Wait(20)
		
		Monitor(uninstallFile)	
		Msg("LANDesk has been removed...")
end sub


sub Verify(vDownload)
	on error resume next
	Msg("Verifying file integrity...")
	
	If (fso.FileExists(CurDir & "\" & vDownload)) Then
		Msg("Download was successful!")
	Else
		Msg("Download failed!")
		ExitSequence(2)
	End If

end sub


sub Install(iCommand)
		on error resume next
		Msg("Installing LANDesk Client...")
		
		objShell.Run iCommand,0,True
		Wait(20)
		
		Monitor(setupFile)		
		Msg("LANDesk Client has been installed!")		
end sub


sub Wait(time)
	on error resume next
    time =  time * 1000
	WScript.Sleep time
end sub


sub Monitor(procName)

'secondary method to make sure wait for exit works
		Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2")		
		cmd = 1
		
		Do While cmd = 1			
			Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = '" & procName & "'")
			If colProcesses.Count = 0 Then
				on error resume next
				'Process is not running
				cmd = 0
				Wait(4)
			Else
				'Process is running
				cmd = 1
				Wait(30)		
			End If
		Loop				
end sub


sub Msg(message)
	on error resume next
	objShell.Run "cmd /c echo " & message & ">" & msgFile,0,true
	Wait(4)
end sub


sub Splash()
	on error resume next
	'a simple animation I made (ldhta.exe is mshta.exe)
        'you'll have to create your own little animation here
	objShell.Run CurDir & "\ldhta.exe " &  CurDir & "\ldprogress.hta",9,false
	Wait(8)
end sub


sub ExitSequence(errorcode)	
	Msg("Exiting...")
	Wait(4)
	objShell.Run "taskkill /f /im ldhta.exe",0,true	
	WScript.Quit(errorcode)
end sub