我有一个.csv文件,其中包含整个共享邮箱的邮箱委派权限。文件将包含两列,其中提到了电子邮件地址。即谁在邮箱上拥有权限。
E.g。 ColA =共享邮箱,ColB =用户邮箱。
ColA. --- ColB
S1 --- User1
S1 --- User2
S1 --- User3
S2 --- User1
S2 --- User4
S3 --- User3
User1 --- S3
S4 --- User5
S4 --- User6
S5 --- User5
User6 --- S5
要求是通过再创建一列来命名它们。
E.g。
ColA --- ColB. ---ColC
S1 --- User1 ---Batch1
S1 --- User2 ---Batch1
S1 --- User3 ---Batch1
S2 --- User1 ---Batch1
S2 --- User4 ---Batch1
S3 --- User3 ---Batch1
User1 --- S3 ---Batch1
S4 --- User5 ---Batch3
S4 --- User6 ---Batch3
S5 --- User5 ---Batch3
User6 --- S5 ---Batch3
批量命名,如Batch1,2,3&所以基于下面解释的逻辑。
在上面看,例如 用户1,2,3可以访问S1,因此它将是Batch1。
User1再次可以访问S2,因此它将进入Batch1,因为它已经存在于Batch1中。
User4可以访问S2,因此它将进入以前存在于Batch1中的Batch1 coz S2
以同样的方式,所有其他用户都可以访问邮箱,并且应该通过创建上述逻辑进行批处理。
我尝试使用循环编写代码并将它们存储到变量中然后使用compare-object。但它没有帮助我。
根据我的理解,我已经写了一半代码。
$csv = import-csv c:\permlist.csv
$compare = compare-object $csv.colA
$csv.ColB -includeequal Foreach ($x in $compare.name) if
($compare.sideindicator -eq "=>")
{write-output "Exist in column B"} else {write-output "exist in column A"}
答案 0 :(得分:3)
我很无聊,很好奇我是如何管理这个的,所以我继续嘲笑你的文件(并添加了一些内容以确保我会将连续的组分成同一批次,只要有任何连接的用户):
$FileIn = @'
ColA,ColB
S1,User1
S1,User2
S1,User3
S2,User1
S2,User4
S3,User3
User1,S3
S4,User5
S4,User6
S5,User5
User6,S5
S6,User4
S6,User7
S7,User7
S7,User8
'@ -split '[\r\n]+'|convertfrom-csv
然后想出如何将其分批进行分类,确保我循环到足以让任何连接的用户组进入同一批次。
$AccessTo = @{}
$FileIn|Group ColA|%{$AccessTo.add($_.Name,$_.Group.ColB)}
$i=1
ForEach($Box in $AccessTo.Keys){
ForEach($User in $AccessTo[$Box]){
If(($FileIn.ColB|?{$_ -eq $User}|Select -First 1).Batch){Continue}
$BatchUsers = $AccessTo.Keys|?{$AccessTo[$_] -contains $User -or $_ -eq $User}|%{$AccessTo[$_]}|Select -Unique
Do{For($x=0;$x -lt $BatchUsers.Count;$x++){$AccessTo.Keys|?{$AccessTo[$_] -contains $BatchUsers[$x]}|%{$AccessTo[$_]}|?{$_ -notin $BatchUsers}|%{$BatchUsers+=$_}}}Until($x -eq $BatchUsers.count)
$FileIn | ?{$_.ColB -in $BatchUsers -and !$_.Batch}|%{Add-Member -InputObject $_ -NotePropertyName 'Batch' -NotePropertyValue $i}
}
$i=($FileIn.batch|sort|select -last 1)+1
}
最后我得到了:
PS C:\Users\TMTech> $FileIn
ColA ColB Batch
---- ---- -----
S1 User1 1
S1 User2 1
S1 User3 1
S2 User1 1
S2 User4 1
S3 User3 1
User1 S3 1
S4 User5 2
S4 User6 2
S5 User5 2
User6 S5 2
S6 User4 1
S6 User7 1
S7 User7 1
S7 User8 1
编辑:好的,请求了代码细分,所以我们继续。请注意,我使用了一些别名,主要是:?{...}
是Where{...}
的缩写,%{...}
是ForEach-Object{...}
的缩写。
我首先将数据导入PowerShell,然后将其保存到名为$FileIn
的变量中。你将导入一个csv,所以我继续前进。接下来我制作一个空的哈希表。
$AccessTo = @{}
然后我获取导入的数据,按ColA中的值对其进行分组,对于每个分组,我将一个项添加到哈希表中,其中ColA中的值是Key,而Value是一个字符串数组来自COLB。例如,哈希表中的第一项的密钥为S1
,值为User1
,User2
,User3
。 ColA中的每个唯一值都有类似的项目。
一旦我拥有了邮箱,并且有权访问这些邮箱的用户进行了组织和分组,我将继续尝试批量邮箱。我从批处理1开始,所以我设置了一个变量。
$i=1
接下来,我遍历每个$Box
(即哈希表中的每个键)。这是我称之为邮箱循环的外部循环。
ForEach($Box in $AccessTo.Keys){
在邮箱循环中,我有一个内循环,它遍历与该邮箱关联的每个$User
。我称之为用户循环。
ForEach($User in $AccessTo[$Box]){
再次使用示例数据,第一个邮箱为S1
,与之关联的用户为User1
,User2
和User3
。因此,在内部循环中,我首先检查当前用户是否已经为其分配了批次。如果他们这样做,我continue
给下一个用户。
If(($FileIn.ColB|?{$_ -eq $User}|Select -First 1).Batch){Continue}
然后我查看哈希表中的每个项目,如果当前$User
在任何给定邮箱的用户列表中,我输出该邮箱的所有用户。这会传递给Select
命令,该命令只获取唯一值,并在$BatchUsers
中捕获。
$BatchUsers = $AccessTo.Keys|?{$AccessTo[$_] -contains $User -or $_ -eq $User}|%{$AccessTo[$_]}|Select -Unique
此时,我们拥有属于批次的用户的良好基础。现在我只需要确保那些用户不在其他不包含当前$User
的群组中,如果他们是,我也需要从这些其他群组中迭代用户,并且我需要继续这样做,直到我停止吸引更多用户。我打破了这个格式,这更容易阅读:
Do{
For($x=0;$x -lt $BatchUsers.Count;$x++){
$AccessTo.Keys|
?{$AccessTo[$_] -contains $BatchUsers[$x]}|
%{$AccessTo[$_]}|
?{$_ -notin $BatchUsers}|
%{$BatchUsers+=$_}
}
}Until($x -eq $BatchUsers.count)
我从Do
/ Until
循环开始,它将自行运行,直到$BatchUsers.Count
等于我们查看循环的最后一次迭代的用户数(因此它循环直到它找不到其他用户)。在该循环内部,我运行For
循环,该循环从$x=0
开始,循环直到$x
等于$BatchUsers.Count
的当前值。我指定"当前值"因为我们在循环内向$BatchUsers
添加内容。
对于循环的每次迭代,我们再次查看$AccessTo
哈希表中的所有项目
For($x=0;$x -lt $BatchUsers.Count;$x++){
$AccessTo.Keys|
我们检查$x
中的$BatchUsers
项是否在哈希表的该项中。
?{$AccessTo[$_] -contains $BatchUsers[$x]}|
如果是,我们展开哈希表中该项目的所有用户。
%{$AccessTo[$_]}|
然后过滤掉$BatchUsers
中已有的内容。
?{$_ -notin $BatchUsers}|
对于$BatchUsers
中尚未包含的每个人,我们将其添加到$BatchUsers
。
%{$BatchUsers+=$_}
完成Do
/ Until
循环后,我们会找到$FileIn
中隐藏的原始数据。我们迭代查看每条记录,查看ColB
中的值是否在$BatchUsers
中,并确保它没有分配批次。
$FileIn | ?{$_.ColB -in $BatchUsers -and !$_.Batch}
我们将这些记录传递给ForEach-Object
循环,并为每个记录添加一个名为Batch
的属性,其值为$i
(我们用它来跟踪当前批次)
$FileIn | ?{$_.ColB -in $BatchUsers -and !$_.Batch}|%{Add-Member -InputObject $_ -NotePropertyName 'Batch' -NotePropertyValue $i}
现在,当前批次中的每个人都有一个批次值,我们将$i
设置为高于最高批次编号的一个。我最初只是为邮箱循环的每个循环迭代$i
,但是在一个批次中包含多个框,所以我最终得到批处理1和批处理4,它没有生成对我来说很有道理。所以,是的,将下一批次设置为比最后一批更高的一个:
$i=($FileIn.batch|sort|select -last 1)+1
那就是它。如果您有具体问题,请随时提出。