Zinthose Posted December 18, 2008 Posted December 18, 2008 (edited) HistoryDid you know that since Windows XP, Microsoft has included a remote desktop support system? Most people don't as it is well hidden in the Help and Support and doesn't have a direct executable to start it. Anyone who has used the MSN Messenger remote desktop has seen it but probably thought it was built into MSN Messenger.I decided to see if I can use AutoIt to connect to a remote system and remote assist the user for HelpDesk use. The easy part was identifying the registry values to allow for unsolicited Remote Assistance. I had this part of the code working within a few hours. the hard part was automating the connection to the remote system. At first I was very disappointed with the lack of documentation and was even surprised just how few people attempted this. I found some attempts that involved hacking some of the "htm" files in the %Windows%\PCHealth folder and in my opinion that is too much of a hack and is asking for trouble.I finally identified the com object used, "PCH.HelpService". The remainder of my script is derived from the VBScript posted at LOGINternet Forum and my own touches. RequirmentsTested on Windows XP Pro and Windows XP x64. It should work on Server 2003/2008. I know Vista changed somethings so it will likely not work but I haven't tested it yet.Script must be run with an account that has administrative privileges on the remote systemThird party firewalls might block the connection and will need an exception added or to be disabled entirely for this demoTarget system's user must accept the request before the remote session is allowed. ** There is a way to bypass this but I WILL NOT disclose how due to ethical issues **I hope everyone finds it useful. expandcollapse popup#Include <File.au3> #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <ListboxConstants.au3> Global $__RegistryConnectFailed, $__HelpServiceFailed Exit _Main() Func _Main() Local $HostName = InputBox("ORA", "Enter Hostname to connect to:") ;## Connect to the remote system's Registry hive $Reg = _RegistryConnect($HostName) If @error Then Return 1 ;## Enable Unsolicited Remote Assistance on remote system _EnableRemoteAssist($Reg) If @error Then Return 2 ;## Start Remote Assistance Session _OfferRemoteAssistance($HostName) If @error Then Return 3 ;## Enable Unsolicited Remote Assistance on remote system and close Remote registry connection _DisableRemoteAssist($Reg) If @error Then Return 4 $Reg = Default Return 0 EndFunc #Region ;**** Offer Remote Assistance Functions Func _OfferRemoteAssistance($HostName, $UserID = Default, $UserDomain = Default, $EnablePingTest = True) Local Const $IncidentFileFormat = '<?xml version="1.0" encoding="Unicode" ?><UPLOADINFO TYPE="Escalated"><UPLOADDATA USERNAME="%s" ' & _ 'RCTICKET="%s" RCTICKETENCRYPTED="0" DtStart="0" DtLength="0" IP="%s" Status="Active" URA="1" /></UPLOADINFO>' Local $Ticket, $HelpService, $Session, $Sessions, $i Local $IncidentFile, $Command, $Users = "" ;## Define the Temporary Incident Ticket File and the command to initialize the Remote Assistance Application $IncidentFile = _TempFile() $Command = '"' & @WindowsDir & '\pchealth\helpctr\binaries\helpctr.exe" -Mode "hcp://system/Remote Assistance/raura.xml" ' & _ '-url "hcp://system/Remote Assistance/Interaction/Client/RcToolscreen1.htm" -ExtraArgument "IncidentFile=' & $IncidentFile & '"' ;## Perform a quick ping test to verify the system is online If $EnablePingTest And Ping($HostName) = 0 Then Return SetError(1, 0, False) ;## Connect to Remote system's Help Service $__HelpServiceFailed = ObjEvent("AutoIt.Error", "__HelpServiceFailed") $HelpService = ObjCreate("PCH.HelpService", $HostName) $__HelpServiceFailed = Default ;## Validate If Not IsObj($HelpService) Then Return SetError(2, 0, False) ;## Identify Active User Sessions $Sessions = $HelpService.RemoteUserSessionInfo Select Case $Sessions.Count = 0 $UserID = "" $UserDomain = "" Case $Sessions.Count = 1 $Session = $Sessions.Item(1) $UserID = $Session.UserName $UserDomain = $Session.DomainName Case $Sessions.Count > 1 ;## Get list of Active Users for prompt dropdown list For $i = 1 to $Sessions.Count $Session = $Sessions.Item($i) $Users &= $Session.DomainName & "/" &$Session.UserName & "|" Next $Users = StringTrimRight($Users, 1) ;## Prompt for UserID $SelectedUser = _PromptForUser($Users) If @error Then Return SetError(3, @error, False) ;## Split Domain/User and save for latter use $SelectedUser = StringSplit($SelectedUser, "/") $UserDomain = $SelectedUser[1] $UserID = $SelectedUser[2] Case Else ;## Error! / Unexpected Return SetError(4, 0, False) EndSelect ;## Create Incident Ticket File $Ticket = $HelpService.RemoteConnectionParms($UserID, $UserDomain, -1, "") $IncidentFileXML = StringFormat($IncidentFileFormat, $UserID, $Ticket, $UserDomain) $File = FileOpen($IncidentFile, 42) $RC = FileWrite($File, $IncidentFileXML) FileClose($File) If $RC = 0 Then Return SetError(5, 0, False); <-- ## Bad Unable to create Incident Ticket File ;## Execute / Offer Remote Assistance to the target system $RC = RunWait($Command) If $RC <> 0 Then SetError(6, $RC, False) Return True EndFunc Func __HelpServiceFailed() MsgBox(4096 + 48, @ScriptName, "Unable to connect to the remote system." & @CRLF & @CRLF & _ "Description: " & @TAB & $__HelpServiceFailed.description & @CRLF & _ "Windows description:" & @TAB & $__HelpServiceFailed.windescription & @CRLF & _ "Number: " & @TAB & Hex($__HelpServiceFailed.number,8) & @CRLF & _ "Last DLL Error: " & @TAB & $__HelpServiceFailed.lastdllerror & @CRLF & _ "Scriptline: " & @TAB & $__HelpServiceFailed.scriptline & @CRLF & _ "Source: " & @TAB & $__HelpServiceFailed.source & @CRLF & _ "Help file: " & @TAB & $__HelpServiceFailed.helpfile & @CRLF & _ "Help context: " & @TAB & $__HelpServiceFailed.helpcontext _ ) EndFunc Func _PromptForUser($Users) Local $frmSelectUser, $cmbUser, $lblSelectUser, $cmdCancel, $cmdOK, $msg, $FirstUser, $SelectedUser = Default Local $PrevGUICloseOnESC, $PrevGUIOnEventMode ;## Define dialog Box $PrevGUICloseOnESC = Opt("GUICloseOnESC", 1) $PrevGUIOnEventMode = Opt("GUIOnEventMode", 0) $frmSelectUser = GUICreate("Offer Remote Assistance", 326, 118, -1, -1, _ BitOR($WS_SYSMENU,$WS_CAPTION,$WS_POPUP,$WS_POPUPWINDOW,$WS_BORDER,$WS_CLIPSIBLINGS), _ BitOR($WS_EX_TOPMOST,$WS_EX_WINDOWEDGE)) $cmbUser = GUICtrlCreateCombo("", 12, 48, 301, 25, $CBS_DROPDOWNLIST, $LBS_NOSEL) GUICtrlCreateLabel("Please Select the user you want to offer remote assistance:", 12, 30, 283, 17) GUICtrlCreateLabel("Target system detected to have multiple active user's ", 0, 0, 325, 17, $SS_CENTER) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $cmdCancel = GUICtrlCreateButton("Cancel", 156, 84, 75, 25, 0) $cmdOK = GUICtrlCreateButton("OK", 240, 84, 75, 25, $BS_DEFPUSHBUTTON) GUISetState(@SW_SHOW) ;## Add users to the ComboBox list $Length = StringInStr($Users, "|") - 1 If $Length > 0 Then $FirstUser = StringLeft($Users, $Length) Else $FirstUser = $Users EndIf GUICtrlSetData($cmbUser, $Users, $FirstUser) ;## Wait for it..... While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $cmdCancel ExitLoop Case $cmdOK $SelectedUser = GUICtrlRead($cmbUser) ExitLoop EndSwitch WEnd ;## Clean Up GUI GUIDelete($frmSelectUser) Opt("GUICloseOnESC", $PrevGUICloseOnESC) Opt("GUIOnEventMode", $PrevGUIOnEventMode) ;## Do some value checking and Return If $SelectedUser = Default Then Return SetError(1, 0, False) Return $SelectedUser EndFunc #EndRegion #Region ;**** General Functions Func _Echo($Msg) ConsoleWrite("+ Echo:" & @CRLF & "+ " & $Msg & @CRLF) EndFunc #EndRegion #Region ;**** Registry Functions Func _RegistryConnect($HostName, $EnablePingTest = True) Local $Reg ;## Perform a quick ping test to verify the system is online If $EnablePingTest And Ping($HostName) = 0 Then Return SetError(1, 0, False) ;## Connect to the Remote system's Registry Tree $__RegistryConnectFailed = ObjEvent("AutoIt.Error", "__RegistryConnectFailed") $Reg=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $HostName & "\root\default:StdRegProv") $__RegistryConnectFailed = Default ;## If Not IsObj($Reg) Then Return SetError(2, 0, False) Return $Reg EndFunc Func __RegistryConnectFailed() MsgBox(4096 + 48, @ScriptName, "Unable to connect to the remote systems Registry tree." & @CRLF & @CRLF & _ "Description: " & @TAB & $__RegistryConnectFailed.description & @CRLF & _ "Windows description:" & @TAB & $__RegistryConnectFailed.windescription & @CRLF & _ "Number: " & @TAB & hex($__RegistryConnectFailed.number,8) & @CRLF & _ "Last DLL Error: " & @TAB & $__RegistryConnectFailed.lastdllerror & @CRLF & _ "Scriptline: " & @TAB & $__RegistryConnectFailed.scriptline & @CRLF & _ "Source: " & @TAB & $__RegistryConnectFailed.source & @CRLF & _ "Help file: " & @TAB & $__RegistryConnectFailed.helpfile & @CRLF & _ "Help context: " & @TAB & $__RegistryConnectFailed.helpcontext _ ) EndFunc Func _EnableRemoteAssist($Reg) Local Const $RegTerminalServ = "Software\Policies\Microsoft\Windows NT\Terminal Services" Local Const $RegRAUnsolicit = $RegTerminalServ & "\RAUnsolicit" Local Const $HKEY_LOCAL_MACHINE = 0x80000002 Local $RC = 0 $Reg.CreateKey($HKEY_LOCAL_MACHINE, $RegTerminalServ) $Reg.CreateKey($HKEY_LOCAL_MACHINE, $RegRAUnsolicit) $RC += $Reg.SetDWORDValue($HKEY_LOCAL_MACHINE, $RegTerminalServ, "fAllowUnsolicited", 1) $RC += $Reg.SetDWORDValue($HKEY_LOCAL_MACHINE, $RegTerminalServ, "fAllowUnsolicitedFullControl", 1) $RC += $Reg.SetStringValue ($HKEY_LOCAL_MACHINE, $RegRAUnsolicit, "helper", "helper") Return SetError($RC, 0, $RC = 0) EndFunc Func _DisableRemoteAssist($Reg) Local Const $RegTerminalServ = "Software\Policies\Microsoft\Windows NT\Terminal Services" Local Const $RegRAUnsolicit = $RegTerminalServ & "\RAUnsolicit" Local Const $HKEY_LOCAL_MACHINE = 0x80000002 Local $RC = 0 $RC += $Reg.DeleteValue($HKEY_LOCAL_MACHINE, $RegTerminalServ, "fAllowUnsolicited") $RC += $Reg.DeleteValue($HKEY_LOCAL_MACHINE, $RegTerminalServ, "fAllowUnsolicitedFullControl") $RC += $Reg.DeleteValue($HKEY_LOCAL_MACHINE, $RegRAUnsolicit, "helper") Return SetError($RC, 0, $RC = 0) EndFunc #EndRegion Edited January 6, 2009 by Zinthose --- TTFN
spudw2k Posted December 22, 2008 Posted December 22, 2008 (edited) Very nice. I like this a lot. It's much simpler than walking a user through setting up a Remote Assist request or NetMeeting session. Well done. edit: Minor bug found. When connecting to a machine with mutiple sessions the objcall fails because of the params passed to it. Lines 84 and 85 read: $UserDomain = $SelectedUser[0] $UserID = $SelectedUser[1] Edited December 22, 2008 by spudw2k Spoiler Things I've Made: Always On Top Tool ◊ AU History â—ŠÂ Deck of Cards â—Š HideIt â—Š ICU â—Š Icon Freezer â—Š Ipod Ejector â—Š Junos Configuration Explorer â—Š Link Downloader â—Š MD5 Folder Enumerator â—Š PassGen â—ŠÂ Ping Tool â—Š Quick NIC â—Š Read OCR â—Š RemoteIT â—Š SchTasksGui â—Š SpyCam â—Š System Scan Report Tool â—Š System UpTime â—Š Transparency Machine ◊ VMWare ESX Builder Misc Code Snippets: ADODB Example â—Š CheckHover ◊ Detect SafeMode â—Š DynEnumArray â—Š GetNetStatData ◊ HashArray â—Š IsBetweenDates â—Š Local Admins â—Š Make Choice â—Š Recursive File List â—Š Remove Sizebox Style â—Š Retrieve PNPDeviceID â—Š Retrieve SysListView32 Contents â—Š Set IE Homepage â—Š Tickle Expired Password â—Š Transpose Array Projects: Drive Space Usage GUI â—ŠÂ LEDkIT â—Š Plasma_kIt â—ŠÂ Scan Engine Builder â—Š SpeeDBurner â—Š SubnetCalc Cool Stuff: AutoItObject UDF â—Š Extract Icon From Proc â—Š GuiCtrlFontRotate â—Š Hex Edit Funcs â—Š Run binary â—Š Service_UDF Â
Zinthose Posted December 23, 2008 Author Posted December 23, 2008 Very nice. I like this a lot. It's much simpler than walking a user through setting up a Remote Assist request or NetMeeting session. Well done. edit: Minor bug found. When connecting to a machine with mutiple sessions the objcall fails because of the params passed to it. Lines 84 and 85 read: $UserDomain = $SelectedUser[0] $UserID = $SelectedUser[1] Good eye spudw2k... Corrected --- TTFN
momus Posted December 28, 2008 Posted December 28, 2008 Hi, I'm very new at this, so I apologize if my questions are simplistic. I compiled and ran this, but nothing seemed to happen. Is there supposed to be a front-end that opens and asks for the hostname variable? What should I see when this script is run? Thanks.
Zinthose Posted January 5, 2009 Author Posted January 5, 2009 Hi,I'm very new at this, so I apologize if my questions are simplistic.I compiled and ran this, but nothing seemed to happen. Is there supposed to be a front-end that opens and asks for the hostname variable? What should I see when this script is run?Thanks.The original code used a hard coded hostname... I added an InputBox to prompt for a Hostname to connect to. --- TTFN
Ghost21 Posted January 6, 2009 Posted January 6, 2009 The original code used a hard coded hostname... I added an InputBox to prompt for a Hostname to connect to.Well what can I say but OMFG thankyou and very niceley written..Been looking for something like this for some time. The only thing that I have found is you need to copy two files to the remote system first. These two files enable you to take control of the other persons computer without asking permission when you need to fix something. If you need the two files let me know and I will send them two you. "\\" & $Hostname & "\c$\windows\pchealth\HelpCtr\System\Remote Assistance\helpeeaccept.htm", 1)"\\" & $Hostname & "\c$\windows\pchealth\HelpCtr\System\Remote Assistance\Interaction\Server\TakeControlMsgs.htm", 1)Thanks again..
FireFox Posted January 6, 2009 Posted January 6, 2009 @Zinthose It works now, what should I enter in input box ? because nothing works.... Cheers, FireFox.
Zinthose Posted January 6, 2009 Author Posted January 6, 2009 It works now, what should I enter in input box ? because nothing works....You will enter the Hostname, also know as the computer name, of the remote Windows XP system you wish to offer remote assistance. The remote system must be administratively accessible by the source system.Also, Please note the additional requirements in the first post. --- TTFN
FireFox Posted January 6, 2009 Posted January 6, 2009 @Zinthose I have the requirements but I dont understand how it works because if I enter the hostname of a friend, how can he receive my message ? Cheers, FireFox.
Zinthose Posted January 6, 2009 Author Posted January 6, 2009 I have the requirements but I don't understand how it works because if I enter the hostname of a friend, how can he receive my message?This example dose not work over the internet unless the systems are connected through a VPN or Hamachi network connection due to firewall and security concerns. --- TTFN
FireFox Posted January 6, 2009 Posted January 6, 2009 @Zinthose Ok, explain me how does this work with hamachi please Cheers, FireFox.
themlruts Posted March 2, 2009 Posted March 2, 2009 might be a real dumb question but how do you complie this? I have visaul studio on my machine can i use that?
torels Posted March 2, 2009 Posted March 2, 2009 yes it is indeed you can do 2 things 1) convert it to whatever you like and then compile it with visual studio 2) download autoit (the zipped one if you don't want an installation) and run aut2exe or the wrapper Some Projects:[list][*]ZIP UDF using no external files[*]iPod Music Transfer [*]iTunes UDF - fully integrate iTunes with au3[*]iTunes info (taskbar player hover)[*]Instant Run - run scripts without saving them before :)[*]Get Tube - YouTube Downloader[*]Lyric Finder 2 - Find Lyrics to any of your song[*]DeskBox - A Desktop Extension Tool[/list]indifference will ruin the world, but in the end... WHO CARES :P---------------http://torels.altervista.org
lgvlgv Posted August 15, 2012 Posted August 15, 2012 (edited) cant make this work, dont have a domain, is it possible to use workgroup if u have your own account on remote machine? Tryed all kind of solutions from internet, u have any idea? ------ ERROR Unable to connect to the remote systems Registry tree. Description: Windows description: Ã…tkomst nekad. Number: 80070005 Last DLL Error: 0 Scriptline: 205 Source: Help file: Help context: 5439580->16:29:35 AutoIT3.exe ended.rc:1 Edited August 15, 2012 by lgvlgv
lgvlgv Posted August 15, 2012 Posted August 15, 2012 (edited) Hi again, it worked if i had an identical account on remote system, but does anyone know how to connect useing another account? Cant figure out how to connect over wmi useing a local existing account on remote machine, can i send the account information somehow in $Reg=ObjGet("winmgmts:{impersonationLevel=impersonate}!" & $HostName & "rootdefault:StdRegProv") Edited August 15, 2012 by lgvlgv
lgvlgv Posted August 16, 2012 Posted August 16, 2012 i solved it with RunAs() Hi again, it worked if i had an identical account on remote system, but does anyone know how to connect useing another account? Cant figure out how to connect over wmi useing a local existing account on remote machine, can i send the account information somehow in $Reg=ObjGet("winmgmts:{impersonationLevel=impersonate}!" & $HostName & "rootdefault:StdRegProv")
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now