Powershell - 将多个数组列表传递给 Invoke-Command 块
Powershell - Passing multiple arraylists to Invoke-Command block
我正在尝试编写一个 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。任何帮助将不胜感激。
@Mathias 是正确的;您传递到脚本块中的变量是按值传递(序列化),而不是按引用传递,因此您无法更新它们并更改原始对象。
要使用脚本块中的 return 值,请使用 Write-Object
或仅使用 "use" 值(Write-Object $env:COMPUTERNAME
与 $env:COMPUTERNAME
相同) .
针对您的具体情况,考虑 returning 一个包含您想要的信息的对象:
$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.
我正在尝试编写一个 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。任何帮助将不胜感激。
@Mathias 是正确的;您传递到脚本块中的变量是按值传递(序列化),而不是按引用传递,因此您无法更新它们并更改原始对象。
要使用脚本块中的 return 值,请使用 Write-Object
或仅使用 "use" 值(Write-Object $env:COMPUTERNAME
与 $env:COMPUTERNAME
相同) .
针对您的具体情况,考虑 returning 一个包含您想要的信息的对象:
$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.