迭代对象的属性

时间:2015-09-30 21:07:35

标签: .net powershell properties

我有以下对象:

$restrictedPrograms = @(
    @{DisplayName = "Microsoft Visual Studio Test"};
    @{Guid = "102C29B2-4320-4774-8003-6912F0AC19"};
    @{DisplayName = "Microsoft Office 365 ProPlus - en-us"};
    @{Guid = "B24E0C46-B627-4781-975E-620ED53CD98"};
    @{DisplayName = "SourceTre"; Guid = "B24E0C46-B627-4781-975E-620ED53CD981"}
)

受限制的项目只能有一个属性(DisplayName或Guid)或两者都有。

$installedPrograms = @(
        @{DisplayName = "SourceTree"; Guid = "B24E0C46-B627-4781-975E-620ED53CD981"};
        @{DisplayName = "Microsoft Help Viewer 2.0"; Guid = "FEB375AB-6EEC-3929-8FAF-188ED81DD8B5"}
    )

我想迭代每个installedPrograms并在restrictedPrograms中比较这些属性。我知道如何通过硬编码属性名称(DisplayName和Guid)来实现这一点:

foreach($installedProgram in $installedPrograms)
    {
        foreach($restrictedProgram in $restrictedPrograms)
        {
            if($restrictedProgram.DisplayName -and $restrictedProgram.Guid)
            {
                if(($installedProgram.DisplayName -eq $restrictedProgram.DisplayName) -and ($installedProgram.Guid -eq $restrictedProgram.Guid))
                {
                    return $false;
                }
            }
            else
            {
                if($restrictedProgram.DisplayName)
                {
                    if($installedProgram.DisplayName -eq $restrictedProgram.DisplayName)
                    {
                        return $false;
                    }
                }

                if($restrictedProgram.Guid)
                {
                    if($installedProgram.Guid -eq $restrictedProgram.Guid)
                    {
                        return $false;
                    }
                }
            }
        }
    }

但是我怎么能通过遍历restrictedProgram项的属性来做到这一点,而不是硬编码:

foreach($installedProgram in $installedPrograms)
    {
        foreach($restrictedProgram in $restrictedPrograms)
        {
            // Foreach property in $restrictedProgram, compare it with the corresponding property in $installedProgram ??
        }
    }

2 个答案:

答案 0 :(得分:1)

不确定我是否完全清楚你在结果之后对结果做了什么,但从它的外观来看,你正在寻找$installedPrograms中的任何属性是否存在于{$restrictedPrograms的相同属性值中1}}。我创建了哈希表的PowerShell对象,因为它开辟了许多途径。大多数情况下,我希望能够使用Compare-Object,但由于我不确定您预期的结果,我将其跳过。

$installedPrograms = @(
        @{DisplayName = "SourceTree"; Guid = "B24E0C46-B627-4781-975E-620ED53CD981"};
        @{DisplayName = "Microsoft Help Viewer 2.0"; Guid = "FEB375AB-6EEC-3929-8FAF-188ED81DD8B5"}
) | ForEach-Object{New-Object PSObject -Property $_}

$restrictedPrograms = @(
    @{DisplayName = "Microsoft Visual Studio Test"};
    @{Guid = "102C29B2-4320-4774-8003-6912F0AC19"};
    @{DisplayName = "Microsoft Office 365 ProPlus - en-us"};
    @{Guid = "B24E0C46-B627-4781-975E-620ED53CD98"};
    @{DisplayName = "SourceTree"; Guid = "B24E0C46-B627-4781-975E-620ED53CD981"}
) | ForEach-Object{
    New-Object PSObject -Property @{
        DisplayName = $_.DisplayName
        Guid = $_.Guid
    }
}


$installedPrograms | Where-Object{$_.DisplayName -in $restrictedPrograms.DisplayName -or $_.Guid -in $restrictedPrograms.Guid}

最后一行是最重要的。从它的外观来看,你至少拥有PowerShell 3.0,所以这应该对你有用。对于每个$installedPrograms,我们检查它是否具有匹配的显示名称或guid。如果找到匹配,则通过管道传递。所以我在这里解释的最终结果是安装在计算机上的受限程序列表。

DisplayName Guid                                
----------- ----                                
SourceTree  B24E0C46-B627-4781-975E-620ED53CD981

你曾经提到过,但你想让它变得更有活力。因此,考虑到这一点,我改变了逻辑以允许动态属性。我们在不知道属性是什么的情况下进行比较。为了简单起见,我不打算在同一个vien中重新制作PowerShell对象,因为我不确定你是否对这种方法感兴趣。

$matchedPrograms = @()
$props = ($installedPrograms | Select-Object -First 1).PSObject.Properties | Select-Object -ExpandProperty Name

ForEach($singleProgram in $installedPrograms){
    ForEach($singleProperty in $props){
        # Check to see $singleProperty of $singleProgam is in $restrictedPrograms
        If($singleProgram.$singleProperty -in $restrictedPrograms.$singleProperty){$matchedPrograms += $singleProgram}
    }
}

$matchedPrograms | Select-Object -Unique

由于正在寻找单独匹配,因此可能会有两倍的程序,而-Unique会照顾到它。

答案 1 :(得分:0)

以下代码有所帮助:

foreach($installedProgram in $installedPrograms)
    {
        foreach($restrictedProgram in $restrictedPrograms)
        {
            $count = 0
            foreach($key in $restrictedProgram.Keys)
            {
                if($installedProgram.$key -eq $restrictedProgram.$key)
                {
                    $count++
                }
            }

            if($count -eq $restrictedProgram.Keys.Count)
            {
                Write-Host "Found the restricted program " $restrictedProgram.Values " installed"
                return $false;
            }
        }
    }