Created
September 8, 2021 12:09
-
-
Save ohaval/3b1936cacc9ce4545f52aa5b8366e044 to your computer and use it in GitHub Desktop.
A small program that log off a user (possibly in another session) in Windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""A small program that log off a user (possibly in another session) in Windows | |
This is actually an implementation in Python of the `LogoffUser.cpp` program I have made. | |
I made that program in order to automate the manual operation of logging off my family | |
user in the workstation each time after they have used it :) | |
LogoffUser.cpp link: https://gist.github.com/ohaval/a922fc07f4585b81c119614e852d9dbd | |
Make sure that the `pywin32` packages is installed before using | |
""" | |
import argparse | |
import ctypes | |
import logging | |
import os | |
import sys | |
from win32ts import ( | |
WTS_CURRENT_SERVER_HANDLE, | |
WTSUserName, | |
WTSEnumerateSessions, | |
WTSQuerySessionInformation, | |
WTSLogoffSession, | |
) # Documentation: http://timgolden.me.uk/pywin32-docs/win32ts.html | |
def logoff_user(username: str): | |
sessions = WTSEnumerateSessions() | |
for s in sessions: | |
session_username = WTSQuerySessionInformation(Server=WTS_CURRENT_SERVER_HANDLE, | |
SessionId=s["SessionId"], | |
WTSInfoClass=WTSUserName) | |
if session_username.lower() == username.lower(): | |
WTSLogoffSession(Server=WTS_CURRENT_SERVER_HANDLE, | |
SessionId=s["SessionId"], | |
Wait=True) | |
logging.info(f"Successfully logged off '{username}'") | |
return | |
logging.info(f"Didn't find any session associated with the user '{username}'") | |
def main(): | |
logging.basicConfig(format="%(asctime)s -%(levelname)s - %(message)s", level=logging.INFO) | |
parser = argparse.ArgumentParser() | |
parser.add_argument("username", metavar="USERNAME", help="Username to logoff (case insensitive)") | |
args = parser.parse_args() | |
if ctypes.windll.shell32.IsUserAnAdmin(): | |
try: | |
logoff_user(args.username) | |
except Exception: | |
logging.error("An exception was raised", exc_info=True) | |
finally: | |
# When the same program is rerun by ShellExecuteW the program's process | |
# exits immediately when finished. We use `PAUSE` to prevent that. | |
os.system("PAUSE") | |
else: | |
logging.info("Rerunning the program with admin privileges") | |
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment