如何使用PowerShell 1从远程计算机中踢出最长的非活动用户?

时间:2012-02-29 17:15:53

标签: powershell remote-desktop terminal-services

如果他们忘记退出,我需要找一个简单的方法从服务器中启动队友。我们的终端服务限制为2个连接。我编写了以下函数来获取登录用户。正如我在powershell 2中所理解的,有更好的方法可以做到这一点,但我现在仍然坚持使用版本1。

以下函数将为我提供每台服务器的登录信息。 (如果你知道一个更漂亮的方法,请随时教育我。:)我对func不满意并希望从你那里学到一些技巧。)

function get-terminal-users($serverName)
{
    $path = "C:\ntui\source\i386"

    cd -path $path

    $result = invoke-expression -Command ".\quser.exe /SERVER:$serverName" | select -Skip 1       

    $a = @()

    foreach($row in $result)
    {        
        $d = new-object Object
        $columns = $row.Replace("  ", " ").Split(" ") | ? {$_ -ne ""}    

        $d | add-member -membertype noteproperty -name UserName -value $columns[0]    
        $id = -1
        $sessionName = ""                                  
        $columShift = 0

        #this part was not ok and needed fixing. Thanks Winfred for the answer!
        if([system.int32]::tryparse($columns[1].ToString(),[ref] $id))
        {     
            $columShift --              
        }
        else
        {            
            $sessionName =  $columns[1]
            $id = [system.int32]::parse($columns[2].ToString())                                             
        }          

        $time = [DateTime]::Parse($columns[5 + $columShift] + " " + $columns[6 + $columShift])

        $d | add-member -membertype noteproperty -name SessionName -value $sessionName
        $d | add-member -membertype noteproperty -name ID -value $id     
        $d | add-member -membertype noteproperty -name State -value $columns[3 + $columShift]
        $d | add-member -membertype noteproperty -name Idle -value $columns[4 + $columShift]
        $d | add-member -membertype noteproperty -name Time -value $time 

        $a += $d
    }

    return $a
}

所以如果用户需要列表,那么如果连接数高于允许的最大值,我就不得不踢出一个人。如果您知道从服务器获取此信息的方法,我将非常感谢您的帮助。

$name = "myserver"
$maxConnections = 2

$users = get-terminal-users($name)   

if($users.Count -eq $maxConnections)
{
    $idList = $users | ? { $_.State -eq "Disc" } | select -First 1 | foreach { $_.ID }   

    foreach($id in $idList)
    {          
        invoke-expression -Command ".\logoff.exe /SERVER:$name $id -V"                  
    }
}

问题是我只能与Active连接进行交互。被遗弃的连接仍然耗尽可用的连接,我似乎无法对它们做太多的事情。具有Disc状态的用户似乎使用了终端连接,当我因其某种原因在其id上调用logoff时,本地进程终止。有没有办法摆脱光盘连接?

rwinsta.exe似乎也只适用于活动连接。

我在XP上运行脚本并以Win 2003服务器为目标。

2 个答案:

答案 0 :(得分:2)

您将$ id错误地添加到此行的自定义对象:

$d | add-member -membertype noteproperty -name ID -value $id

断开的会话没有会话名称,请参阅:

quser.exe /SERVER:mycomputer
USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
winfred                                   2  Disc      4+21:05  2/28/2012 8:38 AM

并且需要$ columShift,你拥有所有属性,除了ID Noteproperty。因此,当您尝试注销断开连接的会话时,您会错误地将log ID指定给logoff.exe。

相反该行应该是:

$d | add-member -membertype noteproperty -name ID -value $columns[2 + $columShift]

答案 1 :(得分:0)

为什么使用PowerShell?使用正确的工具完成工作。在这种情况下,那将是组策略。

http://social.technet.microsoft.com/Forums/eu/winserverTS/thread/620e7bbf-c49b-4ab4-98ab-98e2ce5e979f