遍历对象的属性
Iterating through properties of a object
我有以下对象:
$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 ??
}
}
以下代码有帮助:
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;
}
}
}
不确定我是否完全清楚你在事后对结果做了什么,但从它的外观来看,你正在寻找 $installedPrograms
中的任何属性是否存在于相同的 [=26] =] 的值 $restrictedPrograms
。我将 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
您曾提到过您希望它更具动态性。因此,考虑到这一点,我更改了逻辑以允许动态属性。我们在事先不知道属性是什么的情况下进行比较。为了简单起见,我不会以相同的方式重新制作 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
会处理这个问题。
我有以下对象:
$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 ??
}
}
以下代码有帮助:
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;
}
}
}
不确定我是否完全清楚你在事后对结果做了什么,但从它的外观来看,你正在寻找 $installedPrograms
中的任何属性是否存在于相同的 [=26] =] 的值 $restrictedPrograms
。我将 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
您曾提到过您希望它更具动态性。因此,考虑到这一点,我更改了逻辑以允许动态属性。我们在事先不知道属性是什么的情况下进行比较。为了简单起见,我不会以相同的方式重新制作 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
会处理这个问题。