尝试将 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)
上面的示例缺少正确的错误处理,因此如果无法访问远程系统,您将收到错误消息,但这只是一个开始。
我有一些使用 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)
上面的示例缺少正确的错误处理,因此如果无法访问远程系统,您将收到错误消息,但这只是一个开始。