2016-12-06 1 views
0

Avec l'aide de plusieurs articles en ligne, j'ai pu compiler un script PowerShell qui déconnecte tous les utilisateurs pour chacun de mes hôtes de session RD. Je voulais que quelque chose soit très gentil pour déconnecter les utilisateurs et écrire des profils à leur emplacement de profil itinérant sur le système de stockage. Cependant, cela est trop doux et prend environ quatre heures pour compléter le nombre d'utilisateurs et de serveurs RDS que j'ai.Déconnexion de l'utilisateur RDS Script Slow

Ce script est conçu pour définir chaque vidage de serveur RDS, mais permettre la redirection si un serveur est disponible, donc les premières 15 minutes ont été celles où les premiers serveurs seraient prêts à se connecter. Tout cela fonctionne mais j'aimerais voir s'il y a des suggestions pour accélérer un peu le processus.

Voici la boucle qui passe par chaque serveur et enregistre les utilisateurs sur et définit ensuite le mode de connexion de serveur activé:

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 {} 
} 

Répondre

0

ne sais pas combien de serveurs que vous avez, mais si son moins de 50 ou si vous peut le faire en parallèle avec PSJobs. Vous devrez envelopper votre code dans un scriptblock, lancer chaque serveur en tant que travail séparé, puis attendre qu'ils complètent et récupèrent toutes les données renvoyées. Vous ne serez pas en mesure d'utiliser Write-Host en faisant cela, mais j'ai échangé ceux-ci avec Out-Files. Je n'ai pas non plus analysé votre code pour la collecte de votre liste de serveurs, mais je vais supposer que cela fonctionne et vous pouvez l'obtenir retourner une liste formatée à une variable $rdsservers. Vous aurez probablement aussi besoin de modifier les messages un peu pour pouvoir dire quel serveur est dans le fichier journal, ou faire des journaux différents pour chaque serveur. Si vous voulez autre chose que le nom des jobs pour frapper la console, vous devrez l'éditer avec Write-Output ou une instruction return.

$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 

La boucle foreach lance les travaux, puis la dernière ligne attend tous pour terminer avant d'obtenir des données qui était sortie. Vous pouvez également définir un délai d'attente sur l'attente s'il y a une chance que votre script ne se termine jamais. Si vous avez une tonne de boîtes, vous voudrez peut-être vous pencher sur les espaces de course plutôt que sur les emplois, car ils ont de meilleures performances, mais prennent plus de travail à utiliser. This Link peut vous aider si vous décidez de passer par là. Je n'ai pas de déploiement RDS pour le moment, donc si vous avez des erreurs ou si vous avez du mal à le faire, envoyez un commentaire et je verrai ce que je peux faire.

+0

Merci c'est une bonne information et je vais essayer. Disons que je veux ralentir les tâches qui se déroulent en arrière-plan. Y a-t-il quelque chose que je puisse ajouter à cela pour exécuter trois ou quatre tâches, puis passer à l'ensemble de serveurs suivant? –

+0

Vous pouvez faire quelque chose comme ça en utilisant une boucle while et des fonctions récursives, mais c'est pénible, si vous voulez restreindre l'accès aux runspaces car ils le fournissent nativement, le lien fourni montre comment les utiliser. –

0

J'ai quelque chose prêt pour les tests, mais il peut casser de façon fantastique. Vous les sorciers là-bas pouvez regarder cela et rire. Si j'ai fait ce mal s'il vous plaît faites le moi savoir.

$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