【问题标题】:Powershell Idle Time of Remote Machine using Win32 API GetLastInputInfo使用 Win32 API GetLastInputInfo 的远程机器的 Powershell 空闲时间
【发布时间】:2022-01-05 18:41:54
【问题描述】:

我正在尝试运行发布在Get idle time of machine 中的代码https://stackoverflow.com/users/251123/andy-arismendi。它返回的结果与我在本地运行时所期望的一样,但是当我尝试在远程计算机上执行时,我得到了奇怪的结果:它告诉我空闲时间超过 13 个小时——但我刚走出这个用户的办公室,就知道空闲时间时间应该以秒为单位。

这是我正在运行的确切代码 - 对原始代码稍作调整:

# via https://stackoverflow.com/questions/15845508/get-idle-time-of-machine

# c:\admin\pstools\psexec.exe \\COMPUTERNAME powershell.exe -command Enable-PSRemoting

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);

        [StructLayout(LayoutKind.Sequential)]
        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;
            }
        }
    }
}
'@


for ( $i = 0; $i -lt 10; $i++ ) {
    $Last = [PInvoke.Win32.UserInput]::LastInput
    $Idle = [PInvoke.Win32.UserInput]::IdleTime
    $LastStr = $Last.ToLocalTime().ToString("MM/dd/yyyy hh:mm tt")
    Write-Host ("`nTest " + $i)
    Write-Host ("   Last user keyboard/mouse input: " + $LastStr)
    Write-Host ("   Idle for " + $Idle.Days + " days, " + $Idle.Hours + " hours, " + $Idle.Minutes + " minutes, " + $Idle.Seconds + " seconds.")
    Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 10)
}

我正在像这样远程运行它:

Invoke-Command -ComputerName COMPUTERNAME -FilePath \\path\to\scripts\TESTING-IdleTime.ps1

我运行命令的机器和远程计算机都是 Windows 10 Pro 1709。

示例输出:

测试 0
最后用户键盘/鼠标输入:2018 年 1 月 10 日晚上 11:50
空闲 0 天 13 小时 16 分钟 13 秒。

我刚刚在一台我知道目前没有人登录的计算机上尝试过,它报告的时间是相同的——自上次重新启动系统以来的大致时间。

知道会发生什么吗?

【问题讨论】:

  • 我将您的代码封装成 2 个函数并运行本地测试,结果如下:PS C:\Users\Pythagoras> C:\Users\Pythagoras\Desktop\get-idletime.ps1 Test 0 Last user keyboard/mouse input: 01/12/2018 07:51 PM Idle for 0 days, 0 hours, 0 minutes, 0 seconds. Test 1 Last user keyboard/mouse input: 01/12/2018 07:51 PM Idle for 0 days, 0 hours, 0 minutes, 8 seconds. 然后停止了,所以它肯定在本地工作。您是否尝试过添加[cmdletBinding()] 并将$ComputerName 作为参数而不是使用psexec?
  • 我没有使用 psexec -- 我正在使用 Invoke-Command 我将查看 [cmdletBinding()];我对此并不熟悉。

标签: powershell windows-10


【解决方案1】:

脚本需要在用户上下文中运行。

例如,您可以通过使用任务计划程序并将“运行任务时,使用以下帐户:”设置为您需要空闲时间的用户帐户(或像“用户”这样的组,这也似乎可以完成这项工作)。

将其设置为“仅在用户登录时运行”也很重要。 任何其他设置都将具有您已经观察到的相同结果,显示计算机正常运行时间。

然后您可以调整脚本以定期将空闲时间记录到文件中或在其他地方报告。 如果需要做更多工作,您甚至可以远程部署和启动计划任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多