[英]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
分组创建具有属性Count
、 Name
、 Group
的项目集合。 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.