1

我有一些使用 PowerShell 的经验,当我有问题时,通常谷歌或类似的搜索论坛会产生答案 - 但这次不是。

我正在尝试在远程服务器上的目录中收集 .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)避免语法错误,但我得到一个错误,说我不能在空值表达式上调用方法。

我尝试在内部创建 ArrayListInvoke-Command并且尝试使用New-Object而不是PSCustomObject无济于事。

4

2 回答 2

1

我认为您的混合内容有点高,这会:

$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. 这意味着它在远程机器上的会话中不可用,因此不能在那里使用。

附带说明一下,您不能像填写数据array一样填写Hashtable数据。

  • 数组填充像$MyArray = @(); $MyArray += 'MyValue'
  • $MyHash=@{}; $MyHash.SomeKey = 'SomeValue'像您所指出的那样的哈希表$MyHash.Add('SomeKey', 'SomeValue')
  • ArrayLists 填充为[System.Collections.ArrayList]$MyArrayList = @(); $MyArrayList.Add('SomeValue')

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

于 2018-08-07T13:50:10.157 回答
0

您实际上需要将对象从远程系统返回到本地系统,因为您不能在远程会话中使用 $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)

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

于 2018-08-07T13:55:53.167 回答