对于一个CSV中的每件事,请检查另一种CSV中的多种匹配类型

时间:2019-02-04 20:29:03

标签: powershell csv

很抱歉,如果描述不清楚,但我想不出其他措辞。

我有两个CSV文件:

LocalAdmins.csv-ColumnA = PC名称; ColumnB =本地管理员组中的用户名

PC names and local admin usernames for each PC

Exempt.csv-ColumnA = PC名称; ColumnB =允许用户名成为本地管理员

PC names and allowed local admin usernames for each PC

我想做的是遍历LocalAdmins.csv,并检查每个PC名称是否显示在Exempt.csv中(或匹配该文件中定义的命名模式),以及是否匹配找到后,请检查Exempt.csv中该PC的AllowedUsers列表中是否显示该PC在LocalAdmins.csv中的本地管理员用户名。

如果用户名不在AllowedUsers列表中,或者PC名称不在Exempt.csv中,则从LocalAdmins.csv输出条目。这是我到目前为止的内容:

$admins = Import-Csv .\LocalAdmins.csv
$exempt = Import-Csv .\Exempt.csv
$violations = ".\Violations.csv"

foreach ($admin in $admins) {
    foreach ($item in $exempt) {
        if ($admin.PC -like $item.PC) {
            if ($admin.Name -notin ($item.AllowedUsers -split ",")) {
                $admin | Export-Csv $violations -Append -NoTypeInformation
            }
        }
        else {
            $admin | Export-Csv $violations -Append -NoTypeInformation
        }
    }
}

问题是嵌套的foreach循环会生成重复项,这意味着如果Exempt.csv中有3行,则LocalAdmins.csv中的单个条目将具有3个重复输出(Exempt.csv中的每一行一个)。所以输出看起来像这样:

Current output

何时应如下所示:

Desired output

我猜测问题出在循环结构的某个地方,但是我只需要一些帮助来确定要调整的内容。任何输入,我们将不胜感激!

2 个答案:

答案 0 :(得分:1)

未优化(按 any 属性进行唯一排序应该起作用):

$admins = Import-Csv .\LocalAdmins.csv
$exempt = Import-Csv .\Exempt.csv
$violations = ".\Violations.csv"

$(
    foreach ($admin in $admins) {
        foreach ($item in $exempt) {
            if ($admin.PC -like $item.PC) {
                if ($admin.Name -notin ($item.AllowedUsers -split ",")) {
                    $admin
                }
            }
            else {
                $admin
            }
        }
    }
) | Sort-Object -Property PC, Name -Unique  | 
            Export-Csv $violations -Append -NoTypeInformation

答案 1 :(得分:1)

在forEach受到更好的限制的情况下,不应重复重复
无需排序-unique。

从此处字符串获取输入

## Q:\Test\2019\02\05\SO_54523868.ps1
$admins = @'
PC,NAME
XYZlaptop,user6
workstationXYZ,user7
computerABC,user8
ABClaptop,user1
'@ | ConvertFrom-Csv # .\LocalAdmins.csv

$exempt = @'
PC,AllowedUsers
*laptop,"user1,user2"
computerXYZ,"user3,user4"
workstation*,"user5"
'@ | ConvertFrom-Csv # .\Exempt.csv

$violationsFile = ".\Violations.csv"

$violations = foreach ($admin in $admins) {
    $violation = $True
    foreach ($item in ($exempt|Where-Object {$admin.PC -like $_.PC})){
        if ($admin.NAME -in ($item.AllowedUsers -split ',')){
            $violation = $False
        }
    }
    if ($violation){$admin}    
}
$violations
$violations | Export-Csv $violationsFile -NotypeInformation
## with Doug Finke's ImportExcel module  installed, you can directly get the excel file:
#$violations | Export-Excel .\Violatons.xlsx -AutoSize -Show