Powershell使用文件夹列表操纵阵列以仅显示最后一个文件夹
我必须为我的工作环境(广告中有500多个用户)设置一个基于Windows的文件共享服务器,我想用powershell实现自动化。我想根据广告层次结构中的OU创建文件夹,然后将权限分配给实际在这些部门工作的人员组。每个ou=部门,有时在部门下有团队,甚至更小的组织单位。因此,我将使用混合文件夹结构,如: 根目录/第1层/第2层/第3层/他们的文件和文件夹 根目录/Tier\u 1/Tier\u 2/其\u文件和\u文件夹 根目录/层1/他们的文件和文件夹 当然,每一层都可以有不同的名称,我希望你能理解 我的问题是,在人们开始使用我的服务器并开始创建他们自己的文件夹后,我不知道如何获取仅由基于广告树的脚本创建的最后文件夹列表(因为我可以基于它们授予权限),这将使我的当前方法无法工作。 我目前的方法是:Powershell使用文件夹列表操纵阵列以仅显示最后一个文件夹,powershell,Powershell,我必须为我的工作环境(广告中有500多个用户)设置一个基于Windows的文件共享服务器,我想用powershell实现自动化。我想根据广告层次结构中的OU创建文件夹,然后将权限分配给实际在这些部门工作的人员组。每个ou=部门,有时在部门下有团队,甚至更小的组织单位。因此,我将使用混合文件夹结构,如: 根目录/第1层/第2层/第3层/他们的文件和文件夹 根目录/Tier\u 1/Tier\u 2/其\u文件和\u文件夹 根目录/层1/他们的文件和文件夹 当然,每一层都可以有不同的名称,我希望你能
Get-childitem "path_to_root_shared_directory" -r -directory | Where-Object {$_.GetDirectories().Count -eq 0}
我想,既然我有一个基于AD创建的文件夹列表(在一个变量数组中),也许我可以通过某种方式操纵该数组,只获得最后的文件夹。我的意思是比较文件夹路径以创建并只保留到没有更多子文件夹(叶文件夹)的文件夹的路径。因此,如果我有如下文件夹结构:
根目录
基层主任/部门主任
总经理/部门/团队
基层主任/部门A/团队B
基层主任/部门主任
只离开:
总经理/部门/团队
基层主任/部门A/团队B
基层主任/部门主任
我希望你们能理解我想要实现的目标;) 以下是一种方法:
Get-ChildItem "C:\RootDirectory" -Directory -Recurse |
ForEach-Object {
if((Get-ChildItem $_.FullName -Directory).Count) {
$_.FullName
}
} | Sort-Object
您将在下面找到第三个解决方案的一个改编,它从开始到完成我需要在列表中逐个查看它们的请求,这样我就可以进行另一个foreach循环并基于它们添加权限 产出:
PS C:\> $dirScan = @(Get-ChildItem C:\test -Recurse -Directory | Select-Object -ExpandProperty FullName | Sort-Object)
PS C:\> $dirScan
C:\test\a-level1
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2
C:\test\c-level1\b-level2\a-level3
PS C:\> Get-MostDepthDirectory $dirScan
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2\a-level3
PS C:\> Get-MostDepthDirectory C:\test
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2\a-level3
PS C:\>
编辑:我添加了一点解释
代码段创建了一个Get-MostDepthDirectory
CmdLet,可以使用要筛选的目录数组或要扫描的目录调用该CmdLet
如果使用要扫描的目录调用(ParameterSetName=“DirectoryScan”
),它将构建一个$subDirectories
变量,其中包含所有子目录的绝对路径,否则(ParameterSetName=“DirectoryScan”
)它将直接从参数获取目录列表
它启动一个System.Collections.ArrayList
对象,它是.NET framework中的一个集合,在这里更合适,因为它有Add
和Remove
方法,允许在不需要知道索引的情况下管理数组内容(否则代码会更复杂)。对象将存储过滤后的列表
然后:
foreach($d)中循环
$子目录)
)$t=Split Path$d-parent
)If($deepestDirectories-NotContains$t)
),则会添加当前目录($deepestDirectories.Add($d)| Out Null
)$deepestDirectories.Remove($t)| Out Null
)并添加目录($deepestDirectories.add($d)| Out Null
)ArrayList
将被排序并转换为字符串数组,然后返回
Out Null
用于阻止ArrayList
对象的Add
和Remove
方法的输出,以将它们的内存状态返回到管道中,否则PowerShell可能会将它们与经过筛选的目录列表一起返回
希望解释更清楚一点。您应该看看这篇文章:我认为这可能很好,但如何使用第三种方法从数组中获取正常的文件夹列表?我需要在一个1乘1的列表中看到它们,这样我就可以进行另一个foreach循环,并根据它们添加权限。谢谢,它可以像我所希望的那样工作(我认为:P)。虽然这对我来说有点复杂。我已经在代码片段上添加了解释。希望有帮助:)很好的解释。如果有人愿意解释的话,我真的很想知道我的代码段出了什么问题?这个解决方案是递归扫描每个目录,每次都计算子目录。它可以工作,但是它消耗了太多的(I/O)资源,随着子目录数量的增加,最终可能会导致整个执行时间非常缓慢;此外,我使用了
Foreach对象
而不是Foreach($collection中的项目)
。。。我现在明白了:)。谢谢
PS C:\> $dirScan = @(Get-ChildItem C:\test -Recurse -Directory | Select-Object -ExpandProperty FullName | Sort-Object)
PS C:\> $dirScan
C:\test\a-level1
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2
C:\test\c-level1\b-level2\a-level3
PS C:\> Get-MostDepthDirectory $dirScan
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2\a-level3
PS C:\> Get-MostDepthDirectory C:\test
C:\test\a-level1\a-level2
C:\test\a-level1\b-level2\a-level3
C:\test\a-level1\b-level2\b-level3
C:\test\a-level1\b-level2\c-level3\a-level4
C:\test\b-level1
C:\test\c-level1\a-level2
C:\test\c-level1\b-level2\a-level3
PS C:\>