Hi there,
I’ve been working on script that will filter out users that have been active in for more than 60min or are disconnected.
For the disconnect script, I used a simple open source script from a MS contributor, found here. The only issue I now have is filtering users based on ID. When my script runs through the server, it does not disconnect the specific user, but rather the entire server. I know the $_.ID variable is key to getting this to work, however; I am not sure how to obtain it from my script values. I’ve included my entire code below, the disconnect properties are at bottom.
Thank you!
function Disconnect-LoggedOnUser { 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 ......' 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' $openservers =@() foreach ($Server in $Servers) { if (-not( Test-Connection $Server -Count 1 -Quiet )) { continue } if (-not( Convert-QueryToObjects $Server -ErrorAction SilentlyContinue)) { $openservers += $server $openservers | Out-File 'H:\demo\session\openservers.txt' } else { Convert-QueryToObjects -Name $Server | Where-Object {@('Active','Disconnected') -contains $_.SessionState} | select @{Name='Server Name';Expression={$_.ComputerName}}, @{Name='Username'; Expression={$_.Username}}, @{Name='Session State'; Expression={$_.SessionState}}, @{Name='Idle Time'; Expression={$_.IdleTime}}, @{Name='ID'; Expression={$_.ID}},@{Name='Logon Time';Expression={$_.LogonTime}} if((Convert-QueryToObjects -Name $Server|?{@('Disconnected') -contains $_.SessionState}) -or (Convert-QueryToObjects -Name $Server|Where-Object{($_.IdleTime -like "*:*") -and ($_.IdleTime -gt "00:59")})) { Disconnect-LoggedOnUser -ComputerName $Server -id 5 -Verbose Write-Output "--------------------------------" } else { continue} } }