在f#中递归展开AD组

时间:2015-12-17 22:40:12

标签: f# active-directory

我正在编写一个f#脚本来检查System.DirectoryServices.Principal对象是组还是用户。如果它是一个组,我必须递归地获取组中的用户列表,并且如果用户将用户作为列表返回。我写了以下函数

let rec getUserlist (p:Principal) = 
    match box p with 
        | :? UserPrincipal as u -> [u:>Principal]
        | :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value 
            -> g.GetMembers(false).ToArray() 
            |> Seq.map(fun p -> getUserlist p) 
            |> Seq.concat
            |> Seq.toList
        | _ -> []

此功能有效但对我来说看起来不太干净。我想知道是否有更好的方法来编写这个功能。

1 个答案:

答案 0 :(得分:2)

您不需要将其设置为对类型进行模式匹配,使用下载变量u仅将其再次向上播放是没有意义的。

另请注意,map然后concatcollect,您正在转换为数组,然后列出...更好地使用seq并获得所有结果在呼叫站点将其转换为您想要的任何内容。

let rec getUserlist (p:Principal) = 
    match p with 
        | :? UserPrincipal -> Seq.singleton p
        | :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value 
            -> g.GetMembers false |> Seq.collect getUserlist
        | _ -> Seq.empty

如果您愿意,可以使用序列表达式:

let rec getUserlist (p:Principal) = seq {
    match p with 
        | :? UserPrincipal as u -> yield p
        | :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value 
            -> for p in g.GetMembers false do
                    yield! getUserlist p
        | _ -> ()}