简体   繁体   English

Powershell - 解析列表中的重复项

[英]Powershell - Parse duplicates in a list

I'm working on an issue with SCCM delivered App-V connection groups.我正在处理 SCCM 提供的 App-V 连接组的问题。 Occasionally it delivers multiple (duplicate) connection groups to the client and the apps don't function correctly.有时,它会向客户端提供多个(重复)连接组,并且应用程序无法正常运行。

I'm running get-appvclientconnectiongroups in user context and where duplicates exist, exporting out Name, Groupid and Version id to a CSV.我在用户上下文中运行get-appvclientconnectiongroups并且存在重复项,将 Name、Groupid 和 Version id 导出到 CSV。

I then import this using an elevated Powershell session (as I need admin rights to remove connection groups).然后我使用提升的 Powershell 会话导入它(因为我需要管理员权限才能删除连接组)。

So CSV headers are所以 CSV 标题是

Name, GroupID, VersionID名称、组 ID、版本 ID

The duplication lies in the Name header only重复仅在 Name 标头中

Eg例如

Name, Group ID, Version ID名称、组 ID、版本 ID

Adobe_Reader, 123, 456 Adobe_Reader, 123, 456

Adobe_Reader, 456, 789 Adobe_Reader, 456, 789

Adobe_Reader, 111, 555 Adobe_Reader, 111, 555

Notepad, 333,222记事本,333,222

Notepad, 111,444记事本,111,444

Receiver, 444,777接收器,444,777

Receiver, 123,999接收器, 123,999

What I would like to do is, for each duplicate name grab, the Group ID and Version ID to use in a remove-appvclientconnectiongroup .我想要做的是,对于每个重复的名称抓取,要在remove-appvclientconnectiongroup使用的组 ID 和版本 ID。 HOWEVER - I don't wish to do this for each entry - I want to stop when there is one left of each name (ie when than name becomes unique in the list).但是 - 我不希望为每个条目都这样做 - 我想在每个名称剩下一个时停止(即当名称在列表中变得唯一时)。

So in the end the list would be:所以最后的清单是:

Adobe_Reader, 111, 555 Adobe_Reader, 111, 555

Notepad, 111,444记事本,111,444

Receiver, 123,999接收器, 123,999

And these are the ones we don't want to run throught the cmdlet这些是我们不想通过 cmdlet 运行的那些

Any ideas?有任何想法吗? APologies if that makes no sense!如果这没有意义,请道歉! I've been playing around with arrays but not getting anywhere fast.我一直在玩数组,但没有得到任何快速的进展。

Assuming you have a CSV file already, you can do the following to return the last item in a group of identical names:假设您已经有一个 CSV 文件,您可以执行以下操作以返回一组相同名称中的最后一项:

Import-Csv file.csv | Group-Object Name |
    Foreach-Object { $_.Group[-1] }

Explanation:解释:

Using Group-Object , you can group objects based on a property value.使用Group-Object ,您可以根据属性值对对象进行分组。 Here, grouping by property Name creates collection of items with properties Count , Name , Group .在这里,按属性Name分组创建具有属性CountNameGroup的项目集合。 Name contains the values of the property you are grouping by. Name包含您分组所依据的属性的值。 Count contains the number of matching values of that grouped property. Count包含该分组属性的匹配值的数量。 Group contains the objects that had matching property values. Group包含具有匹配属性值的对象。

Since the Group property contains your objects, you can access the objects using the member access operator .由于Group属性包含您的对象,您可以使用成员访问运算符来访问这些对象. . . When piping to Foreach-Object , $_.Group will return the object groupings.当管道到Foreach-Object 时$_.Group将返回对象分组。 Then you simply need to grab the last element [-1] of the collection.然后您只需要获取集合的最后一个元素[-1]

If you have that information stored in a CSV file, you can do this to remove all but the last connection group:如果您将该信息存储在 CSV 文件中,则可以执行此操作以删除除最后一个连接组之外的所有连接组:

Import-Csv -Path 'TheGroups.csv'  | Group-Object Name | Where-Object { $_.Count -gt 1 } | Foreach-Object { 
    $last = $_.Count - 2
    # remove all but the last connection group
    $_.Group[0..$last] | Remove-AppvClientConnectionGroup
}

Thanks!谢谢! I managed to get it working with the code below after much messing about.经过一番折腾,我设法让它与下面的代码一起工作。 As there can be multiple instances of duplicates I pushed everything into an editable array which a removes line from as the groups are removed.由于可能有多个重复实例,我将所有内容都推送到一个可编辑的数组中,当组被删除时,该数组将删除行。 It then checks how many duplicates are left for any given package and stops when there's one of each left然后它会检查任何给定的包还剩下多少重复,并在每个都剩下一个时停止

$data = import-csv $env:ALLUSERSPROFILE\AppvDuplciateGroups.csv

#Push the data into an ArrayList so it can be edited on the fly

$dataarray = [System.Collections.ArrayList]($data)

#Get the array size, number of duplicates and target array size

$arraysize = $dataarray.Count

$dupescount = $dataarray| group name

$arraytargetsize = $dupescount.count


$i = $arraysize -1


Function RemoveDuplicates(){

#select the relevant duplicate from the array based in index number (running bottom to top)

$lineX = $dataarray | select -Index $i

 #remove the duplicate

Remove-AppvClientConnectionGroup -GroupId $lineX.groupid -VersionId $lineX.VersionId

 #remove enrty from the array

$dataarray.RemoveAt($i)

 #check to see if that was the last entry for that particular connection group

$getcount = $dataarray | group-object name| Select-Object name, count | where name -eq $lineX.name

 #if there's still more that one entry for that package, run the function again on the next line up

If ($getcount.count -gt 1){

$i = $i -1

RemoveDuplicates}

 #if the array size is still larger than the calculated target array size, move up 2 lines in the array and run the function again

Else{

    If ($dataarray.count -gt $arraytargetsize){

        $i = $i -2

        RemoveDuplicates}

 #once the array meets the calculated target size, repair all connection groups and remove .csv file          

          
          Else{

                Repair-AppvClientConnectionGroup *

                Remove-Item -Path $env:ALLUSERSPROFILE\AppvDuplicateGroups.csv}

}

}

RemoveDuplicates ```


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM