想要使用powershell循环创建逻辑

时间:2018-04-24 19:18:00

标签: powershell exchange-server-2010

我有一个.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"}

1 个答案:

答案 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,值为User1User2User3。 ColA中的每个唯一值都有类似的项目。

一旦我拥有了邮箱,并且有权访问这些邮箱的用户进行了组织和分组,我将继续尝试批量邮箱。我从批处理1开始,所以我设置了一个变量。

$i=1

接下来,我遍历每个$Box(即哈希表中的每个键)。这是我称之为邮箱循环的外部循环。

ForEach($Box in $AccessTo.Keys){

在邮箱循环中,我有一个内循环,它遍历与该邮箱关联的每个$User。我称之为用户循环。

    ForEach($User in $AccessTo[$Box]){

再次使用示例数据,第一个邮箱为S1,与之关联的用户为User1User2User3。因此,在内部循环中,我首先检查当前用户是否已经为其分配了批次。如果他们这样做,我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

那就是它。如果您有具体问题,请随时提出。