Sign in to follow this  
Followers 0
AdamUL

Checking if a User is Logged Onto a Mac Computer with Plink

3 posts in this topic

#1 ·  Posted (edited)

I thought this would be helpful to share with the community. Functions below were written while currently working on a project to check public computers availability in our library. We use Pharos SignUp for users to log into the computers, both PC and Mac. Most recently we added iMac computers to our public computers managed through Pharos SignUp, and I was tasked with updating the "Computers Available" server side script, written in AutoIt, to check to see if a user is logged for a Mac, as well as a PC. I used >WMI to check to see if someone is logged into our PCs, but this is not avaible on a Mac, so I have to find another solution. After researching, I found out that I could use Plink, PuTTY Link, to connect to the Macs with SSH. I found some Plink wrapper UDFs, when searching the forums, and used the >ones that I though were most useful for this task and updated them.

For the _UserLoggedOniMac function to work, you must use an account that has SSH access to the Mac.  

Please look at the >Available Computers Example for updated example of the functions below.  
 

; #FUNCTION# ====================================================================================================================
; Name ..........: _UserLoggedOniMac
; Description ...: Checks to see if a user is logged into the console on a Macintosh computer.
; Syntax ........: _UserLoggedOniMac($sComputer, $sSSHUserName, $sSSHPassword)
; Parameters ....: $sComputer - A string of the host server name or IP Address.
;                 $sSSHUserName - A string of the SSH User Name.
;                 $sSSHPassword- A string of the SSH Password.
; Return values .: Success - 1 - User logged into the computer.
;                 Failure - 0, sets @error to:
;                 |0 - User not logged in.
;                 |1 - Unable to connect to computer.
; Author ........: Adam Lawrence (AdamUL)
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _UserLoggedOniMac($sComputer, $sSSHUserName, $sSSHPassword)

Local $iPIDPlink = _PlinkConnect($sComputer, $sSSHUserName, $sSSHPassword)
If @error Then Return SetError(1, 0, 0)

Local $sCmdLine = "who" & @CR
_PlinkSend($iPIDPlink, $sCmdLine)
Local $sUserName = _PlinkRead($iPIDPlink)
_PlinkSend($iPIDPlink, "exit" & @CR)
_PlinkExit($iPIDPlink)
;~  ConsoleWrite($sUserName & @CRLF & @CRLF) ;For testing.

;Cleanup output to show only user names by removing the command and the prompt.
$sUserName = StringStripWS(StringReplace(StringReplace($sUserName, $sCmdLine, ""), $sComputer & ":~ " & $sSSHUserName & "$", ""), 3)
Local $aUserName = StringSplit($sUserName, " console", 1) ;Split on " console" to get the desktop user.
If @error Then
$sUserName = ""
Else
$sUserName = $aUserName[1]
EndIf

If $sUserName = "" Then Return 0

Return 1
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _PlinkConnect
; Description ...: Use Plink to connect to a remote server using SSH.
; Syntax ........: _PlinkConnect($sHostName, $sUserName, $sPassword)
; Parameters ....: $sHostName - A string of the host server name or IP Address.
;                 $sUserName - A string of the SSH User Name.
;                 $sPassword - A string of the SSH Password.
; Return values .: Success - $iPID - the PID of the Plink session.
;                 Failure - 0, sets @error to:
;                 |1 - Plink.exe not found in @ScriptDir.
;                 |2 - Error running Plink.exe.
; Author ........: spudw2k
; Modified ......: Adam Lawrence (AdamUL)
; Remarks .......:
; Related .......: _PlinkExit
; Link ..........: http://www.autoitscript.com/forum/topic/130536-interacting-with-a-remote-computer-via-ssh/page__p__910252#entry910252
; Example .......: No
; ===============================================================================================================================
Func _PlinkConnect($sHostName, $sUserName, $sPassword)
    $sEXE = @ScriptDir & "\plink.exe"
;~   $sEXE = "plink.exe"
    If Not FileExists($sEXE) Then Return SetError(1, 0, 0)
$iPID = Run('"' & $sEXE & '" -ssh -pw ' & $sPassword & " " & $sUserName & "@" & $sHostName, @ScriptDir, @SW_HIDE, 0x1 + 0x8)  ;Run SSH.EXE
    If Not $iPID Then Return SetError(2, 0, 0)
    $iPIDCurrent = $iPID
    $sReturn = _PlinkRead($iPID)  ;Check for Login Success - Prompt
    If StringInstr($sReturn, "Store key in cache? (y/n)") Then
        _PlinkSend($iPID, "y" & @CR)
;~       _PlinkSend($iPID, "n" & @CR) ;For Testing.
        $sReturn = _PlinkRead($iPID)
    EndIf
    If StringInstr($sReturn, "Access denied") Or StringInstr($sReturn, "FATAL") Then Return SetError( 3, 0, 0)
    Return $iPID
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _PlinkRead
; Description ...: Read text data returned from the connected server.
; Syntax ........: _PlinkRead($iPID)
; Parameters ....: $iPID - PID returned from _PlinkConnect.
; Return values .: Success - String returned from StdOutRead of Plink.
;                 Failure - -1, sets @error to:
;                 |1 - Invaild Plink PID.
; Author ........: spudw2k
; Modified ......: Adam Lawrence (AdamUL)
; Remarks .......:
; Related .......: _PlinkSend
; Link ..........: http://www.autoitscript.com/forum/topic/130536-interacting-with-a-remote-computer-via-ssh/page__p__910252#entry910252
; Example .......: No
; ===============================================================================================================================
Func _PlinkRead($iPID)
    If Not $iPID Then Return SetError(1, 0, -1)
    Local $sDataA
    Local $sDataB
    Do
        $sDataB = $sDataA
        Sleep(100)
        $sDataA &= StdOutRead($iPID)
        If @error Then ExitLoop
    Until $sDataB = $sDataA And $sDataA And $sDataB
    Return $sDataA
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _PlinkSend
; Description ...: Send text data to the connected server.
; Syntax ........: _PlinkSend($iPID, $sCmd)
; Parameters ....: $iPID - PID returned from _PlinkConnect.
;                 $sCmd - A string of the command to send.
; Return values .: Success - 1
;                 Failure - 0, sets @error to:
;                 |StdinWrite @error code.
; Author ........: spudw2k
; Modified ......: Adam Lawrence (AdamUL)
; Remarks .......:
; Related .......: _PlinkRead
; Link ..........: http://www.autoitscript.com/forum/topic/130536-interacting-with-a-remote-computer-via-ssh/page__p__910252#entry910252
; Example .......: No
; ===============================================================================================================================
Func _PlinkSend($iPID, $sCmd)
    $iChars = StdinWrite($iPID,$sCmd)
Return SetError(@error, 0, $iChars)
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _PlinkExit
; Description ...: End a Plink session.
; Syntax ........: _PlinkExit($iPID)
; Parameters ....: $iPID - PID returned from _PlinkConnect.
; Return values .: Success - 1
;                 Failure - 0, sets @error to:
;                 |ProcessClose @error code.
; Author ........: spudw2k
; Modified ......: Adam Lawrence (AdamUL)
; Remarks .......:
; Related .......: _PlinkConnect
; Link ..........: http://www.autoitscript.com/forum/topic/130536-interacting-with-a-remote-computer-via-ssh/page__p__910252#entry910252
; Example .......: No
; ===============================================================================================================================
Func _PlinkExit($iPID)
    $iClosed = ProcessClose($iPID)
Return SetError(@error, 0, $iClosed)
EndFunc

_UserLoggedOniMac only returns a 1, logged in, or a 0, not logged in, if you need the need the user name just parse the data saved in the $sUserName variable.

Edit: Fixed Variable name in _UserLoggedOniMac.


Adam

Edited by AdamUL

Share this post


Link to post
Share on other sites



Curious, about how long does it take for the function to return?

woah....just noticed my name in the func desc metadata.

thanks.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

On my network, it varies in testing from around 800 ms to 1 s, but mostly stays around 850 ms to 950 ms. The way I use it, it is run in a separate process, so I can connect to each computer one right after the other, and then wait for a return from each computer in an another loop until a time out.

Your welcome. Your functions, that I link to in the OP, was where I started, and I wanted to give you credit.

Edit: Spelling.

Adam

Edited by AdamUL

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0