Попытка добавить PSCustomObjects в ArrayList на удаленной машине

У меня есть некоторый опыт работы с PowerShell, и обычно Google или поисковые форумы, подобные этим, дают ответы, когда у меня есть вопросы - но не в этот раз.

Я пытаюсь собрать количество файлов.log в каталоге на удаленном сервере, затем я хочу сохранить местоположение (букву диска и путь к папке) и количество в списке массивов для дальнейшего использования. Пока все работает так, как я ожидал, но у меня проблемы с добавлением моих объектов PSCustomObject в список массивов. Я не уверен, что это потому, что я выполняю на удаленном сервере или что-то еще вызывает проблему. Вот мой код:

$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) Я избегаю синтаксической ошибки, но вместо этого получаю сообщение о том, что не могу вызвать метод для выражения с нулевым значением.

Я пытался создать ArrayList внутри Invoke-Command и я пытался использовать New-Object вместо PSCustomObject но безрезультатно.

2 ответа

Решение

Я думаю, что ваши вещи немного смешаны, это будет делать:

$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'
  • Hashtables, как $MyHash=@{}; $MyHash.SomeKey = 'SomeValue' или как вы указали $MyHash.Add('SomeKey', 'SomeValue')
  • ArrayLists заполнены как [System.Collections.ArrayList]$MyArrayList = @(); $MyArrayList.Add('SomeValue')

Я надеюсь, что это делает это немного более ясным. Возвращаемые значения всегда можно отследить до Invoke-Command или даже перед простым foreach (), Например $result = 0..3 | ForEach-Object {$_} тоже совершенно верно.

Вам действительно нужно вернуть ваш объект из удаленной системы в вашу локальную систему, поскольку вы не можете использовать ваш $ 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)

В приведенном выше примере отсутствует надлежащая обработка ошибок, поэтому вы получите сообщение об ошибке, если удаленная система недоступна, но это начало.

Другие вопросы по тегам