How to unassign user and then shut down instance using the Logoff (Logout) action?

This article discusses how to unassign (unbind) users, shutdown, delete instances, and other actions that are performed by delivering messages from the guest operating system to an external source when performing the Logoff (Logout) action for the user.

Example for Windows operating system

  1. Install dependencies. Download archive:https://curl.se/windows/dl-7.85.0_1/curl-7.85.0_1-win64-mingw.zip.

    Unzip the archive into a directory C:/Programm Files.

  2. Install the Chocolatey package manager. To do this, open command line and run the following command:

    @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
    
  3. Install with Chocolatey jQuery. To do this, on the command line, run:

    chocolatey install -y jq
    
  4. Reboot the instance.

  5. To restart and delete, create a script file “Restart, delete instance on Logout event” - logout.bat. An example script is given below. Put it in C:\scripts\.

  6. For logging, create script file “Logging Login / Logout events in the database” - journal.bat. An example script is given below. Put it in C:\scripts\.

    Important

    The paths for finding the script and token files (see script) must be available in the rights to create and edit new files. Otherwise, the script will not work, because during the Logout event it works with user rights, not administrator!

  7. To run the script on the Login/Logout event, you need to:

    Click “Start” - “Run” - input gpedit.msc and press “Enter”;

    Go to “User Configuration” - “Windows Settings” - “Scripts (Logon / Logoff)” - “Logoff” and specify the path to the script;

    Go to “User Configuration” - “Windows Settings” - “Scripts (Logon / Logoff)” - “Logon” and specify the path to the script. Consider the order in which scripts are executed when installing them.

  8. To automatically end the session of an authorized user upon disconnection (by timeout), you need to:

    Click “Start” - “Run” - input gpedit.msc.

    Next, configure the following setting: Computer Configuration - Administrative Components - Windows Components - Remote Desktop Services - Remote Desktop Session - Session Time Limits - Set time limit for disconnected sessions - <set timeout> (select the desired timeout time).

Example of script for unbinding user from the TRS instance and then turning it off

Note

Script must use the administrator of the project of the domain or the project in which the virtual machine is located, since other, ordinary users do not have the right to turn off and unbind users from the virtual machine! Also, the user must have the right to read the list of domain users.

Script text:

(# delete comments when implementing)
@echo off

setlocal enableextensions enabledelayedexpansion

rem set variables
# insert controller IP
set controller=10.1.220.31
       # login
set login=jerry
# password
set pass=1pass
       # project
set tenant=testproject1
set hostname=%computername%
# lowercase conversion function. Delete "rem" if necessary.
rem call :tolower hostname
# make sure that users in the directory have permissions to create files
# script log
set logfile=c:\scripts\logout.log
set responsefile=c:\scripts\token.txt
# make sure the path is correct
set curl=c:\progra~1\curl-7.84.0_9-win64-mingw\bin\curl.exe
set json="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%login%\",\"password\":\"%pass%\"}}},\"scope\":{\"project\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%tenant%\"}}}}"
set json_adm="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"jerry\",\"password\":\"13Qwerty\"}}},\"scope\":{\"project\":{\"domain\":{\"name\":\"msk\"},\"name\":\"testproject1\"}}}}"

rem write to log file
echo get command logout %username% at %date% %time% >> %logfile%
rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%

rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo  - get token >> %logfile%

rem get userid
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:5000/v3/users" | jq ".users[] | select(.name==\"%username%\").id" > %responsefile%
set /p userid=<%responsefile%
echo  - get id user %username% - %userid% >> %logfile%

rem get tenantid
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:5000/v3/projects" | jq ".projects[] | select(.name==\"%tenant%\").id" > %responsefile%
set /p tenantid=<%responsefile%
echo  - get id tenant %tenant% - %tenantid% >> %logfile%

rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%

rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo  - get token >> %logfile%

rem get id vm
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:8774/v2.1/servers" | jq ".servers[] | select(.name==\"%hostname%\").id" > %responsefile%
set /p vm=<%responsefile%
echo  - get id vm %hostname% - %vm% >> %logfile%

rem unassign user from vm
%curl% -X DELETE -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:9364/v1/servers/%vm%/users/%userid%" | jq ".users[] | select(.name==\"%username%\").id" > %responsefile%
echo  - unassign user %username% from vm %vm% >> %logfile%

rem poweroff vm
%curl% -s -X POST -H "X-Auth-Token: %token%" -H "Content-type:application/json" -d "{\"os-stop\" : null}" "http://%controller%:8774/v2.1/servers/%vm%/action"
echo  - shutoff vm %vm% >> %logfile%

rem delay and write to log file
timeout 30 > nul
echo after sleping 30 sec %date% %time% >> %logfile%
echo ----- >> %logfile%

rem delete temp files
del %responsefile%
goto :END

:tolower
for %%L in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set %1=!%1:%%L=%%L!
goto :EOF

:END

Example of script for logging Logout event in database

Script text:

(# delete comments when implementing)
@echo off

setlocal enableextensions enabledelayedexpansion

rem set variables
# insert controller IP
set controller=10.1.220.31
# login
set login=peppa
# password
set pass=13Qwerty
       # project
set tenant=testproject1
set hostname=%computername%
# lowercase conversion function. Delete "rem" if necessary.
call :tolower hostname
# make sure that users in the directory have permissions to create files
# script log
set logfile=c:\scripts\journal.log
set responsefile=c:\scripts\token.txt
# make sure the path is correct
set curl=c:\progra~1\curl-7.84.0_9-win64-mingw\bin\curl.exe
set json_adm="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"name\":\"msk\"},\"name\":\"%login%\",\"password\":\"%pass%\"}}},\"scope\":{\"domain\":{\"name\":\"msk\"}}}}"

rem write to log file
echo get command logout %username% at %date% %time% >> %logfile%

rem http request
%curl% -si -X POST -H "Content-type:application/json" -d %json_adm% "http://%controller%:5000/v3/auth/tokens" | findstr X-Subject-Token > %responsefile%

rem get token
set /p response=<%responsefile%
set token=%response:~17%
echo  - get token >> %logfile%

rem get ip
for /f "delims=[] tokens=2" %%a in ('ping -4 -n 1 %ComputerName% ^| findstr [') do set ip=%%a

rem get id vm
%curl% -s -X GET -H "X-Auth-Token: %token%" -H "Content-type:application/json" "http://%controller%:8774/v2.1/servers" | jq ".servers[] | select(.name==\"%hostname%\").id" > %responsefile%
set /p vm=<%responsefile%
echo  - get id vm %hostname% - %vm% >> %logfile%

rem add record to journal
set json_journal="{\"journal\":{\"object_id\": \"%vm%\",\"object_type\":\"server\",\"action\":\"logout\",\"status\":\"success\",\"user_name\":\"%username%\",\"message\":\"%ip%\",\"domain_id\":\"d1949bd531b24445921669165cf2813d\"}}"
%curl% -X POST -H "X-Auth-Token: %token%" -H "Content-type:application/json" -d %json_journal% "http://%controller%:9360/v1/journal/"
echo  - add record to journal >> %logfile%

rem write to log file
echo ----- >> %logfile%

rem delete temp files
del %responsefile%
goto :END

:tolower
for %%L in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set %1=!%1:%%L=%%L!
goto :EOF

:END