Jerome Lefebvre

Log Out from PI Vision

Blog Post created by Jerome Lefebvre on Jun 19, 2019

A customer recently asked that they wanted a log out feature of PI Vision. A very reasonable request for any users that have shared terminal.

This is already a popular feature request on user voice: Logout capability – User Feedback for OSIsoft Products and Services 

As well this is possible when using Claim based authentication and PI Vision. OpenID providers give you a log out URL that you can open when you want to log out. (Thus, not a place to click on a PI Vision dashboard, but something you would keep in your favorites).


Moving to claim based authentication is not easy, nor does it make sense for all deployment.


I couldn't think of anything clever to, so a created a timeout script for IE. If the user doesn't interact with the machine for a few minutes, then close the IE. After a day, I still haven't thought of anything better, so I am sharing it here.


This is not particular clever and will aggravate users.

If I find something better, I will try to update this post.


$timeout = new-timespan -Minutes 100
$stopwatch = [diagnostics.stopwatch]::StartNew()

#while the timeout hasn't occured, periodically check if the user is idle.
#If so, then close IE if it is running.
while ($stopwatch.elapsed -lt $timeout){
    # Check how many minutes the user has been idle
    if ([PInvoke.Win32.UserInput]::IdleTime.Minutes -ge 10) {
        get-process iexplore -ErrorAction SilentlyContinue| stop-process
    start-sleep -seconds 30



To find how long a user has not interacted with their system uses some methods not exposed to PowerShell, thus we must add in some .Net code in the script.


Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PInvoke.Win32 {

    public static class UserInput {

        [DllImport("user32.dll", SetLastError=false)]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        private struct LASTINPUTINFO {
            public uint cbSize;
            public int dwTime;

        public static DateTime LastInput {
            get {
                DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount);
                DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
                return lastInput;

        public static TimeSpan IdleTime {
            get {
                return DateTime.UtcNow.Subtract(LastInput);

        public static int LastInputTicks {
            get {
                LASTINPUTINFO lii = new LASTINPUTINFO();
                lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
                GetLastInputInfo(ref lii);
                return lii.dwTime;