2016-12-06 75 views
0

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

回答

0

不知道有多少服务器,但如果低于50左右,你可以与PSJobs并行执行此操作。您必须将代码包装在scriptblock中,将每个服务器作为单独的作业启动,然后等待它们完成并检索返回的任何数据。这样做时您将无法使用写主机,但我已将这些交换到了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部署进行测试,所以如果您发现任何错误或无法在发布评论时运行,我会看看我能做些什么。

+0

感谢这是很好的信息,我会试试这个。比方说,我想扼杀在后台运行的工作。有什么我可以添加到这个来运行三个或四个工作,然后移动到下一组服务器? –

+0

你可以使用while循环和一些递归函数来做类似的事情,但如果你想限制查看运行空间,因为它们本身就提供了它,所以提供的链接显示了如何使用它们。 –

0

我准备好了一些测试,但它可能会非常糟糕。你向导可能会看到这个和大笑。如果我做错了,请让我知道。

$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