PowerShell:从数组

时间:2017-07-05 18:59:52

标签: arrays powershell csv duplicates unique

我正在尝试查找BIND DNS记录中的差异。我想输出一个只有这些差异的CSV文件。我有一个CSV文件,其中包含BIND中所有位置的所有记录(ns.prvt,ns.pub,common,includes)。我想弄清楚的是如何输出只显示差异的CSV。如果2条记录被视为差异,则必须符合以下条件:

  1. 两个记录都具有相同的RecordName和RecordType。
  2. 两个记录都有不同的数据或TTL。
  3. 这两个记录都来自不同的地方。
  4. 我几乎有以下脚本,但它一直向我显示几行不一定符合上述标准。

    $Records = Import-Csv C:\Temp\Domain_ALL.csv | Select * | Sort Data,Location
    $RecordsRev = @()
    $Records | % {
        $Record = $_
        $Records | % {
            $DataFE = $_
            If (
            ([string]($Record | ? {($_.RecordName -eq $DataFE.RecordName)}).RecordName -eq $DataFE.RecordName) -and 
            ([string]($Record | ? {($_.RecordName -eq $DataFE.RecordName)}).RecordType -eq $DataFE.RecordType) -and 
            ([string]($Record | ? {($_.RecordName -eq $DataFE.RecordName)}).Location -ne $DataFE.Location) -and 
            (([string]($Record | ? {($_.RecordName -eq $DataFE.RecordName)}).Data -ne $DataFE.Data) -or 
            ([string]($Record | ? {($_.RecordName -eq $DataFE.RecordName)}).TTL -ne $DataFE.TTL))
            ) {
                $RecordsRev += $_
            }
        }
    }
    $RecordsRev | Export-Csv C:\Temp\Domain_Discrepancies.csv -NoType
    

    我得到的结果是:

    RecordName RecordType Data                           TTL Location
    ---------- ---------- ----                           --- --------
    domain.com TXT        "MS=abc1234566"                600 Includes
    domain.com TXT        "MS=abc1234566"                600 Common  
    domain.com TXT        "site-verification=abcd1234"   600 Includes
    domain.com TXT        "site-verification=abcd1234"   600 Common  
    www        CNAME      somedomain.com.test.           600 Includes
    www        CNAME      somedomain.com.                600 Common
    

    我期望的结果是:

    RecordName RecordType Data                           TTL Location
    ---------- ---------- ----                           --- -------- 
    www        CNAME      somedomain.com.test.           600 Includes
    www        CNAME      somedomain.com.                600 Common
    

    如何删除数组中的所有重复行?这与“Select * -unique”不同,因为我不想保留包含重复信息的任何行。

    编辑:我认为主要的问题是,由于脚本会根据CSV中的每条记录检查每条记录,因此从技术上来说这是一个差异。例如,在下表中,记录1满足条件是不一致的,因为它与记录4不同。但是,由于记录1与记录2相同,因此实际上应该从结果中省略它。

    RecordNumber RecordName RecordType Data                           TTL Location
    ------------ ---------- ---------- ----                           --- --------
    1            domain.com TXT        "MS=abc1234566"                600 Includes
    2            domain.com TXT        "MS=abc1234566"                600 Common  
    3            domain.com TXT        "site-verification=abcd1234"   600 Includes
    4            domain.com TXT        "site-verification=abcd1234"   600 Common  
    5            www        CNAME      somedomain.com.test.           600 Includes
    6            www        CNAME      somedomain.com.                600 Common
    

    非常感谢任何帮助。

    凯尔

1 个答案:

答案 0 :(得分:1)

我能够在删除帖子的人的帮助下解决这个问题......以下是我现在用来查找符合以下所有条件的所有记录的脚本:

  1. 两个记录都具有相同的RecordName和RecordType。 -and
  2. 两个记录都有不同的数据或TTL。 -and
  3. 这两个记录都来自不同的地方。

    $Records = Import-Csv C:\Temp\Domain_ALL.csv | Select * | Sort Data,Location
    $Discrepancies = @()
    $GoodRecords = @()
    $BadRecords = @()
    
    $Records | ForEach-Object { 
    
        # for each record $_, compare it against every other record..
        foreach ($R in $Records) {
    
            # if Both records have the same RecordName and RecordType.. 
            if (($_.RecordName -eq $R.RecordName) -and ($_.RecordType -eq $R.RecordType)) {
    
                # and if Both records come from different locations..
                if ($_.Location -ne $R.Location) {
    
                    # if Both records have the same Data and TTL then they are considered good:
                    if (($_.Data -eq $R.Data) -and ($_.TTL -eq $R.TTL)) {
                        $GoodRecords += $_
                    }
                    Else{
                        # if Both records have different Data or TTL then they are considered bad:
                        $BadRecords += $_
                    }
                }
            }
        }
    
    } 
    
    ForEach ($BadRecord in $BadRecords){
        If (($GoodRecords -notcontains $BadRecord)){
            $Discrepancies += $BadRecord
        }
    }
    $Discrepancies | Select * -Unique | Sort RecordName,Location,Data | ft