PowerShell-如何判断两个对象是否相同

PowerShell-如何判断两个对象是否相同,powershell,object,if-statement,conditional,equality,Powershell,Object,If Statement,Conditional,Equality,假设有两个相同的对象,这意味着它们分别具有相同的属性和值 你如何测试平等性 范例 $obj1和$obj2是相同的 以下是我尝试过的: if($obj1 -eq $obj2) { echo 'true' } else { echo 'false' } # RETURNS "false" if(Compare-Object -ReferenceObject $obj1 -DifferenceObject $obj2) { echo 'true' } else { e

假设有两个相同的对象,这意味着它们分别具有相同的属性和值

你如何测试平等性

范例

$obj1和$obj2是相同的

以下是我尝试过的:

if($obj1 -eq $obj2)
{
    echo 'true'
} else {
    echo 'false'
}
# RETURNS "false"

if(Compare-Object -ReferenceObject $obj1 -DifferenceObject $obj2)
{
    echo 'true'
} else {
    echo 'false'
}
# RETURNS "false"
编辑

这是不一样的

我建议使用Compare对象执行此任务:

Function Test-Objects
{
    Param(
    [Parameter(Mandatory,Position=0)]
    [PSCustomObject]$Obj1,
    [Parameter(Mandatory,Position=1)]
    [PSCustomObject]$Obj2
    )

    [Void](Compare-Object -ReferenceObject $Obj1.PSObject.Properties -DifferenceObject.PSObject.Properties $Obj2 -OutVariable 'Test')

    ## Tests whether they are equal, no return = success
    If (-not $Test)
    {
        $True
    }
    Else
    {
        $False
    }
}
我建议使用Compare对象执行此任务:

Function Test-Objects
{
    Param(
    [Parameter(Mandatory,Position=0)]
    [PSCustomObject]$Obj1,
    [Parameter(Mandatory,Position=1)]
    [PSCustomObject]$Obj2
    )

    [Void](Compare-Object -ReferenceObject $Obj1.PSObject.Properties -DifferenceObject.PSObject.Properties $Obj2 -OutVariable 'Test')

    ## Tests whether they are equal, no return = success
    If (-not $Test)
    {
        $True
    }
    Else
    {
        $False
    }
}
通过使用“比较对象”比较两个PSObject对象的属性,可以比较两个PSObject对象的属性和值是否相等。例如:

if ( -not (Compare-Object $obj1.PSObject.Properties $obj2.PSObject.Properties) ) {
  "object properties and values match"
}
else {
  "object properties and values do not match"
}
如果要将其包含在函数中:

function Test-PSCustomObjectEquality {
  param(
    [Parameter(Mandatory = $true)]
    [PSCustomObject] $firstObject,

    [Parameter(Mandatory = $true)]
    [PSCustomObject] $secondObject
  )
  -not (Compare-Object $firstObject.PSObject.Properties $secondObject.PSObject.Properties)
}
通过使用“比较对象”比较两个PSObject对象的属性,可以比较两个PSObject对象的属性和值是否相等。例如:

if ( -not (Compare-Object $obj1.PSObject.Properties $obj2.PSObject.Properties) ) {
  "object properties and values match"
}
else {
  "object properties and values do not match"
}
如果要将其包含在函数中:

function Test-PSCustomObjectEquality {
  param(
    [Parameter(Mandatory = $true)]
    [PSCustomObject] $firstObject,

    [Parameter(Mandatory = $true)]
    [PSCustomObject] $secondObject
  )
  -not (Compare-Object $firstObject.PSObject.Properties $secondObject.PSObject.Properties)
}

我编写了一个函数来检查是否完全相等:

 function Global:Test-IdenticalObjects
 {
    param(
        [Parameter(Mandatory=$true)]$Object1,
        [Parameter(Mandatory=$true)]$Object2,
        $SecondRun=$false
    )

    if(-not ($Object1 -is [PsCustomObject] -and $Object2 -is [PsCustomObject))
    {
        Write-Error "Objects must be PsCustomObjects"
        return
    }

    foreach($property1 in $Object1.PsObject.Properties)
    {
        $prop1_name = $property1.Name
        $prop1_value = $Object1.$prop1_name
        $found_property = $false
        foreach($property2 in $Object2.PsObject.Properties)
        {
            $prop2_name = $property2.Name
            $prop2_value = $Object2.$prop2_name
            if($prop1_name -eq $prop2_name)
            {
                $found_property = $true
                if($prop1_value -ne $prop2_value)
                {
                    return $false
                }
            }
        } # j loop
        if(-not $found_property) { return $false }
    } # i loop
    if($SecondRun)
    {
        return $true
    } else {
        Test-IdenticalObjects -Object1 $Object2 -Object2 $Object1 -SecondRun $true
    }
 } # function

我编写了一个函数来检查是否完全相等:

 function Global:Test-IdenticalObjects
 {
    param(
        [Parameter(Mandatory=$true)]$Object1,
        [Parameter(Mandatory=$true)]$Object2,
        $SecondRun=$false
    )

    if(-not ($Object1 -is [PsCustomObject] -and $Object2 -is [PsCustomObject))
    {
        Write-Error "Objects must be PsCustomObjects"
        return
    }

    foreach($property1 in $Object1.PsObject.Properties)
    {
        $prop1_name = $property1.Name
        $prop1_value = $Object1.$prop1_name
        $found_property = $false
        foreach($property2 in $Object2.PsObject.Properties)
        {
            $prop2_name = $property2.Name
            $prop2_value = $Object2.$prop2_name
            if($prop1_name -eq $prop2_name)
            {
                $found_property = $true
                if($prop1_value -ne $prop2_value)
                {
                    return $false
                }
            }
        } # j loop
        if(-not $found_property) { return $false }
    } # i loop
    if($SecondRun)
    {
        return $true
    } else {
        Test-IdenticalObjects -Object1 $Object2 -Object2 $Object1 -SecondRun $true
    }
 } # function

以下是我使用的函数:

function Test-ObjectEquality {
    param(
        [Parameter(Mandatory = $true)]
        $Object1,
        [Parameter(Mandatory = $true)]
        $Object2
    )

    return !(Compare-Object $Object1.PSObject.Properties $Object2.PSObject.Properties)
}
示例:

PS C:\> $obj1 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
True
PS C:\> $obj2 = [psobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = New-Object -TypeName PSObject -Property @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
True
PS C:\> $obj2 = [pscustomobject] @{ 'c' = '6'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 8; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; c = 8 };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = '7'; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
我当然相信这是有可能错过的事情;但是,如果查看属性中的内容,可以看到对象上每个属性的比较内容:

PS C:\> $obj1.PSObject.Properties | Select-Object -First 1


MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : 5
TypeNameOfValue : System.String
Name            : a
IsInstance      : True
我通常只关心对象属性的MemberType、Name、TypeNameOfValue或Value


另外,请注意,如果确实需要,可以比较.PSObject.Members而不是.PSObject.Properties。这将比较属性和方法,尽管您只是比较方法调用而不是方法定义。

以下是我使用的函数:

function Test-ObjectEquality {
    param(
        [Parameter(Mandatory = $true)]
        $Object1,
        [Parameter(Mandatory = $true)]
        $Object2
    )

    return !(Compare-Object $Object1.PSObject.Properties $Object2.PSObject.Properties)
}
示例:

PS C:\> $obj1 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
True
PS C:\> $obj2 = [psobject] @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = New-Object -TypeName PSObject -Property @{ 'a' = '5'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
True
PS C:\> $obj2 = [pscustomobject] @{ 'c' = '6'; 'b' = 7; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 8; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = 7; c = 8 };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
PS C:\> $obj2 = [pscustomobject] @{ 'a' = '5'; 'b' = '7'; };
PS C:\> Test-ObjectEquality $obj1 $obj2
False
我当然相信这是有可能错过的事情;但是,如果查看属性中的内容,可以看到对象上每个属性的比较内容:

PS C:\> $obj1.PSObject.Properties | Select-Object -First 1


MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : 5
TypeNameOfValue : System.String
Name            : a
IsInstance      : True
我通常只关心对象属性的MemberType、Name、TypeNameOfValue或Value


另外,请注意,如果确实需要,可以比较.PSObject.Members而不是.PSObject.Properties。这将比较属性和方法,尽管您只是比较方法调用,而不是方法定义。

如果您想测试每个对象属性的相等性,一次一个,以便比较和对比两个对象,并查看哪些单独的部分不同,您可以使用以下函数,改编自这篇关于如何

函数比较对象属性{ Param [PSObject]$leftObj, [PSObject]$rightObj $leftProps=$leftObj.PSObject.Properties.Name $rightProps=$rightObj.PSObject.Properties.Name $allProps=$leftProps+$rightProps |排序|选择-唯一 $props=@ $allProps中的foreach$propName{ 测试是否有道具 $leftHasProp=$propName-in$leftProps $rightHasProp=$propName-in$rightProps 从对象获取值 $leftVal=$leftObj.$propName $rightVal=$rightObj.$propName 创建自定义输出- $prop=[pscustomobject]@{ Match=$If$propName-eq SamAccountName{1st}Else{ $If$leftHasProp-和!$rightHasProp{Left}Else{ $If$rightHasProp-和!$leftHasProp{Right}Else{ $If$leftVal-eq$rightVal{Same}Else{Diff} } } } PropName=$PropName LeftVal=$LeftVal RightVal=$RightVal } $props+=$prop } 排序和格式化表格宽度 $props |排序对象匹配,PropName |格式表-属性` @{Expression={$\.Match};Label=Match;Width=6}, @{Expression={$\.PropName};Label=Property Name;Width=25}, @{Expression={$\ LeftVal};Label=左值;Width=40}, @{Expression={$\.RightVal};Label=Right值;Width=40} } 然后像这样使用:

$adUser1=获取ADUser'Grace.Hopper'-Properties* $adUser2=获取ADUser'Katherine.Johnson'-Properties* 比较对象属性$adUser1$adUser2 两个有趣的注意事项:

尝试使用或对输出着色,但无法使其使用具有优先级的固定列宽
如果您想测试每个对象属性的相等性,一次测试一个,以便比较和对比两个对象,并查看哪些单独的部分是不同的,您可以使用下面的函数,该函数改编自关于如何

函数比较对象属性{ Param [PSObject]$leftObj, [PSObject]$rightObj $leftProps=$leftObj.PSObject.Properties.Name $rightProps=$rightObj.PSObject.Properties.Name $allProps=$leftProps+$rightProps |排序|选择-唯一 $props=@ $allProps中的foreach$propName{ 测试是否有道具 $leftHasProp=$propName-in$leftProps $rightHasProp=$propNam e-in$rightProps 从对象获取值 $leftVal=$leftObj.$propName $rightVal=$rightObj.$propName 创建自定义输出- $prop=[pscustomobject]@{ Match=$If$propName-eq SamAccountName{1st}Else{ $If$leftHasProp-和!$rightHasProp{Left}Else{ $If$rightHasProp-和!$leftHasProp{Right}Else{ $If$leftVal-eq$rightVal{Same}Else{Diff} } } } PropName=$PropName LeftVal=$LeftVal RightVal=$RightVal } $props+=$prop } 排序和格式化表格宽度 $props |排序对象匹配,PropName |格式表-属性` @{Expression={$\.Match};Label=Match;Width=6}, @{Expression={$\.PropName};Label=Property Name;Width=25}, @{Expression={$\ LeftVal};Label=左值;Width=40}, @{Expression={$\.RightVal};Label=Right值;Width=40} } 然后像这样使用:

$adUser1=获取ADUser'Grace.Hopper'-Properties* $adUser2=获取ADUser'Katherine.Johnson'-Properties* 比较对象属性$adUser1$adUser2 两个有趣的注意事项:

尝试使用或对输出着色,但无法使其使用具有优先级的固定列宽
使用Compare Object-IncludeEqual,否则它只会告诉您差异。否则,如果没有返回,它就是成功的。@theincorgible1不完全是我想要的。如果我将属性添加到$obj1,-IncludeEqual仍将返回$truecheck我的答案。它应该按照您的期望工作。不要发布图片输出。使用代码格式并将输出粘贴为文本。@我没有否决你的问题。可能是因为您使用图片而不是粘贴输出文本,所以其他人投了反对票?但不是我;我认为这是一个好问题。使用Compare Object-IncludeEqual,否则它只会告诉你区别。否则,如果没有返回,它就是成功的。@theincorgible1不完全是我想要的。如果我将属性添加到$obj1,-IncludeEqual仍将返回$truecheck我的答案。它应该按照您的期望工作。不要发布图片输出。使用代码格式并将输出粘贴为文本。@我没有否决你的问题。可能是因为您使用图片而不是粘贴输出文本,所以其他人投了反对票?但不是我;我觉得这是个好问题。如果你这么做$obj1 |添加成员-NotePropertyName'NewProperty'-NotePropertyValue'NewValue'。。。如果运行上面的代码,它仍然认为$obj1等于$obj2,即使它们不是。我刚刚测试了它比较对象使用ToString进行比较-这是不可靠的。使用$obj1=[pscustomobject]@{'a'='5';'b'=7;}$obj2=[pscustomobject]@{'c'='6';'b'=7;}例如,它说它们是相等的。请看:@KolobCanyon这是事实上错误的。在我的测试v2,v5中,它工作正常。为什么如果-不是$Test{$true}或者{$false}当你可以简单地编写时-不是$Test?@Bill_Stewart我太专注于他的问题示例了,但你绝对正确说你这样做$obj1 |添加成员-NotePropertyName'NewProperty'-NotePropertyValue'NewValue'。。。如果运行上面的代码,它仍然认为$obj1等于$obj2,即使它们不是。我刚刚测试了它比较对象使用ToString进行比较-这是不可靠的。使用$obj1=[pscustomobject]@{'a'='5';'b'=7;}$obj2=[pscustomobject]@{'c'='6';'b'=7;}例如,它说它们是相等的。请看:@KolobCanyon这是事实上错误的。在我的测试v2,v5中,它工作正常。为什么如果-不是$Test{$true}或者{$false}当你可以简单地编写时-不是$Test?@Bill_Stewart我太专注于他的问题示例,但你绝对正确1不推荐全局:范围ID。2大量不必要的工作和开销;一个比较对象可以看到我的答案。1不推荐全局:范围ID。2大量不必要的工作和开销;一个比较对象可以看到我的答案。