在脚本块

问题描述

我正在尝试编写Powershell脚本,该脚本将注销当前登录用户。我正在将Invoke-Command cmdlet与脚本内的脚本块一起使用。

我在脚本中定义了一些要传递给脚本块的参数,但是我可以使它正常工作。

这是脚本:

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

在这确实可行,但是它会注销一个随机用户(出于公平考虑,可能不是随机的)。

据我了解,它是将$Username中的{-ArgumentList)变量传递到脚本块,并且似乎可以正确地解释它。我可以进一步使用$args打印出Write-Host变量,它会返回正确的用户名

仅使用$args会出错,但是指定第一个位置($args[0])可以但会断开随机用户的连接。

我显然做错了,但我不明白为什么。这些脚本的行为可能不像我认为的那样。

谢谢!

解决方法

感谢Theo,我弄清楚了。我在脚本中使用的$Username变量未正确传递到脚本块。我必须在脚本块内重新定义一个参数,然后使用-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

感谢西奥和其他所有人的帮助!