我正在尝试编写一个powershell脚本,告诉我网络中的计算机是打开还是关闭,如果打开,是否有人登录。目前我有:
# Create some empty arraylists
$availablecomputers = New-Object System.Collections.ArrayList
$unavailablecomputers = New-Object System.Collections.ArrayList
$usersloggedon = New-Object System.Collections.ArrayList
#Check connectivity for each machine via Test-WSMan
foreach ($computer in $restartcomputerlist)
{
try
{
Test-WSMan -ComputerName $computer -ErrorAction Stop |out-null
Invoke-Command `
-ComputerName $computer `
-ScriptBlock `
{
if
((Get-WmiObject win32_computersystem).username -like "AD\*")
{
$args[0] += $computer
}
else
{
$args[1] += $computer
}
} `
-ArgumentList (,$usersloggedon), (,$availablecomputers)
}
catch
{
$unavailablecomputers += $computer
}
}
到目前为止,如果计算机未开启,则可正常工作。但是,如果它打开,$ computer将不会被添加到$ usersloggedon或$ availablecomputers。任何帮助将不胜感激。
答案 0 :(得分:1)
@Mathias是正确的;传递给scriptblock的变量按值(序列化)传递,而不是通过引用传递,因此您无法更新它们并更改原始对象。
要从scriptblock返回值,请使用Write-Object
或只是简单地使用"使用"值{Write-Object $env:COMPUTERNAME
与刚才$env:COMPUTERNAME
}相同。
针对您的具体情况,请考虑返回包含所需信息的对象:
$computers = @()
#Check connectivity for each machine via Test-WSMan
foreach ($computer in $restartcomputerlist)
{
try
{
Test-WSMan -ComputerName $computer -ErrorAction Stop |out-null
$computers += Invoke-Command -ComputerName $computer -ScriptBlock {
$props = @{
Name = $env:COMPUTERNAME
Available = $true
UsersLoggedOn = ((Get-WmiObject win32_computersystem).username -like "AD\*")
}
New-Object PSObject -Property $props
}
}
catch
{
$props = @{
Name = $computer
Available = $false
UsersLoggedOn = $false
}
$computers += New-Object PSObject -Property $props
}
}
$computers # You can now use this with Select-Object, Sort-Object, Format-* etc.