我编写了一个脚本,用于优化断开连接或空闲时间超过60分钟的用户。我已经设置了这些参数,但过滤器运行良好;该脚本不是断开该服务器中的特定用户,而是将服务器断开连接为整体
我正在使用另外两个函数,其中一个我直接添加到脚本中。另一个来自Get-LoggedOnUser.ps1 Disconnect-LoggedOnUser和Get-LoggedOnUser旨在协同工作。我保留了注销脚本的说明。我已将此完整脚本包含在此GitHub gist
中非常感谢任何帮助或建议! 以下所有相关代码:
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
< #My script#>
<#
.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
}
答案 0 :(得分:2)
问题是H:\WindowsPowerShell\Get-LoggedOnUser.ps1 -ComputerName $Server| Disconnect-LoggedOnUser -Verbose
未使用Where-Object
进行过滤。因此,您需要保存需要断开连接的用户会话的信息,然后使用该过滤后的信息断开连接。
这是一种接近它的方法,内联评论。
$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"))} |
ForEachObject {
Disconnect-LoggedOnUser -ComputerName $_.ComputerName -Id $_.ID -Verbose
}