【问题标题】:PowerShell - User session managementPowerShell - 用户会话管理
【发布时间】:2019-05-25 09:15:53
【问题描述】:

我有这个 PowerShell 脚本可以在空闲时间超过 1 小时的情况下注销用户:

#Force script to run.
Set-ExecutionPolicy Unrestricted -force
#Check connected users and save output.
quser|out-file C:\Users\Administrator\Documents\disconectAgora\quser.txt
#Read output with logged in users.
$file = Get-Content C:\Users\Administrator\Documents\disconectAgora\quser.txt

#Obtain IDLE time by using patters.
$pattern = "Disc(.*?)11"
#Obtaons session ID by using patther.
$pattern2 = "adminagora(.*?)Disc"


#Execute query using above patterns.
$result = [regex]::Match($file,$pattern).Groups[1].Value
$result2 = [regex]::Match($file,$pattern2).Groups[1].Value

#Trim file and save both session id and username.

$result = $result -replace(' ','')
$result |out-file C:\Users\Administrator\Documents\disconectAgora\getDCUser.txt

$result2 = $result2 -replace(' ','')
$result2 |out-file C:\Users\Administrator\Documents\disconectAgora\getDCUserID.txt

#If IDLE time is greater than 1 hour user is disconnected.
if ($result -gt '1:00'){    
    logoff $result2
    }
else{
    write-host "No users with IDLE time greater than 1 hour found.No users to be logged off."
    }

我要做的是检查 cmd 进程是否正在运行,以便用户可以保持登录状态,直到该进程结束。

我认为,也许通过运行此命令 get-process | where-object {$_.mainwindowhandle -ne 0} | select-object name, mainwindowtitle 并使用正则表达式仅获取 cmd 进程可能会成功,但这是一种非常原始的方法。

如果你们对如何执行此操作有任何线索,请告诉我。

根据要求,这是 quser 的输出:

长话短说

除了检查 CPU 使用率之外,我还需要一种方法来了解 CMD 是否正在执行某些操作:

【问题讨论】:

  • 您应该发布实际代码而不是屏幕截图。如果有人想尝试一下,他们不会为了帮助你而坐下来重新输入。
  • 你说得对,谢谢
  • 如果您向我们展示您的(可能已本地化)quser 的示例输出,我认为您的大部分代码都可以使用命名捕获组通过 RegEx 缩短
  • 为什么$pattern 中有11
  • @LievenKeersmaekers,它是用于测试目的,当我执行quser 时,我要提取的部分位于光盘和登录时间之间。在本例中,11 是月份中的某一天。

标签: powershell session user-management usersession


【解决方案1】:

要获取 cmd 进程,只需运行 get-process -name cmd

要在 cmd 中查找任何子进程,您可以使用以下内容:

Get-WmiObject win32_process | where {$_.ParentProcessId -eq ((Get-Process -name cmd).id)}

更新。 正如@LievenKeersmaekers 注意到的那样,如果同时运行多个 cmd,这将无法工作。固定版本:

(Get-Process -name cmd).id | foreach { Get-WmiObject win32_process -filter "ParentProcessId='$_'"}

【讨论】:

  • 是的,这有帮助,但本质上我想要的是一些数据,让我知道 cmd 上是否正在运行某些东西。我可以使用 CPU 使用率作为参考,但我认为这不是一个可靠的标记。
  • 这取决于在 cmd 中究竟执行了什么。在一般情况下,它只能通过反复试验来完成。
  • 你也可以找到cmd的子进程。这可能是 cmd 中正在执行某些东西的轻微证据。
  • 请注意,这不是万无一失的。如果您有两个或多个 cmd 进程正在运行,并且在第一个 cmd 之外的另一个进程上有一个繁忙的子进程,则不会返回结果。
  • @LievenKeersmaekers 感谢您的注意,我进行了一项更改,应该检测所有正在运行的 cmd 的子进程。关于由 cmd 本身运行的一些代码 - 没有太多内部 cmd 命令可能会花费大量时间。
【解决方案2】:

Following 稍微简化了一点,返回除 adminagora 以外的会话断开超过一个小时的用户

(& quser) -split "`n" | ? {$_ -match "(?<!adminagora).*?Disc\s+\d:\d{2}"}

细分

(& quser) -split "`n"  -- Executes quser 
                          Splits each line on newline to pass through the pipeline
? {$_ -match           -- Where the current item matches the regex
(?<!adminagora)        -- Use a negative lookbehind to exclude adminagora
.*?Disc                -- match any characters as few times as possible up until Disc. 
\s+\d:\d{2}            -- match any space character followed by
                       -- a digit, a colon and two digits

【讨论】:

  • 哇,这确实简化了我的脚本。但主要是我如何确定是否有东西在 cmd 上运行,我可以通过 CPU 使用率来指导我,但我并不热衷于此。
猜你喜欢
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2014-08-25
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
相关资源
最近更新 更多