PowerShell 检测用户无输入时间(idle)


背景

上个周末Codecook问起idle,一段往事划过脑际。话说某公司安全制度比较严格,员工离开座位机器一律要锁屏,不锁屏着,被IT发现:轻则罚钱,中则罚项目组的团队的活动经费,重则直接走人。某哥们投机取巧,直接把显示器关了,没有锁屏。结果那个IT简直是母鸡中的战斗机啊,竟然打开显示器去检查,逮了个正着啊,然后就是一番批评教育。

再后来公司内部组织了个兄弟写了个程序,大概是检测如果用户没有输入(键盘和鼠标等)超过5分钟,系统处于idle状态,自动锁屏,大大降低了被IT抓的几率。

脚本

那现在回到正题上来,如何通过PowerShell 检测Windows系统中用户无输入(idle)的时间呢,肯定得调用系统的Windows API了。

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

namespace Win32_API
{
    internal struct LASTINPUTINFO 
    {
        public uint cbSize;
        public uint dwTime;
    }

    /// <summary>
    /// Summary description for Win32.
    /// </summary>
    public class Win32
    {
        [DllImport("User32.dll")]
        public static extern bool LockWorkStation();

        [DllImport("User32.dll")]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);        

        [DllImport("Kernel32.dll")]
        private static extern uint GetLastError();

        public static uint GetIdleTime()
        {
            LASTINPUTINFO lastInPut = new LASTINPUTINFO();
            lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
            GetLastInputInfo(ref lastInPut);

            return ( (uint)Environment.TickCount - lastInPut.dwTime);
        }

        public static long GetTickCount()
        {
            return Environment.TickCount;
        }

        public static long GetLastInputTime()
        {
            LASTINPUTINFO lastInPut = new LASTINPUTINFO();
            lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
            if (!GetLastInputInfo(ref lastInPut))
            {
                throw new Exception(GetLastError().ToString());
            }                           
            return lastInPut.dwTime;
        }
    }
}
'@

以上c# 代码来源于Getting the user idle time with C#

测试

再然后写一行命令测试一下,写个循环,循环10次,每次先sleep 1秒钟,然后检测下idle,并打印。脚本执行过程中请不要敲键盘或者动鼠标,你会发现 GetIdleTime返回的整数单位正好是毫秒。然后再运行一次,在中途敲敲键盘测试,对比一下吧。

PS> 1..10 | foreach { 
	sleep -Seconds 1 
	 'loop {0}, Idle={1}s' -f $_ , ( [Win32_API.Win32]::GetIdleTime()/1000 )
}
loop 1, Idle=0.937s
loop 2, Idle=1.937s
loop 3, Idle=2.937s
loop 4, Idle=3.953s
loop 5, Idle=4.953s
loop 6, Idle=5.953s
loop 7, Idle=6.953s
loop 8, Idle=7.953s
loop 9, Idle=8.953s
loop 10, Idle=9.968s

总结

那如果检测到idle超时后,我可以用PowerShell 锁屏吗,我可以用PowerShell关闭显示器吗,当然。所以万事俱备,只欠你这股东风了。

 

×用微信扫描并分享
本文链接: https://www.pstips.net/detec-idle-time.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注