GFI workstations only check in every 30-60 minutes, but it would still be helpful to see if anyone was logged on to a workstation at the most recent check-in. If it’s 8pm and no one was logged in at 7:30pm, probably they are gone for the evening and I can log in to the machine to do some work.
The first question is how to determine if someone is logged on to a computer, and there are lots of possible solutions. After researching a few options, I decided to use the PsLoggedon.exe tool from the Sysinternals PsTools package.
There are ways to call an executable from PowerShell, but I chose to write this as a “batch” or “command” script rather than in PowerShell.
Scripting 101
Always get to know your core tool before trying to run it from a script. If you simply run
psloggedon.exe
from an administrative command prompt, you should a list of active logons. I had some trouble with the logon times not displaying properly in my testing, so I added the –x parameter to suppress the the time:
psloggedon.exe – -x
Update December 15, 2014 I’ve learned that PSLoggedOn lists all logons since the last system boot. Only the one displaying the time is current. Those displaying <unknown time> are no longer active. Also, I only care about local logons. And I want to accept the EULA from the command line. So I’m now running PsLoggedOn as follows:
psloggedon.exe –accepteula –l
Update August 24, 2015 Another option for finding out who is logged on is to use wmic. It doesn’t list the logon time, but it is built in to Windows so it wouldn’t require putting an executable on each machine. This approach is not implemented here, but I wanted to document it in case you want to test it:
wmic ComputerSystem get Username
Where is the Tool?
The trick then becomes how to get access to that psloggedon.exe executable file on each workstation where you want to run it. Obviously you could copy it to each machine, perhaps into a C:\Scripts\Helpers folder. Another option is to put it in a server folder, e.g. D:\NetAdmin, then share that folder read-only through the network.
Theoretically, your script could be as simple as
\\MyServer\NetAdmin\psloggedon.exe –accepteula –l
Put that in a .cmd file and upload it to the GFI dashboard and you have a script for at least one site.
I wanted my script to be more flexible, so it accepts one parameter, the path to the psloggedon executable. There is also some error trapping (if you run it interactively and forget to specify a parameter) and some abstraction to make it easier to adapt for running other programs.
Deployment
When you deploy the script, specify the path to the psloggedon.exe file in the Command Line. A 10-second timeout should suffice. I’d recommend testing on one workstation before rolling out to an entire site.
Once running, you’ll see results like this in the Checks tab:
Click on the blue link to see the full output:
The Script
Here is the script. Save it to a .cmd file for uploading it as a GFI custom script. Use at your own risk and test first!
@echo off REM 10/16/2014 REM REM Check who is logged on to the local PC. REM REM Param 1: path to local or network copy of Sysinternals psloggedon REM REM Assumes you have administrative permissions on the local PC, e.g. domain admin. REM =========================================================================================== REM Set up variables REM =========================================================================================== REM This script can be adapted to run another program by modifying the next two lines set ProgramExe=psloggedon.exe set ProgramParams=-accepteula -l REM Exit with 0; exceptions below set /A exitcode=0 REM =========================================================================================== REM Check for parameters REM =========================================================================================== if ###%1###==###### goto NoParam goto ParamsFound :NoParam echo. echo Missing parameter(s) echo. echo Usage: CheckLogonLocal.cmd Sysinternals echo. echo Example: echo. echo CheckLogonLocal.cmd "C:\Program Files (x86)\Sysinternals" echo. set /A exitcode=1001 goto End :ParamsFound REM =========================================================================================== REM Strip quotation marks, if any, from parameters REM =========================================================================================== set ProgramPath=%~1 REM =========================================================================================== REM Echo parsed parameters REM =========================================================================================== REM echo ProgramPath: %ProgramPath% REM echo ProgramExe: %ProgramExe% REM echo ProgramParams: %ProgramParams% REM =========================================================================================== REM Check for program path REM =========================================================================================== if exist "%ProgramPath%" goto PathExists echo Program path "%ProgramPath%" does not exist. Exiting. set /A exitcode=1002 goto End :PathExists REM =========================================================================================== REM Check for program executable REM =========================================================================================== if exist "%ProgramPath%\%ProgramExe%" goto ProgramExists echo Program executable "%ProgramPath%\%ProgramExe%" does not exist. Exiting. set /A exitcode=1003 goto End :ProgramExists REM =========================================================================================== REM Run ProgramExe with the specified ProgramParams REM =========================================================================================== "%ProgramPath%\%ProgramExe%" %ProgramParams% set %exitcode%=%errorlevel% :End exit /b %exitcode%