# Logging out of perspective session with perspective.SessionInfo and perspective.logout

**URL:** <https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171>\
**Category:** Ignition\
**Tags:** ignition81, perspective, scripting\
**Created:** [July 31, 2023, 8:15pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171 "2023-07-31T20:15:16Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [July 31, 2023, 8:15pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/1 "2023-07-31T20:15:16Z")

</div>

Hi all,

I'm currently working on a timer script that checks to see if the users that are logged into sessions exist in the database user-source and if they don't force a logout of that session.

currently this is the code I have in the scripting library:

```auto
def checkUser():
	logger = system.util.getLogger("checkUser")
	#Run a named query and store the dataset result
	ds = system.db.runNamedQuery("Admin_user/get_userInfo/get_allUserNames", {})
		
	#Convert the dataset result into a list
	usersList = ds.getColumnAsList(ds.getColumnIndex('username'))
	
	#Iterate through the list and pre-process all the names in the list for accurate comparison 
	for indx, val in enumerate(usersList):
		usersList[indx] = val.strip().lower()
		#logger.info(str(val))
		
	loggedInUsers = system.perspective.getSessionInfo()
	logger.info(str(loggedInUsers))
	loggedInUserNames = []
	for indx, val in enumerate(loggedInUsers):
	    loggedInUserNames.append(loggedInUsers[indx]['username'])
	
	logger.info(str(loggedInUserNames))
	for indx, name1 in enumerate(loggedInUserNames):
		if loggedInUsers[indx]['username'] not in usersList:
			forceRemove = loggedInUsers[indx]['id']
			forceRemovePage = loggedInUsers[indx]['pageIds']
			system.perspective.logout(sessionId = forceRemove, pageId = forceRemovePage, message = "Please Contact Admin about new username for : " + str(name1))
	

```

I'm uncertain how to fix the errors its giving me.  
The current error is:

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 2, in File "", line 80, in checkUser at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:57) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475) at jdk.internal.reflect.GeneratedMethodAccessor356.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Page "["2e36985f"]" not found.
at org.python.core.Py.JavaError(Py.java:547)
at org.python.core.Py.JavaError(Py.java:538)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:552)
at org.python.core.PyObject. __call__ (PyObject.java:400)
at org.python.pycode._pyx9591.checkUser$2(:76)
at org.python.pycode._pyx9591.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:119)
at org.python.core.PyFunction. __call__ (PyFunction.java:406)
at org.python.pycode._pyx9590.f$0(:2)
at org.python.pycode._pyx9590.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:803)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:823)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:751)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:804)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:90)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Page "["2e36985f"]" not found.
... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: Page "["2e36985f"]" not found.
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:57)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475)
at jdk.internal.reflect.GeneratedMethodAccessor356.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
... 23 common frames omitted

```

Hopefully there is a simple solution to this issue.

Thank you,

Cam

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 31, 2023, 8:50pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/2 "2023-07-31T20:50:57Z")

</div>

> [@Cameron\_Nickle](#):
>
> ```auto
> Traceback (most recent call last): File "", line 2, 
> in File "", line 80, in checkUser at com.inductiveautomation.perspective... 
> Page "["2e36985f"]" not found.
> 
> ```

That message suggests that the problem is at line 80 but you've only pasted 25 lines so I'm guessing it's a gateway script with more lines above or below it. Which is line 80?

The page not found suggests a [system.perspective.closePage](https://docs.inductiveautomation.com/display/DOC81/system.perspective.closePage?src=sidebar) or similar being passed an invalid page ID.

---

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [July 31, 2023, 8:54pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/3 "2023-07-31T20:54:12Z")

</div>

Line 80 is:

```auto
system.perspective.logout(sessionId = forceRemove, pageId = forceRemovePage, message = "Please Contact Admin about new username for : " + str(name1))

```

Thats what I was thinking too but im grabbing the Page ID's right from the system.perspective.getSessionInfo() so am I using the wrong values?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 31, 2023, 9:00pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/4 "2023-07-31T21:00:02Z")

</div>

> [@Cameron\_Nickle](#):
>
> system.perspective.getSessionInfo()

I notice from the manual page that it returns,  
**pageIds** - An array of page IDs that are currently open in the Session.

Are you handling the array correctly? (I don't know enough to say.)

---

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [July 31, 2023, 9:05pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/5 "2023-07-31T21:05:15Z")

</div>

I dont know enough to say either but I'll try and pass them in a different way I guess.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 31, 2023, 9:15pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/6 "2023-07-31T21:15:51Z")

</div>

What if you just... Don't pass a page id? You're trying to end the whole session, so which page it is shouldn't matter.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [August 1, 2023, 1:55am UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/7 "2023-08-01T01:55:27Z")

</div>

Sessions may have multiple page IDs, so the `pageIds` attribute of the Session object is a list.  
These lines

```auto
forceRemovePage = loggedInUsers[indx]['pageIds']
system.perspective.logout(sessionId = forceRemove, pageId = forceRemovePage, message = "Please Contact Admin about new username for : " + str(name1))

```

are attempting to supply a list of page id strings when the function expects a singular string.  
The relevant part of the error message is this: `java.lang.IllegalArgumentException: Page "["2e36985f"]" not found.` See how the list of `pageId` strings is being cast as a string? The back-end is trying to act on that page, while an id of "2e36985f" exists, no id of "["2e36985f"]" does.

~~As @paul-griffith suggested, you can just omit the `pageId` argument entirely, as that function doesn't really make use of the argument anyway.~~

---

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [August 1, 2023, 4:17pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/8 "2023-08-01T16:17:10Z")

</div>

Fair enough. I edited the code to be:

```auto
system.perspective.logout(sessionId = [forceRemove], message = "Please Contact Admin about new username for : " + str(name1))

```

However I'm now getting a 'UUID string too large' Error.

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 2, in File "", line 87, in checkUser at java.base/java.util.UUID.fromString(Unknown Source) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475) at jdk.internal.reflect.GeneratedMethodAccessor448.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: UUID string too large
at org.python.core.Py.JavaError(Py.java:547)
at org.python.core.Py.JavaError(Py.java:538)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:552)
at org.python.core.PyObject. __call__ (PyObject.java:400)
at org.python.pycode._pyx9950.checkUser$2(:81)
at org.python.pycode._pyx9950.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:119)
at org.python.core.PyFunction. __call__ (PyFunction.java:406)
at org.python.pycode._pyx9949.f$0(:2)
at org.python.pycode._pyx9949.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:803)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:823)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:751)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:804)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:90)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: UUID string too large
... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: UUID string too large
at java.base/java.util.UUID.fromString(Unknown Source)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.getSession(AbstractScriptingFunctions.java:91)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:118)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475)
at jdk.internal.reflect.GeneratedMethodAccessor448.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
... 23 common frames omitted

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 1, 2023, 4:18pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/9 "2023-08-01T16:18:11Z")

</div>

You _don't_ want those square brackets.  
`system.perspective.logout(sessionId = forceRemove, message = "Please Contact Admin about new username for : " + str(name1))`

---

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [August 1, 2023, 4:25pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/10 "2023-08-01T16:25:31Z")

</div>

```auto
system.perspective.logout(sessionId = forceRemove, message = "Please Contact Admin about new username for : " + str(name1))

```

is giving me this error:

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 2, in File "", line 87, in checkUser at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:64) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120) at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47) at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475) at jdk.internal.reflect.GeneratedMethodAccessor448.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.
at org.python.core.Py.JavaError(Py.java:547)
at org.python.core.Py.JavaError(Py.java:538)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:552)
at org.python.core.PyObject. __call__ (PyObject.java:400)
at org.python.pycode._pyx9954.checkUser$2(:81)
at org.python.pycode._pyx9954.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:119)
at org.python.core.PyFunction. __call__ (PyFunction.java:406)
at org.python.pycode._pyx9953.f$0(:2)
at org.python.pycode._pyx9953.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:803)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:823)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:751)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:804)
at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:90)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.python.core.PyException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: No perspective page attached to this thread.
... 26 common frames omitted
Caused by: java.lang.IllegalArgumentException: No perspective page attached to this thread.
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.lambda$operateOnPage$0(AbstractScriptingFunctions.java:64)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnSession(AbstractScriptingFunctions.java:120)
at com.inductiveautomation.perspective.gateway.script.AbstractScriptingFunctions.operateOnPage(AbstractScriptingFunctions.java:47)
at com.inductiveautomation.perspective.gateway.script.PerspectiveScriptingFunctions.logout(PerspectiveScriptingFunctions.java:475)
at jdk.internal.reflect.GeneratedMethodAccessor448.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)
... 23 common frames omitted

```

This is strange to me, because in the sessionInfo function it is printing that the user I want removed is in the list of online users with the correct session ID I'm passing it.

```auto
u'id': '2cabd449-52e1-4cbb-bdb7-08e274025e97', u'username': 'test_one', u'authorized': True

```

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/d/2ded1997398e1efc5d533ad4a178a2d1ec237533.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 1, 2023, 4:28pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/11 "2023-08-01T16:28:54Z")

</div>

Well, that's unfortunate. Turns out `logout` requires a page context (you can omit the session; it'll be retrieved from the page), specifically because (as far as I can tell from the code) it has to tell each running page "hey, log out now".

---

<div class="post-metadata">

**Author:** ![Cameron\_Nickle](https://avatars.discourse-cdn.com/v4/letter/c/b3f665/32.png) [@Cameron\_Nickle](https://forum.inductiveautomation.com/u/Cameron_Nickle)\
**Post date:** [August 1, 2023, 5:28pm UTC](https://forum.inductiveautomation.com/t/logging-out-of-perspective-session-with-perspective-sessioninfo-and-perspective-logout/77171/12 "2023-08-01T17:28:20Z")

</div>

I got it to work.

```auto
    logger = system.util.getLogger("checkUser")
	#Run a named query and store the dataset result
	ds = system.db.runNamedQuery("Admin_user/get_userInfo/get_allUserNames", {})
		
	#Convert the dataset result into a list
	usersList = ds.getColumnAsList(ds.getColumnIndex('username'))
	
	#Iterate through the list and pre-process all the names in the list for accurate comparison 
	for indx, val in enumerate(usersList):
		usersList[indx] = val.strip().lower()
		
	loggedInUsers = system.perspective.getSessionInfo()
	loggedInUserNames = []
	for indx, val in enumerate(loggedInUsers):
	    loggedInUserNames.append(loggedInUsers[indx]['username'])
	
	for indx, name1 in enumerate(loggedInUserNames):
		if loggedInUsers[indx]['username'] not in usersList:
			forceRemoveSession = loggedInUsers[indx]['id']
			forceRemovePage = loggedInUsers[indx]['pageIds']
			for indx, page in enumerate(forceRemovePage):
				try:
					system.perspective.logout(sessionId = forceRemoveSession, pageId = forceRemovePage[indx], message = "Please Contact Admin about new username for : " + str(name1))
				except:
					logger.info("Tried to remove user: Failed")

```

The function seems to want both the session ID and page ID. Without both you get "Not perspective thread" errors.
