#powershell #invoke-command
#powershell #вызов-команда
Вопрос:
Я пытаюсь написать сценарий Powershell, который отключит текущего пользователя, вошедшего в систему. Я использую Invoke-Command
командлет со скриптовым блоком внутри скрипта.
Я определил некоторые параметры в скрипте, которые я пытаюсь передать в блок сценария, но я вполне могу заставить его работать.
Вот сценарий:
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
Я запускаю скрипт следующим образом:
.Logoff-User.ps1 -Computername some_server -Username some_user
Теперь это действительно работает, но он выходит из системы от случайного пользователя (вероятно, не случайного, если честно).
Насколько я понимаю, переменная (the $Username
) из -ArgumentList
передается в scriptblock и, похоже, интерпретируется правильно. Я могу распечатать $args
переменную, используя Write-Host
далее вниз, и она возвращает правильное имя пользователя.
Работает только с использованием $args
ошибок, но с указанием первой позиции ( $args[0]
), но отключает случайного пользователя.
Я, очевидно, делаю что-то не так, но я не понимаю, почему. Скрипты, вероятно, ведут себя не так, как я думаю.
Спасибо!
Комментарии:
1. Изменить
{$_ -match "$args[0]"}
на{$_ -match "b$([regex]::Escape($args[0]))b"}
2. Зачем использовать
$args[0]
, если вы определили$Username
для него именованный параметр?3. @MathiasR.Jessen Спасибо за ответ, я попробовал другое предложение, но оно не сработало. Похоже, что переменная содержит не имя пользователя, а «заголовок» столбца в выходных данных (выход из сеанса id [SESSION])
4. @Noct03 Тогда кажется, что имя пользователя, которое вы предоставляете, — это не просто строка, содержащая имя пользователя, но, вероятно, вывод таблицы форматов для объекта. Проверьте, что вы отправляете в скрипт, это должно быть 2 строки
5. @Noct03 Да, я знаю, но я подозреваю, что вы не отправляете строку. Проверьте, что у вас есть
some_user
. Это определенно не просто имя пользователя, возможно, объект или строковое представление объекта.
Ответ №1:
Я понял это благодаря Тео. $Username
Переменная, которую я использовал в скрипте, была неправильно передана в scriptblock. Мне пришлось переопределить параметр внутри блока скрипта, который затем использовал -Argument
бы из Invoke-Command
для передачи переменной в виде строки (чего первый скрипт также не делал.
Вот окончательный сценарий:
param(
[Parameter()]
[string]$ComputerName,
[Parameter()]
[string]$Username
)
$ScriptBlock = {
param($User)
$ErrorActionPreference = 'Stop'
try {
## Find all sessions matching the specified username
$sessions = quser | Where-Object {$_ -match $User}
## 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
Затем я смог запустить скрипт по мере необходимости:
.Logoff-User.ps1 -Computername some_server -Username some_user
Спасибо Тео и всем остальным за вашу помощь!