尝试将 PSCustomObjects 添加到远程计算机上的 ArrayList

Trying to add PSCustomObjects to an ArrayList on a remote machine

我有一些使用 PowerShell 的经验,当我有问题时,通常 Google 或搜索此类论坛会得到答案 - 但这次不会。

我正在尝试收集远程服务器目录中 .log 文件的数量,然后我想将位置(驱动器盘符和文件夹路径)和计数存储在数组列表中以备后用.到目前为止,一切都如我所料,但我 运行 在将我的 PSCustomObjects 添加到数组列表时遇到了麻烦。我不确定是因为我在远程服务器上执行还是其他原因导致了问题。这是我的代码:

$server = Read-Host -Prompt 'Please enter the server name'
[System.Collections.ArrayList]$returnObj = @()

Invoke-Command -ComputerName $server {
    $drives = Get-PSDrive -PSProvider FileSystem |
              Where-Object {$_.Description -like "ExVol*"} |
              Select-Object Root

    foreach ($d in $drives) {
        Set-Location -Path $d.Root
        $folders = Get-ChildItem -Path $d.Root |
                   Where-Object {$_.Name -like "*.log"} |
                   Select-Object Name
        foreach ($f in $folders) {
            $count = (Get-ChildItem -Path $f.Name).Count

            $obj = [PSCustomObject]@{
                LogFolder = $d.Root.Trim() + $f.Name
                LogFileCount = $count
            }
            Write-Host $obj
            $returnObj.Add($obj | Select-Object DatabaseFolder,LogFileCount)
        }
    }
}
$returnObj

在这种格式中,我在行中遇到语法错误

$returnObj.Add($obj | Select-Object DatabaseFolder,LogFileCount)

如果我将上面的行更改为 $returnObj.Add($obj) 我避免了语法错误,但我收到一条错误消息说我不能在空值表达式上调用方法。

我试过在 Invoke-Command 中创建 ArrayList,我试过使用 New-Object 而不是 PSCustomObject 无济于事。

我认为你的混合材料有点复杂,这样就可以了:

$returnObj = Invoke-Command -ComputerName $server {
    $drives = Get-PSDrive -PSProvider FileSystem |
              Where-Object {$_.Description -like "ExVol*"} |
              Select-Object Root

    foreach ($d in $drives) {
        Set-Location -Path $d.Root

        $folders = Get-ChildItem -Path $d.Root |
                   Where-Object {$_.Name -like "*.log"} |
                   Select-Object Name

        foreach ($f in $folders) {
            $count = (Get-ChildItem -Path $f.Name).Count

            [PSCustomObject]@{
                LogFolder = $d.Root.Trim() + $f.Name
                LogFileCount = $count
            }
        }
    }

}
$returnObj

问题出在这一行:

[System.Collections.ArrayList]$returnObj = @()

Invoke-Command -ScriptBlock 之外声明。这意味着它在远程机器上的会话中不可用,因此不能在那里使用。

附带说明一下,您不能像用数据填充 Hashtable 那样填充 array

  • 数组像$MyArray = @(); $MyArray += 'MyValue'
  • 那样填充
  • 哈希表,如 $MyHash=@{}; $MyHash.SomeKey = 'SomeValue' 或如您所述 $MyHash.Add('SomeKey', 'SomeValue')
  • ArrayLists 的填充方式类似于 [System.Collections.ArrayList]$MyArrayList = @(); $MyArrayList.Add('SomeValue')

我希望这能让它更清楚一点。 return 值总是可以在 Invoke-Command 之前甚至在简单的 foreach () 之前被捕获。例如 $result = 0..3 | ForEach-Object {$_} 也完全有效。

您实际上需要 return 您的对象从远程系统到您的本地系统,因为您不能在远程会话中使用您的 $returnObj。

举个例子:

$returnValue = Invoke-Command -ComputerName $server {

    $obj = [PSCustomObject]@{
        LogFolder = $d.Root.Trim() + $f.Name
        LogFileCount = $count
    }

    #return the object via the pipline
    $obj 
}

$returnObj.Add($returnValue | Select-Object DatabaseFolder,LogFileCount)

上面的示例缺少正确的错误处理,因此如果无法访问远程系统,您将收到错误消息,但这只是一个开始。