Powershell:奇怪的数组/哈希表copyTo行为

时间:2016-02-03 09:38:54

标签: powershell

我尝试在计算机上枚举已安装的软件。我主要在远程系统上使用注册表中的一些键来执行此操作。我写的函数在某些机器上工作正常,但在其他机器上却没有。问题似乎是将数组从散列表复制到PSCustomObject类型的数组。 为了避免双重条目(在注册表中查询32位和64位配置单元),我生成了一个哈希表,其中包含一个由软件名称和版本组成的密钥。然后在将数据添加到哈希表之前检查密钥是否已存在。在处理结束时,我将哈希表的值复制到预先分配的数组。这是代码:

Function Get-InstalledSoftware
{
[CmdletBinding()]
param (
    [ValidateNotNull()]
    [Parameter(Mandatory = $true)]
    [string]$ComputerName
)

$RegistryLocation = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\',
'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'
$htSoftware = @{ }

$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $ComputerName)
foreach ($CurrentReg in $RegistryLocation)
{
    if ($RegBase)
    {
        $CurrentRegKey = $RegBase.OpenSubKey($CurrentReg)
        if ($CurrentRegKey)
        {
            foreach ($key in $CurrentRegKey.GetSubKeyNames())
            {
                $newreglocation = $CurrentReg + $key + '\'
                $cv = $RegBase.OpenSubKey($newreglocation)

                if ($cv.GetValue('DisplayName') -ne $null)
                {
                    $software = [PSCustomObject]@{
                        'Name' = $cv.GetValue('DisplayName')
                        'Version' = $cv.GetValue('DisplayVersion')
                        'Publisher' = $cv.GetValue('Publisher')
                        'Installationsort' = $cv.GetValue('InstallLocation')
                        'Installationsdatum' = $cv.GetValue('InstallDate')
                    }
                }
                #$arrSoftware += $software
                $hashkey = $cv.GetValue('DisplayName') + "_" + $cv.GetValue('DisplayVersion')
                if (!$htSoftware.ContainsKey($hashkey))
                {
                    $htSoftware.Add($hashkey, $software)
                }
            }
        }
    }
}

[PSCustomObject[]]$arrSoftware = (1..$htSoftware.Count)
$htSoftware.Values.CopyTo($arrSoftware, 0)
$arrSoftware
}

然后使用一些辅助函数将返回的数组填充到gridview中:

    $form_computer_details.UseWaitCursor = $true
    [System.Windows.Forms.Application]::DoEvents()
    $soft = Get-InstalledSoftware -ComputerName $ComputerName
    if ($soft -ne $null)
    {
        $table = ConvertTo-DataTable -InputObject $soft
        Load-DataGridView -DataGridView $datagridview_sw -Item $table
    }
    else
    {
        $richtextbox_ComputerInfoMsg.Text = "Konnte keine Daten aus der Registry des Computers $ComputerName lesen."    
    }
    $form_computer_details.UseWaitCursor = $false

经过更长时间的调试会话后,问题出现在我的函数中这两行代码:

    [PSCustomObject[]]$arrSoftware = (1..$htSoftware.Count)
$htSoftware.Values.CopyTo($arrSoftware, 0)

在运行它的机器上,调试器在声明和初始化后显示变量$ arrSoftware的以下内容:

"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40"

在CopyTo命令之后,数组看起来像这样:

$arrSoftware    "@{Name=Microsoft Visual Studio 2010 Shell (Isolated) - ENU; Version=10.0.40219; Publisher=Microsoft Corporation; Installationsort=; Installationsdatum=20151128}", "@{Name=Microsoft SQL Server 2014 RsFx Driver; Version=12.0.2000.8; Publisher=Microsoft Corporation; Installationsort=; Installationsdatum=20151128}", .....

(我截断了输出.....)

在机器上, NOT 工作时,它看起来如下:

"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"

好到目前为止,但现在复制后:

(Empty)

$arrSoftware.count在调试器中显示以下结果:

$arrSoftware.count  22

当我查看数组的第一个元素时,我看到以下内容:

$arrSoftware[0] @{Name=7-Zip 9.20 (x64 edition); Version=9.20.00.0; Publisher=Igor Pavlov; Installationsort=; Installationsdatum=20130526}
$arrSoftware[1] @{Name=Altaro Backup FS; Version=2.0.26.0; Publisher=Altaro; Installationsort=; Installationsdatum=20131221}
....
$arrSoftware[20]    @{Name=Microsoft Visual C++ 2012 x86 Additional Runtime - 11.0.61030; Version=11.0.61030; Publisher=Microsoft Corporation; Installationsort=; Installationsdatum=20151219}

有趣的是,22的大小的最后一个元素应该是[21],这是EMPTY!

知道这里出了什么问题吗?

0 个答案:

没有答案