I am trying to write a Powershell script that will logoff a currently logged in user. I am using the Invoke-Command
cmdlet with a scriptblock inside of the script.
I defined some parameters in the script that I am trying to pass to the script block but I can quite get it to work.
Here's the script:
param(
[Parameter()]
[string]$ComputerName,
[Parameter()]
[string]$Username
)
$ScriptBlock = {
$ErrorActionPreference = 'Stop'
try {
## Find all sessions matching the specified username
$sessions = quser | Where-Object {$_ -match "$args[0]"}
## Parse the session IDs from the output
$sessionIds = ($sessions -split ' +')[2]
Write-Host "Found $(@($sessionIds).Count) user login(s) on computer."
## Loop through each session ID and pass each to the logoff command
$sessionIds | ForEach-Object {
Write-Host "Logging off session id [$($_)]..."
logoff $_
}
} catch {
if ($_.Exception.Message -match 'No user exists') {
Write-Host "The user is not logged in."
} else {
throw $_.Exception.Message
}
}
}
Invoke-Command -ComputerName $ComputerName -Argumentlist $Username -ScriptBlock $ScriptBlock
I am launching the script like this:
.\Logoff-User.ps1 -Computername some_server -Username some_user
Now this actually works but it logs off a random user (probably not random in all fairness).
The way I understand it is that the (the $Username
) variable from the -ArgumentList
is passed to the scriptblock and it seems to be interpreted correctly. I can print out the $args
variable using the Write-Host
further down and it returns the correct username.
Only using $args
errors out but specifying the first position ($args[0]
) works but disconnects a random user.
I am obviously doing something wrong but I don't understand why. The scripts probably not behaves that way I think it does.
Thanks!