This project is read-only.

Detect Active user / Locked Screen / Not Logged On user

Topics: Archive - General
Jan 15, 2015 at 5:49 PM
Is there a way to detect in the AppDeployToolkit if SCCM 2012 starts the script:
  • a user is logged on
  • no user is logged on
  • user is logged on but screen is locked
Jan 16, 2015 at 7:13 AM
Get-LoggedOnUser function returns a property called IsConsoleUser. If this property is true, then that is the user with control of the keyboard, mouse, and screen.

To check if the screen is locked, see below code. There may be some other method of checking as well but you may have to google that:
$UserNotificationStateSource = @'
using System;
using System.Runtime.InteropServices;
namespace QueryUser
{
    public class NotificationState
    {
        // http://msdn.microsoft.com/en-us/library/bb762533(v=vs.85).aspx
        public enum UserNotificationState
        {
            ScreenSaverOrLockedOrFastUserSwitching=1, FullScreenOrPresentationMode=2, RunningDirect3dFullScreen=3, PresentationMode=4, AcceptsNotifications=5, QuietTime=6, WindowsStoreAppRunning=7
        }
        // Only for Vista or above
        [DllImport("shell32.dll")]
        static extern int SHQueryUserNotificationState(out UserNotificationState pquns);
        public static UserNotificationState GetState()
        {
            UserNotificationState state;
            int returnVal = SHQueryUserNotificationState(out state);
            return state; 
        }
    }
}
'@
If (-not ([System.Management.Automation.PSTypeName]'QueryUser.NotificationState').Type) {
    Add-Type -TypeDefinition $UserNotificationStateSource -Language CSharp
}
Start-Sleep -Seconds 10
[QueryUser.NotificationState]::GetState()
Jan 16, 2015 at 9:14 AM
Edited Jan 16, 2015 at 9:14 AM
Someone available to rewrite above code to some useable code for the AppDeployToolKit ?
Jan 16, 2015 at 9:25 AM
Edited Jan 16, 2015 at 9:26 AM
I don't understand how the above code is not usable. Copy/paste the above code into your script. You can get rid of the Start-Sleep line. Then simply calling this line will give you the result you are looking for: [QueryUser.NotificationState]::GetState()

Then use an if statement of some sort to determine what to do based on the result you get. The result you get will be one of the following:
ScreenSaverOrLockedOrFastUserSwitching, FullScreenOrPresentationMode, RunningDirect3dFullScreen, PresentationMode, AcceptsNotifications, QuietTime, WindowsStoreAppRunning
Marked as answer by Pollewops on 1/16/2015 at 2:18 AM
Jan 16, 2015 at 10:17 AM
Hi MMashwani...is it that simple....thanks for the update.
I will try...tnx
Jan 16, 2015 at 5:27 PM
Hi I tried the following script
$UserNotificationStateSource = @'
using System;
using System.Runtime.InteropServices;
namespace QueryUser
{
    public class NotificationState
    {
        // http://msdn.microsoft.com/en-us/library/bb762533(v=vs.85).aspx
        public enum UserNotificationState
        {
            ScreenSaverOrLockedOrFastUserSwitching=1, FullScreenOrPresentationMode=2, RunningDirect3dFullScreen=3, PresentationMode=4, AcceptsNotifications=5, QuietTime=6, WindowsStoreAppRunning=7
        }
        // Only for Vista or above
        [DllImport("shell32.dll")]
        static extern int SHQueryUserNotificationState(out UserNotificationState pquns);
        public static UserNotificationState GetState()
        {
            UserNotificationState state;
            int returnVal = SHQueryUserNotificationState(out state);
            return state; 
        }
    }
}
'@
If (-not ([System.Management.Automation.PSTypeName]'QueryUser.NotificationState').Type) {
    Add-Type -TypeDefinition $UserNotificationStateSource -Language CSharp
}


$time = Get-date
$test = [QueryUser.NotificationState]::GetState()
$output = "$($test) - $($time)"
$output |Out-File -FilePath c:\test.log -Append

# Then use an if statement of some sort to determine what to do based on the result you get. 
# ScreenSaverOrLockedOrFastUserSwitching, FullScreenOrPresentationMode, RunningDirect3dFullScreen, PresentationMode, AcceptsNotifications, QuietTime, WindowsStoreAppRunning
I schedule it in my Windows 7 task scheduler and run as SYSTEM every 5 minutes.
My log file contains:
FullScreenOrPresentationMode - 01/16/2015 17:46:42
FullScreenOrPresentationMode - 01/16/2015 17:49:32
FullScreenOrPresentationMode - 01/16/2015 17:53:22
FullScreenOrPresentationMode - 01/16/2015 17:58:22
FullScreenOrPresentationMode - 01/16/2015 18:03:22
FullScreenOrPresentationMode - 01/16/2015 18:08:22
FullScreenOrPresentationMode - 01/16/2015 18:13:22
FullScreenOrPresentationMode - 01/16/2015 18:18:22
FullScreenOrPresentationMode - 01/16/2015 18:23:56
And it doesn't matter if I am logged on or not or if the screen is locked :-(
Jan 16, 2015 at 9:52 PM
What happens if you schedule it to run as a user and not as SYSTEM?
Jan 16, 2015 at 10:08 PM
I think the above code will only work if run as a user.

However, I just realized the Get-LoggedOnUser function already in the toolkit will provide the information you are looking for. Look at the property called "ConnectState" returned by the function. This property can hold one of the following values: Active, Connected, ConnectQuery, Shadow, Disconnected, Idle, Listen, Reset, Down, Init.

The one's you are interested in are these:
Active: Logged in and using
Disconnected: logged in but the screen is locked or user is detached
Jan 16, 2015 at 10:14 PM
Also, you can check to see if LogonUI.exe is running. If computer is locked, then LogonUI.exe will be running.
Feb 11, 2015 at 6:35 PM
Edited Feb 11, 2015 at 6:35 PM
What version of PSADT started using get-LoggedOnUser? we are currently on 3.2.0
Feb 13, 2015 at 10:09 AM
I use 3.5.0
Feb 13, 2015 at 11:11 AM
Get-LoggedOnUser does not provide me that information.
I tried, but the info in the log is the same when logged on with or without screensaver active and screen locked.
Mar 12, 2015 at 5:09 PM
I just did a test and Get-LoggedOnUser will return FullScreenorPresentationmode when I am logoff.

I find it interesting but what is the mean of each value?

ScreenSaverOrLockedOrFastUserSwitching
FullScreenOrPresentationMode--> logoff?
RunningDirect3dFullScreen
PresentationMode
AcceptsNotifications
QuietTime-->login with no screensaver?
WindowsStoreAppRunning
Mar 13, 2015 at 1:13 AM
Get-LoggedOnUser does not return any of that information.

The code I posted above returns that information. There is a link in the code that explains what the values mean.
Mar 13, 2015 at 3:03 AM
Edited Mar 13, 2015 at 3:21 AM
I ran the 3.6 PSADTK and found the interactivity was working today. But if the session is logoff, the interactivity was still active. So I ran get-loggedonuser and found on a logoff that function was returning "FullScreenOrPresentationMode" so when I get that result, I can disable interactivity.

This is interesting but it would be interesting understanding why such result.

I called the above function test-locksession and then I was able to turn off deploymodesilent. Not sure if its the best way.
$Var_Testlock=Test-LockSession
if ($Var_Testlock -eq "FullScreenOrPresentationMode") {
                    
                    $deployModeSilent=$true
                    
}   
Mar 13, 2015 at 7:39 PM
Hi Mo,

Can you add in both the docs and the comments for the Get-LoggedOnUser Function,

About how "ConnectState" returned by the function, That it can hold one of the following values:
Active, Connected, ConnectQuery, Shadow, Disconnected, Idle, Listen, Reset, Down, Init.

And a table of what each value means. Like this:
Active: Logged in and using
Disconnected: logged in but the screen is locked or user is detached

Why? Right now, it's fresh in your memory and it's gibberish to us common mortals.
Mar 13, 2015 at 8:16 PM
Absolutely, I can do that.
Mar 13, 2015 at 8:16 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.