测量Windows 7用户登录时间


8

客户端已要求我计算计算机和用户的平均登录时间。到目前为止,我发现该事件记录了一些启动过程,这些启动过程所花费的时间超过了在以下位置找到的键所设置的阈值:

HKLM\Software\Microsoft\Windows\CurrentVersion\Diagnostics\Performance\Boot

但是这些键似乎已锁定,因此我无法对其进行编辑以降低阈值以确保每次启动均被记录下来。是否有足够的方法来查找每个登录的登录时间,以使用户知道正在登录的详细信息以及可能的更详细的信息,所以还需要足够轻巧以在每次登录时运行,并且不会对用户造成明显的影响。


“锁定”是什么意思?尝试更改值时会显示什么信息?您是否以“以管理员身份”启动Regadit来规避当前帐户权限的限制或UAC设置的限制?
the-wabbit 2012年

通过以管理员身份运行的regedit编辑密钥,结果为“无法编辑BootMinorThreshold_Sec:写入值的新内容时出错。”
Decad 2012年

确保您具有更改此密钥的值的权限。此外,还要检查您的防病毒引擎是否由于某些不可思议的原因未阻止注册表更改。
the-wabbit 2012年

由于此计算机是全新安装的测试软件,因此该计算机上目前没有正在运行的防病毒软件。我以本地管理员身份运行。有没有办法检查密钥的权限?
Decad 2012年

3
您如何定义“用户登录时间”?在用户验证其用户名和密码与资源管理器准备启动程序之间的这段时间?
Gregory MOUSSAT 2012年

Answers:


4

最近有人要求我做一个非常类似的事情,但要包括启动和登录时间,并允许历史参考。因此下面的powershell脚本执行以下操作:

  1. 获取一些环境变量
  2. 获取4个不同事件日志条目的时间/日期戳。其中的第二和第四位不是精确的测量值,但是经过大量的研究,故障排除和测试,它们非常接近,并且据我所知,这是最佳选择。
  3. 计算这4个事件之间的差
  4. 将所有数字填充到一个简单的SQL表中[您可以进行调整以将数字自然地传递到所需的任何内容中]

因此,脚本旨在通过计划任务运行,或者如果您具有SCCM,则可以按计划运行(不在登录期间,以便根本不更改登录)。有趣的是,您可以将PCname更改为其他名称,以便从您自己的PC运行它,并从远程计算机获取数据(尽管用户名将显示为您自己的名称)以进行故障排除和验证数字。

我采取了另一步骤,并使用SharePoint创建了外部数据列表(使用BCS),因此它们具有不错的前端GUI。在以下脚本中,我保留了编写该脚本时使用的大多数注释行:

$USER = $env:username.ToUpper()
$COMPUTER = $env:computername.ToUpper()
$Current_Time = Get-Date
$PCname = ''
$addedtime = 0

#1. get event time of last OS load
$filterXML = @'
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (Level=4 or Level=0) and (EventID=12)]]</Select>
  </Query>
</QueryList>
'@
$OSLoadTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
#Write-Host $PCname
#Write-Host "1. Last System Boot @ " $OSLoadTime

#2. Get event time of Time-Service [pre-Ctrl+Alt-Del] after latest OS load
$filterXML = @'
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Time-Service'] and (Level=4 or Level=0) and (EventID=35)]]</Select>
  </Query>
</QueryList>
'@
$CtrlAltDelTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
#Write-Host "2. Time-sync after Boot @ " $CtrlAltDelTime
#get minutes (rounded to 1 decimal) between OS load time and 1st load of GPOs
$BootDuration = "{0:N1}" -f ((($CtrlAltDelTime - $OSLoadTime).TotalSeconds + $addedtime)/60)

#3. get event time of 1st successful logon
$filterXML = @'
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Winlogon'] and (Level=4 or Level=0) and (EventID=7001)]]</Select>
  </Query>
</QueryList>
'@
$LogonDateTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML -ErrorAction SilentlyContinue).timecreated

If ($LogonDateTime) { 
    #Write-Host "3. Successful Logon @ " $LogonDateTime 
    } 
    Else {
    #Write-Host "Duration of Bootup = " $BootDuration "minutes" -foregroundcolor blue -BackgroundColor white
    #Write-Host $PCname "has not logged back in." -foregroundcolor red -BackgroundColor white
    Exit
    }
#Write-Host "Duration of Bootup = " $BootDuration "minutes" -foregroundcolor blue -BackgroundColor white

#4. Get Win License validated after logon (about same time as explorer loads)
$filterXML = @'
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[Provider[@Name='Microsoft-Windows-Winlogon'] and (Level=4 or Level=0) and (EventID=4101)]]</Select>
  </Query>
</QueryList>
'@
$DesktopTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
$LogonDuration = "{0:N1}" -f ((($DesktopTime - $LogonDateTime).TotalSeconds + $addedtime)/60)
#Write-Host "4. WinLicVal after Logon @ " $DesktopTime
#Write-Host "Duration of Logon = " $LogonDuration "minutes" -foregroundcolor blue -BackgroundColor white

#START SQL Injection Section
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")

$sqlServer = "SQLserver01"
$dbName = "BootUpTimes"
$tbl = "tblBootUpTimes"
#$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $sqlServer
#$db = $srv.databases[$dbName]
#$conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$sqlServer;Initial Catalog=$dbName; Integrated Security=SSPI")
$conn = New-Object System.Data.SqlClient.SqlConnection("server=$sqlServer;database=$dbName;Password=plaintext;User Id=BootUpTimes")
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = "INSERT INTO $tbl VALUES ('$Current_Time','$USER','$COMPUTER','$OSLoadTime','$CtrlAltDelTime','$BootDuration','$LogonDateTime','$DesktopTime','$LogonDuration')"
Try
{
$null = $cmd.ExecuteNonQuery()
}
Catch
{
}
$conn.Close()

在最后一个SQL部分中,注释掉了几行,提供了另一种方法(基于安全性)输入SQL,而无需输入明文密码。


引导后的时间同步似乎没有发生。我重新启动了测试计算机并运行了脚本。我的启动时间为-4,657.9分钟。由于时间同步日期是2天前。
Decad 2012年

我猜我的域策略设置不同。我们已经打开“始终等待网络..”,这可能是原因。另外,如果您只需要登录时间,则可以注释掉那些启动部分
Jordan W.

该脚本仅对未登录的身份进行验证
Jim B

3

我不确定为什么有人会认为脚本会帮助您确定登录时间(毕竟,您必须等到有人登录才能运行脚本,并且拉动时间将无济于事,因为时间漂移肯定会导致误报-这也在启动处理之前不会固定。我建议您使用的工具是性能工具包中的xperf工具。您希望查看总登录时间的explorerinit时间。有关以下内容的详细说明,请参见Windows On / Off Transition Performance Analysis。从启动到台式机会发生什么情况,请参阅Windows Performance Analysis Tools从适当的位置获取xperf和xbootmgr。


我前一段时间看着xperf。但是我感觉这更像是一次性调试工具?是否可以将其设置为每次启动和每次登录都运行?
Decad 2012年

可以,但是为什么您需要测量每次引导和每次登录?
Jim B

一些用户抱怨登录时间,当有人抱怨时,他们希望掌握事实。截至目前,他们还没有任何事实可以支持。因此,他们希望能够显示和监视用户和计算机的登录时间。IE机器0001-平均登录时间为10秒。用户joe博客的平均登录时间为8秒。这只需要运行足够长的时间即可获得足够的数据,以获得足够的平均值。
Decad '02

如果您遇到间歇性问题,那么平均水平将无济于事。当用户抱怨时,首先要查看的是组策略处理日志,看看是否有问题(99%的时间是脚本)。之后,我将安装该工具,重新启动并让他们再次登录。
Jim B

我们以与您建议的类似的方式解决间歇性情况,通常是脚本。但是,他们希望能够向用户显示这些数字,以帮助他们向他们显示登录时间不如其当前的声誉那么糟糕。
Decad 2012年

2

/superuser/250267/how-to-diagnose-slow-booting-or-logon-in-windows-7

该线程使用Windows Performance Analysis Tools显示启动诊断的“ Microsoft”方式

Microsoft提供的有关“打开/关闭转换性能”的很好的记录程序,又名“打开/关闭Windows”:http//msdn.microsoft.com/zh-cn/windows/hardware/gg463386.aspx

使用这些官方工具,您可以为客户提供权威的答案。我认为,这比尝试使用脚本优越得多。如果您的基本需要,可能会有些过大。

另外,如果您的需求非常基本,请不要错过Soluto的网站:)


2

以下作为登录脚本执行的批处理文件将在某种程度上告诉您从身份验证到准备就绪外壳所需的时间。

set logfile=\\server\share\%computername%-%username%.log
net user /domain %username% | find /I "Last logon" > %logfile%
net time %logonserver% >> %logfile%

我尚未对此进行测试,并且做了一些假设。

  1. 返回的登录时间net user是DC执行身份验证的时间。我相信情况就是如此,但是找不到任何具体的证据来支持这一点。
  2. 登录脚本在用户外壳程序加载时运行。如果您使用较旧的旧版NT4登录脚本,而不是由组策略定义的登录脚本,则肯定是这种情况,但是由于GPO登录脚本对用户隐藏(默认情况下),所以我从未见过他们被执行。
  3. 您的用户名不包含空格,%username%在这种情况下,您可能需要加引号。
  4. 您拥有一个可写入的世界共享区,将在其中记录数据(\\server\share在上面的示例中)。您可以将其本地记录在单独的计算机上,但这将使检查结果更加困难。

编辑:

我已经更新了脚本以处理Jim关心的时间漂移​​。net use命令的登录开始时间取自身份验证域控制器的时钟。的net time现在,命令还将花费同一服务器的时间。


用户GPO在登录后但在执行loginscript之前应用。这次将不见了。
汤姆(Tom)

如果我将此批处理文件放在机器启动中,我认为它会给出更可接受的读数吗?
Decad 2012年

@Decad我本来建议将其作为一种选择,但认为使用登录脚本来部署脚本会更容易。我个人将其部署为旧版登录脚本。即通过ProfileADU&C中用户帐户属性对话框的标签。这肯定在资源管理器外壳加载时运行。
布赖恩

我认为脚本在explorerinit期间运行(这就是为什么登录脚本会减慢登录速度)
Jim B

@Decad我已经更新了脚本,以消除任何时间漂移的机会。
布赖恩2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.