【问题标题】:PowerShell Behaviour for return from Function从函数返回的 PowerShell 行为
【发布时间】:2015-09-01 14:35:25
【问题描述】:

我有一个简单的 CSV 文件。它包含标题和一些值。通常,如果 CSV 文件中有 2 个以上的条目,它会正常工作。如果只有 1 个条目(和标题),它的行为对我来说非常出乎意料。

function ImportServersToProcess($csv) {
    begin {
        [System.Collections.ArrayList] $aServers = @()
    } 

    process {
        $ImportedData = Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD'
        ForEach ($item in $ImportedData){
            [System.Collections.Hashtable] $hServer = @{}

            $hServer.Hostname = $($item.Hostname)
            $hServer.ServiceIP = $($item.ServiceIP)
            $hServer.AdminIP = $($item.AdminIP)
            $hServer.IBRIP = $($item.IBRIP)
            $hServer.HW = $($item.HW)
            $hServer.VMHW = $($item.VMHW)
            $hServer.OS = $($item.OS)
            $hServer.CPUs = $($item.CPUs)
            $hServer.RAM = $($item.RAM)
            $hServer.DriveSizeC = $($item.DriveSizeC)
            $hServer.DriveSizeD = $($item.DriveSizeD)

            if ($hServer.Hostname -eq "Hostname") { continue } # Ignore 1st line/headers
            $aServers.Add($hServer) | Out-Null # OutNull is used to prevent additonal add to array of unexpected object (also suprising output)
        }
        Write-Host "Test0 - " $aServers.Count
        $aServers #| Out-Null
        Write-Host "TEST1 - " $aServers.Count
    }
    end {
    }
}

CSV 看起来像这样:

Hostname;ServiceIP;AdminIP;IBRIP;HW;VMHW;OS;CPUs;RAM;DriveSizeC;DriveSizeD
ash000126;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300
ash000127;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300

然后我使用以下命令运行脚本:

[System.Collections.ArrayList] $aServersToProcess = ImportServersToProcess($csvPath)
[int] $count = $($aServersToProcess.Count)
Write-Host -ForegroundColor Red "[*] There are $count servers to be checked. Starting up [*]"

屏幕上的输出是:

Test0 -  2
TEST1 -  2
[*] There are 2 servers to be checked. Starting up [*]

哪个好。 CSV 格式的 2 台服务器。 2 计数。

现在,如果我从 CSV 中删除 1 个服务器,CSV 现在看起来像这样:

Hostname;ServiceIP;AdminIP;IBRIP;HW;VMHW;OS;CPUs;RAM;DriveSizeC;DriveSizeD
ash000126;1.1.1.191;2.2.2.223;3.3.3.223;System x;Virtual: 01_CL_01;Windows 2012 R2 ;4;16;200;300

注意没有空行等。

脚本的返回是……

Test0 -  1
TEST1 -  1
[*] There are 11 servers to be checked. Starting up [*]

11 是从哪里来的?

如果我修改脚本并在 $aServers 后面添加 $aServers.Count

Write-Host "Test0 - " $aServers.Count        
$aServers 
$aServers.Count
Write-Host "TEST1 - " $aServers.Count

输出是这样的:

Test0 -  1
TEST1 -  1
[*] There are 2 servers to be checked. Starting up [*]

【问题讨论】:

  • 旁注:您没有在函数中使用 $csv 参数。
  • 返回,$aServers 而不是$aServers
  • 哈!你是正确的马蒂亚斯......请尽可能提供答案和解释:-)
  • 好读:Keith Hill 的有效 Powershell 项目 8(查找一元逗号上的文本):rkeithhill.wordpress.com/2007/09/24/…
  • @dugas 谢谢,它使用的是全局值。我更希望 PowerShell 对此有所抱怨。

标签: powershell hashtable return-value


【解决方案1】:

11 来自 CSV 中的标题数量。这是您获取单个对象的问题,而不是在 csv 中包含多个条目的集合。

我认为这里最好的解决方案是将 $ImportedData 类型转换为一个数组,这样如果只有一个元素,它就会变成一个集合,而不是一个对象。

$ImportedData = @(Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD')

这是完成此任务的一种简单方法。另一种方法是:

[Collections.Generic.List[Object]]$ImportedData = Import-CSV $csvPath -Delimiter ';' -Header 'Hostname','ServiceIP','AdminIP','IBRIP','HW','VMHW','OS','CPUs','RAM','DriveSizeC','DriveSizeD'

编辑: 事实证明,看起来问题实际上出在您的返回中,当输出中只有一个对象时,它被作为单个哈希表接收,而不是哈希表数组。在您的 return 语句中使用逗号来强制 return 作为一个集合进行:

,$aServers #| Out-Null

刚刚看到有人在 cmets 中击败了我。

【讨论】:

  • 我都试过了,都没有改变任何东西。请注意我正在返回(期望至少 $aServers 而不是 $importedData。我猜它返回 $aServer 中该 1 个条目的 Hash.Values 的数量。Hrmms
  • 好的,是的,我看到了问题所在。我看得太快了。问题是当你返回 $aServers 时,因为只有一个元素,你的父调用进程将它作为一个对象接收,即使它被转换为一个数组。在你的回报中试试这个:,$aServers #|外空
  • 我已经接受了,即使你应该归功于 Mathias,但我想他没有打扰 ;-)
猜你喜欢
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多