DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: Help with Windows batch script  (Read 7,848 times)

AzureToad

  • Charter Member
  • Joined in 2006
  • ***
  • Posts: 101
Help with Windows batch script
« on: May 05, 2015, 04:11 PM »
Ok, 1st off, I'm guessing this probably isn't the best place for this post. If not, someone can move it to the best area - as long as it's not the trash bin!

I am having problems with a Windows batch script. Maybe someone out there can point out my error.

What I'm trying to do is to retrieve a list of remote desktop sessions on a server, then log each one off unless the login name matches a list of names to be ignored.
The list of sessions and logging off is not a problem. It's when I need to check against the list of names that I have a problem.

Here's my code:

Code: (generic)
SET serverlist=APPLE BANANA CHERRY
FOR %%s in (%serverlist%) DO (
	FOR /f "tokens=1,2,3" %%a IN ('QUERY USER /server:%%s^"') DO (
		::	Don't log off this list of users:
		::	administrator, Zebra, Yankee
		IF /I [%%a] EQU [administrator] (
			ECHO Ignored user %%a
		) ELSE ( 
			IF /I [%%a] EQU [Zebra] (
				ECHO Ignored user %%a
			) ELSE (
				IF /I [%%a] EQU [Yankee] (
					ECHO Ignored user %%a
				) ELSE (
					IF %%c LSS 65536 (
						ECHO Logging off ACTIVE user %%a on session %%c
						LOGOFF /server:%%s %%c
					) ELSE (
						IF %%b LSS 65536 (
							ECHO Logging off DISCONNECTED user %%a on session %%b
							LOGOFF /server:%%s %%b
						)
					)
				)
			)
		)
	)
)

When I DON'T check for individual login names, all users are logged off. That part works great - has been working for years.
Checking for the individuals doesn't work - all users are logged off anyway with the message indicating whether they were active or disconnected.

PLUS, with username checking, the script stops after the 2nd server loop. Server APPLE and BANANA are checked and all users are logged off, but the loop stops without checking server CHERRY.
  (Turns out the script only had APPLE and BANANA defined - no CHERRY on top!)

I figured I must have an unbalanced parenthesis, but I've gone over this until my head hurts and can't find it.  So I turn to this group for help.
« Last Edit: May 05, 2015, 04:17 PM by AzureToad »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: Help with Windows batch script
« Reply #1 on: May 06, 2015, 01:27 AM »
Bearing in mind I haven't got a Domain setup to test this on:

I get the following return from QUERY USER /server:8x8x64  (8x8x64 is localhost):

Code: (text)
USERNAME      SESSIONNAME       ID   STATE   IDLE TIME      LOGON TIME
 4wd          console            1   Active      none       6/05/2015 10:31

A multi-line return, you seem to be interested in only the first three tokens returned, which would be: USERNAME, SESSIONNAME, ID

If it's a different for a Domain server, can you post an example?

Otherwise, here's a short version that might work, (no output regarding who's logged on/off - but you should be able to add it under the IF statement by parsing the text file for the info):

Code: (generic)
SET serverlist=APPLE BANANA CHERRY
SET userlist=administrator zebra yankee
SET tempfile=%TEMP%\quser.txt
FOR %%s in (%serverlist%) DO (
  QUERY USER /server:%%s >%tempfile%
  FOR %%u in (%userlist%) DO (
    FIND /C /I %%u %tempfile%
    IF %ERRORLEVEL% NEQ 0 LOGOFF /server:%%s
    )
  )


Regarding your command file:
'QUERY USER /server:%%s^"'  - seems to escaping a single quotation mark, there's no matching quote, although quotes shouldn't be needed anyway since there's no spaces in any of the arguments.

While it runs, it could be written as:

FOR /f "tokens=1,2,3 usebackq" %%a IN (`QUERY USER /server:%%s`) DO (
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

AzureToad

  • Charter Member
  • Joined in 2006
  • ***
  • Posts: 101
Re: Help with Windows batch script
« Reply #2 on: May 06, 2015, 05:13 AM »
Wow, I like how compact your example is!  :up:
I managed to modify my script, using an array of users and a FOR loop, somewhat similar to yours.

Output from the QUERY USER /SERVER: looks the same as query on localhost.  Here's a sample (names changed, of course):
Code: (text)
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 ablebz                                    2  Disc         4:25  5/5/2015 5:33 AM
 wertala                                   4  Disc         2:57  5/5/2015 10:21 AM
 trowe801              rdp-tcp#40          7  Active       5:18  5/5/2015 10:49 AM
 aspensma                                  8  Disc         4:17  5/5/2015 3:18 PM

After looking at your code a bit more, i think it would have to be modified a bit. I think you'd need to create a file of the users that should NOT be logged off, then have a FOR loop for each server, and have a FOR loop extracting each user currently logged on that server. Then you could use the FIND command to see if the current login ID is in the file to be ignored, and if it's not, then you'd issue the LOGOFF command.  Unless I totally missed your example?

Bottom line, I finally did get my script to work.
Thanks for your reply!

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: Help with Windows batch script
« Reply #3 on: May 06, 2015, 05:52 AM »
Thanks for the example output, forgot about having more than one user logged in since I only have single user machines on a LAN to play with - so yeah, my example only dealt with that scenario so not having a session specified in the LOGOFF command is kind of limiting :)

I might have a play with your output to see what I can come up with.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: Help with Windows batch script
« Reply #4 on: May 06, 2015, 07:36 AM »
Seemed to work OK with the example output you gave above, (edited to test various cases), but I couldn't test it listing output from servers, etc.

Create a file in the same directory as the command file called validusers.txt and enter each user, one per line.

Remove the echo. in front of the LOGOFF command if the output looks OK.

Code: (generic)
@echo off
SET serverlist=APPLE BANANA CHERRY
SET userlist=.\validusers.txt
SET tempfile=.\quser.txt
for %%s in (%serverlist%) do (
  QUERY USER /server:%%s >%tempfile%
  for /f "skip=1 tokens=1,2,3,4,5,6,7,8" %%a in (%tempfile%) do (
rem If it's a remote session then %%h will not be empty
    if "%%~h" NEQ "" call :Logoff %%a %%b %%c %%d %%s
  )
)
goto :End

:Logoff
findstr /I ^%1$ %userlist% >NUL
  if %ERRORLEVEL% NEQ 0 (
    echo.Logging off User: %1, Session: %2, Status: %4
    echo.LOGOFF %2 /server:%5
  ) else (
    echo.Ignored user %1
  )
goto :EOF

:End

Example output, (as is, using a modified QUSER output):
Code: (text)
Logging off User: wertala, Session: rdp-tcp#2, Status: Disc
LOGOFF rdp-tcp#2 /server:8x8x64
Ignored user trowe801
Ignored user administrator

So if nothing else, the :Logoff subroutine will maybe give you some ideas.

QUSER test output used
Code: (text)
USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 ablebz                                    2  Disc         4:25  5/5/2015 5:33 AM
 wertala               rdp-tcp#2           4  Disc         2:57  5/5/2015 10:21 AM
 trowe801              rdp-tcp#40          7  Active       5:18  5/5/2015 10:49 AM
 administrator         rdp-tcp#1           8  Active       4:17  5/5/2015 3:18 PM

validuser.txt used
administrator
yankee
zebra
trowe801
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

Ath

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 3,649
    • Participated in NANY Challenge Eleven Times
    • Coding Snacks
    • Linux User
    • Hardware Hacker
Re: Help with Windows batch script
« Reply #5 on: May 06, 2015, 08:18 AM »
You might want to create a %server%-validusers.txt file, by making these subtle changes:

Code: (generic)
...
SET userlist=validusers.txt
...
and
Code: (generic)
...
:Logoff
findstr /I ^%1$ .\%5-%userlist% >NUL
...

and having 3 files APPLE-validusers.txt, BANANA-validusers.txt and CHERRY-validusers.txt in the current directory.

You could make it even more fancy by adding a check for common users in validusers.txt, but that seems like a little overkill to me.
/Ton
Ath's software collection, Quote: "A problem well stated is a problem half-solved." (Charles Kettering)

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: Help with Windows batch script
« Reply #6 on: May 06, 2015, 09:37 AM »
@Ath: I was hoping you'd show us a one line Powershell script.

:P

Good idea the per server user list.  :Thmbsup:
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

Original address: https://www.donationcoder.com/forum/index.php?topic=40847.0