【问题标题】:RDS User logoff Script SlowRDS 用户注销脚本慢
【发布时间】:2017-04-21 16:47:18
【问题描述】:

在几篇在线文章的帮助下,我能够编译一个 powershell 脚本,用于注销我的每个 RD 会话主机的所有用户。我希望在注销用户并将配置文件写回到他们在存储系统上的漫游配置文件位置时非常温和。但是,这太温和了,大约需要四个小时才能完成我拥有的用户和 RDS 服务器的数量。

此脚本旨在设置每个 RDS 服务器消耗,但如果服务器可用,则允许重定向,因此围绕此的想法是在前 15 分钟内我会准备好前几台服务器供用户登录。

所有这些都有效,但我想看看是否有任何建议可以加快速度。

这是遍历每台服务器并注销用户然后将服务器登录模式设置为启用的循环:

ForEach ($rdsserver in $rdsservers){
    try {
        query user /server:$rdsserver 2>&1 | select -skip 1 | ? {($_ -split "\s+")[-5]} | % {logoff ($_ -split "\s+")[-6] /server:$rdsserver /V}


        Write-Host "Giving the RDS Server time"
        Write-Progress "Pausing Script" -status "Giving $rdsserver time to settle" -perc (5/(5/100))
        Start-Sleep -Seconds 5




        $RDSH=Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace "root\CIMV2\terminalservices" -ComputerName $rdsserver -Authentication PacketPrivacy -Impersonation Impersonate
        $RDSH.SessionBrokerDrainMode=0
        $RDSH.put() > $null
        Write-Host "$rdsserver is set to:"
        switch ($RDSH.SessionBrokerDrainMode) {
            0 {"Allow all connections."}
            1 {"Allow incoming reconnections but until reboot prohibit new connections."}
            2 {"Allow incoming reconnections but prohibit new connections."}
        default {"The user logon state cannot be determined."}
        }
    } 
    catch {}
}

【问题讨论】:

    标签: powershell rds logoff


    【解决方案1】:

    不确定您有多少服务器,但如果少于 50 台左右,您可以与 PSJobs 并行执行此操作。您必须将代码包装在脚本块中,将每个服务器作为单独的作业启动,然后等待它们完成并检索返回的任何数据。执行此操作时您将无法使用 Write-Host,但我已将它们交换为 Out-Files。我也没有解析你的代码来收集你的服务器列表,但我假设它有效,你可以让它将格式化列表返回到变量$rdsservers。您可能还想稍微修改一下消息,以便您可以在日志文件中判断哪个服务器是哪个服务器,或者为每个服务器执行不同的日志。如果您希望将作业名称以外的任何内容打到控制台,则必须使用 Write-Outputreturn 语句输出它。

    $SB = {
    param($rdsserver)
    Start-Sleep -Seconds 5
    
    $RDSH=Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace "root\CIMV2\terminalservices" -ComputerName $rdsserver -Authentication PacketPrivacy -Impersonation Impersonate
    $RDSH.SessionBrokerDrainMode=0
    $RDSH.put() > $null
    "$rdsserver is set to:" | out-file $LogPath #Set this to whatever you want
    switch ($RDSH.SessionBrokerDrainMode) {
        0 {"Allow all connections." | out-file $LogPath}
        1 {"Allow incoming reconnections but until reboot prohibit new connections." | out-file $LogPath}
        2 {"Allow incoming reconnections but prohibit new connections." | out-file $LogPath}
        default {"The user logon state cannot be determined." | out-file $LogPath}
    }
    
    foreach ($server in $rdsservers){
      Start-Job -Scriptblock -ArgumentList $server
    }
    
    Get-Job | Wait-Job | Receive-Job
    

    foreach 循环启动作业,然后最后一行等待所有作业完成,然后再获取输出的任何数据。如果您的脚本有可能永远不会完成,您还可以设置等待超时。如果您有大量的盒子,您可能需要查看运行空间而不是作业,因为它们具有更好的性能但需要更多的工作才能使用。如果您决定这样做,This Link 可以帮助您。我目前没有要测试的 RDS 部署,所以如果您遇到任何错误或无法使其正常工作,只需发表评论,我会看看我能做什么。

    【讨论】:

    • 谢谢,这是很好的信息,我会试试看。假设我想限制在后台运行的作业。我可以添加一些东西来运行三四个作业然后转移到下一组服务器吗?
    • 你可以使用 while 循环和一些递归函数来做类似的事情,但这很痛苦,如果你想限制查看运行空间,因为它们本机提供它,提供的链接显示了如何使用它们。
    【解决方案2】:

    我已经准备好进行测试,但它可能会严重损坏。你们那里的巫师可能会看到这个并笑。如果我做错了,请告诉我。

    $Serverperbatch = 2
    $job = 0
    $job = $Serverperbatch - 1 
    $batch = 1
    
    While ($job -lt $rdsservers.count) {
        $ServerBatch = $rdsservers[$job .. $job]
        $jobname = "batch$batch"
    Start-job -Name $jobname -ScriptBlock {
        param ([string[]]$rdsservers)
        Foreach ($rdsserver in $rdsservers) {
            try {
        query user /server:$rdsserver 2>&1 | select -skip 1 | ? {($_ -split "\s+")[-5]} | % {logoff ($_ -split "\s+")[-6] /server:$rdsserver /V}
        $RDSH=Get-WmiObject -Class "Win32_TerminalServiceSetting" -Namespace "root\CIMV2\terminalservices" -ComputerName $rdsserver -Authentication PacketPrivacy -Impersonation Impersonate
        $RDSH.SessionBrokerDrainMode=0
        $RDSH.put() > $null
       }
         catch {}
    
    } -ArgumentList (.$serverbatch)
        $batch += 1
        $Job = $job + 1
        $job += $serverperbatch
    
        If ($Job -gt $rdsservers.Count) {$Job = $rdsservers.Count}
        If ($Job -gt $rdsservers.Count) {$Job = $rdsservers.Count}
      }
    }
    Get-Job | Wait-Job | Receive-Job
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-14
      • 2021-08-01
      • 2011-04-14
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 2017-05-22
      相关资源
      最近更新 更多