Logoff remoto de usuários no Windows com o PowerShell + SONAR
<#
.SYNOPSIS
Logs off user(s) specified. You can't log off a user from the console session.
.DESCRIPTION
Logs off user(s) specified. You can't log off a user from the console session.
.EXAMPLE
-User "Administrator"
Logs off Administrator user.
.EXAMPLE
-User "Administrator","Guest"
Logs off Administrator and Guest users.
.EXAMPLE
PS C:> Logoff-User.ps1 -User "Administrator","Guest"
Logs off Administrator and Guest users.
.OUTPUTS
String[]
.NOTES
Minimum OS Architecture Supported: Windows 10, Windows Server 2016
Release Notes:
#>
[CmdletBinding(SupportsShouldProcess = $True)]
param (
# User name(s) to log off
[Parameter(Mandatory = $true)]
[String[]]
$User
)
begin {
function Test-IsElevated {
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object System.Security.Principal.WindowsPrincipal($id)
if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
{ Write-Output $true }
else
{ Write-Output $false }
}
Function Get-QueryUser() {
Param()
# Replaces all occurrences of 2 or more spaces in a row with a single comma
$Lines = @(query.exe user).foreach({ $(($_) -replace ('s{2,}', ',')) })
$Header = $($Lines[0].split(',').trim())
for ($i = 1; $i -lt $($Lines.Count); $i++) {
$Line = $($Lines[$i].split(',')).foreach({ $_.trim().trim('>') })
# Accounts for disconnected users
if ($Line.count -eq 5) {
$Line = @($Line[0], "$($null)", $Line[1], $Line[2], $Line[3], $Line[4] )
}
$CurUser = [PSCustomObject]::new()
for ($j = 0; $j -lt $($Line.count); $j++) {
$CurUser | Add-Member -MemberType NoteProperty -Name $Header[$j] -Value $Line[$j]
}
$CurUser
}
}
}
process {
if (-not (Test-IsElevated)) {
Write-Error -Message "Access Denied. Please run with Administrator privileges."
exit 1
}
# Get a list of users logged on from query.exe, format it for powershell to process
$QueryResults = Get-QueryUser
# Accounts for only one user logged in
$QueryTest = $($QueryResults | Select-Object -First 1)
if (
$QueryResults.Count -or
(
$QueryTest.USERNAME -is [String] -and
-not [String]::IsNullOrEmpty($QueryTest.USERNAME) -and
-not [String]::IsNullOrWhiteSpace($QueryTest.USERNAME)
)
) {
$script:HasError = $false
$QueryResults | Where-Object {
# For each session filter out the user that weren't specified in $User
$_.UserName -in $User
} | ForEach-Object {
Write-Host "Found Logged In User: $($_.UserName)"
if ($_.SessionName -like "console") {
# We can't log out a user that is at the console.
# We could do this logic in the Where-Object code block, but then there isn't an output of what was skipped.
# https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/logoff#remarks
# "You can't log off a user from the console session."
Write-Host "Skipping user, can't log off a user($($_.UserName)) from the $($_.SessionName) session."
}
else {
# Log off the user session with a matching ID
logoff.exe $_.Id
if ($LASTEXITCODE -gt 0) {
$script:HasError = $true
Write-Error "logoff.exe $($_.Id) returned exit code: $LASTEXITCODE"
}
else {
Write-Host "Logged Off User: $($_.UserName)"
}
}
}
if ($script:HasError) {
exit 1
}
}
else {
Write-Output "No Users Logged In"
exit 2
}
}
end {}
Análise detalhada
Inicialização : O script começa com uma série de comentários, ou '.SYNOPSIS', '.DESCRIPTION' e '.EXEMPLE', que fornecem uma visão geral, uma descrição detalhada e exemplos de uso, respectivamente.
Parâmetros : O bloco param define que o script requer uma entrada ( $User ), que é o(s) nome(s) de usuário(s) para fazer logoff.
Funções : Duas funções principais são definidas:
Test-IsElevated : determina se o script é executado com privilégios de administrador.
Get-QueryUser : Obtém uma lista de usuários conectados usando o comando do Windows query.exe user e, em seguida, formata essa saída para facilitar o consumo pelo PowerShell.
Bloco de Processo : As principais operações ocorrem aqui:
Verificação de permissão : verifica se o script está sendo executado com privilégios administrativos usando Test-IsElevated .
Consulta de sessão : recupera todos os usuários conectados via Get-QueryUser .
Término de Sessão : Itera pela lista de usuários conectados. Se o nome de usuário corresponder ao parâmetro $User fornecido e não for uma sessão de console, ele desconecta esse usuário usando logoff.exe .
Atualizado
Isto foi útil?