J'ai écrit un script qui affinera les utilisateurs qui sont déconnectés ou qui ont un temps d'inactivité supérieur à 60 minutes. J'ai déjà mis en place ces paramètres et le filtre fonctionne bien, cependant; Au lieu de déconnecter l'utilisateur spécifique dans ce serveur, le script déconnecte le serveur comme entierDéconnecter l'utilisateur du serveur en utilisant l'ID de session
J'utilise deux autres fonctions, dont une que j'ai ajoutée directement dans le script. l'autre vient de Get-LoggedOnUser.ps1 Le Disconnect-LoggedOnUser et Get-LoggedOnUser sont destinés à fonctionner ensemble. J'ai gardé les instructions pour le script de déconnexion. J'ai inclus mon script complet dans ce GitHub gist
Toute aide ou suggestion est grandement appréciée! Tout le code correspondant ci-dessous:
Description
-----------
This command dot sources the script to ensure the Disconnect-LoggedOnUser function is available in your current PowerShell session
.EXAMPLE
Disconnect-LoggedOnUser -ComputerName server01 -Id 5
Description
-----------
Disconnect session id 5 on server01
.EXAMPLE
.\Get-LoggedOnUser.ps1 -ComputerName server01,server02 | Where-Object {$_.UserName -eq 'JaapBrasser'} | Disconnect-LoggedOnUser -Verbose
< script #My #>
<#
.SYNOPSIS
Convert output from CMD's 'query.exe user' to usable objects.
.DESCRIPTION
Take the text based output returned by 'query.exe user' and convert it to objects that can be manipulated in PowerShell.
.PARAMETER Name
Computer name to run query.exe against.
.EXAMPLE
PS C:\> Convert-QueryToObjects -Name server01
ComputerName Username SessionState SessionType
------------ -------- ------------ -----------
server01 bobsmith Disconnected
server01 janedoe Active tcp-rdp
#>
function Disconnect-LoggedOnUser {
<#
.SYNOPSIS
Function to disconnect a RDP session remotely
.DESCRIPTION
This function provides the functionality to disconnect a RDP session remotely by providing the ComputerName and the SessionId
.PARAMETER ComputerName
This can be a single computername or an array where the RDP sessions will be disconnected
.PARAMETER Id
The Session Id that that will be disconnected
.NOTES
Name: Disconnect-LoggedOnUser
Author: Jaap Brasser
DateUpdated: 2015-06-03
Version: 1.0
Blog: http://www.jaapbrasser.com
.LINK
http://www.jaapbrasser.com
.EXAMPLE
. .\Disconnect-LoggedOnUser.ps1
Description
-----------
This command dot sources the script to ensure the Disconnect-LoggedOnUser function is available in your current PowerShell session
.EXAMPLE
Disconnect-LoggedOnUser -ComputerName server01 -Id 5
Description
-----------
Disconnect session id 5 on server01
.EXAMPLE
.\Get-LoggedOnUser.ps1 -ComputerName server01,server02 | Where-Object {$_.UserName -eq 'JaapBrasser'} | Disconnect-LoggedOnUser -Verbose
Description
-----------
Use the Get-LoggedOnUser script to gather the user sessions on server01 and server02. Where-Object filters out only the JaapBrasser user account and then disconnects the session by piping the results into Disconnect-LoggedOnUser while displaying verbose information.
#>
param(
[Parameter(
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
Position=0
)]
[string[]]
$ComputerName,
[Parameter(
Mandatory,
ValueFromPipelineByPropertyName
)]
[int[]]
$Id
)
begin {
$OldEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
}
process {
foreach ($Computer in $ComputerName) {
$Id | ForEach-Object {
Write-Verbose "Attempting to disconnect session $Id on $Computer"
try {
rwinsta $_ /server:$Computer
Write-Verbose "Session $Id on $Computer successfully disconnected"
} catch {
Write-Verbose 'Error disconnecting session displaying message'
Write-Warning "Error on $Computer, $($_.Exception.Message)"
}
}
}
}
end {
$ErrorActionPreference = $OldEAP
}
}
function Convert-QueryToObjects
{
[CmdletBinding()]
[Alias('QueryToObject')]
[OutputType([PSCustomObject])]
param
(
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[Alias('ComputerName', 'Computer')]
[string]
$Name = $env:COMPUTERNAME
)
Process
{
Write-Verbose "Running query.exe against $Name."
$Users = query user /server:$Name 2>&1
if ($Users -like "*No User exists*")
{
# Handle no user's found returned from query.
# Returned: 'No User exists for *'
Write-Error "There were no users found on $Name : $Users"
Write-Verbose "There were no users found on $Name."
}
elseif ($Users -like "*Error*")
{
# Handle errored returned by query.
# Returned: 'Error ...<message>...'
Write-Error "There was an error running query against $Name : $Users"
Write-Verbose "There was an error running query against $Name."
}
elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue')
{
# Handdle null output called by -ErrorAction.
Write-Verbose "Error action has supressed output from query.exe. Results were null."
}
else
{
Write-Verbose "Users found on $Name. Converting output from text."
# Conversion logic. Handles the fact that the sessionname column may be populated or not.
$Users = $Users | ForEach-Object {
(($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1 none $2' -replace "\s{2,}", "," -replace "none", $null))
} | ConvertFrom-Csv
Write-Verbose "Generating output for $($Users.Count) users connected to $Name."
# Output objects.
foreach ($User in $Users)
{
Write-Verbose $User
if ($VerbosePreference -eq 'Continue')
{
# Add '| Out-Host' if -Verbose is tripped.
[PSCustomObject]@{
ComputerName = $Name
Username = $User.USERNAME
SessionState = $User.STATE.Replace("Disc", "Disconnected")
SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
IdleTime = $User.'IDLE TIME'
ID = $User.ID
LogonTime =$User.'Logon Time'
} | Out-Host
}
else
{
# Standard output.
[PSCustomObject]@{
ComputerName = $Name
Username = $User.USERNAME
SessionState = $User.STATE.Replace("Disc", "Disconnected")
SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
IdleTime = $User.'IDLE TIME'
LogonTime = $User.'Logon Time'
ID = $User.ID
}
}
}
}
}
}
$Servers = Get-Content 'H:\demo\computernames.txt'
$Queries = foreach ($Server in $Servers) {
#Query each server that pings, save it in a variable for reuse
if (Test-Connection $Server -Count 1 -Quiet) {
Convert-QueryToObjects $Server -ErrorAction SilentlyContinue
}
}
#Open servers are ones that responded to the query.
$Queries |
Select-Object -ExpandProperty ComputerName -Unique |
Out-File 'H:\demo\session\openservers.txt'
#Use the saved query information, filter with Where-Object, loop over to disconnect.
$Queries |
Where-Object { ($_.SessionState -eq 'Disconnected') -or (($_.IdleTime -like "*:*") -and ($_.IdleTime -gt "00:59"))} |
ForEach-Object {
Disconnect-LoggedOnUser -ComputerName $_.ComputerName -Id $_.ID -Verbose
}
Il fait exactement ce que vous lui dites. 'H: \ WindowsPowerShell \ Get-LoggedOnUser.ps1 -ComputerName $ Serveur | Disconnect-LoggedOnUser -Verbose 'n'est pas filtré avec' Where-Object' à tous. Donc va tout déconnecter. – BenH
@BenH Je voulais dire que j'ai essayé d'ajouter 'Where-Object {$ _. ID -eq' $ Id '}' mais ça ne semble pas fonctionner. est-ce que je m'approche mal? merci – russell
L'utilisation de guillemets simples ne permet pas l'évaluation des variables. Mais cela ne résout qu'une seule pièce, l'autre pièce est d'où vous obtenez «$ ID». – BenH