使用 PowerShell 从目录(带有子项)获取最新文件

使用 PowerShell 从目录(带有子项)获取最新文件

意图/任务

从嵌套目录结构中检索最新文件。假设给定以下目录结构:

X:\Archive\SSL-Certificates\    
                            foo.example.com\
                                            2014\cert-10457879297372006618810300677.pem
                                            2016\cert-13677147326148109482722985339.pem
                                            2019\cert-12284327752958698998181242513.pem
                                            2020\cert-12335167671983512419735879508.pem
                                            2021\cert-12482084320823734707339770201.pem
                            bar.example.com\
                                            2017\cert-10767600219438996090564087606.pem
                                            2019\cert-11211589658854057466031159348.pem
                                            2021\cert-11671143093416928819383653766.pem
                            baz.example.com\
                                            2019\cert-10572485377335948619489409340.pem

我目前拥有的脚本:

$path = "X:\Archive\SSL-Certificates\"
$directories = Get-ChildItem $path -Directory -Recurse
foreach ($directory in $directories)
{
    if (([array]$directory.EnumerateDirectories()).count -eq 0)
    {
        #If it has no directory inside, then it's one of the folders we need to analyse
        Get-ChildItem $directory.FullName -Filter "cert*.pem" | Select-Object FullName
    }
}

不幸的是,这个脚本有以下限制:

  1. 它显示所有年份的所有文件,而它应该只返回最新的(即最近)每个域一个文件

  2. 完整路径长度超过 85 个字符后,它会删除尾随字符,将其替换为三个点。即使将其传输到类似这样的文件,也会发生这种情况get_certificates.ps1 > cert_list.txt

以下是关于剥离路径的摘录:

X:\Archive\SSL-Certificates\subdomain.example.com\2012\cert-1198403086374501969...
X:\Archive\SSL-Certificates\foo.example.com\2019\cert-1228432775295869899818124...
X:\Archive\SSL-Certificates\foo.example.com\2021\cert-1248208432082373470733977...
X:\Archive\SSL-Certificates\bar.example.com\2017\[...]
X:\Archive\SSL-Certificates\bar.example.com\2019\[...]
and so on [...]

预期结果

从上面给出的示例目录结构中,预计以下列表包含完整路径和每个域(不是年份)的最新文件。域表示foo.example.combar.example.combaz.example.com

因此,脚本应该只返回(近期)文件领域

X:\Archive\SSL-Certificates\foo.example.com\2021\cert-12482084320823734707339770201.pem
X:\Archive\SSL-Certificates\bar.example.com\2021\cert-11671143093416928819383653766.pem
X:\Archive\SSL-Certificates\baz.example.com\2019\cert-10572485377335948619489409340.pem

(修订)问题

为了让挑战更加清晰,我把重点放在一个目录上,即域foo.example.com。子文件夹2014, 2016, 2019, 2020包含过期的证书,而子文件夹2021包含最新的、因此有效的证书。

总共有以下目录和文件(请记住,此示例仅限于路径,X:\Archive\SSL-Certificates\foo.example.com以便于理解应该实现什么结果):

X:\Archive\SSL-Certificates\foo.example.com\2014\cert-10457879297372006618810300677.pem
X:\Archive\SSL-Certificates\foo.example.com\2016\cert-13677147326148109482722985339.pem
X:\Archive\SSL-Certificates\foo.example.com\2019\cert-12284327752958698998181242513.pem
X:\Archive\SSL-Certificates\foo.example.com\2020\cert-12335167671983512419735879508.pem
X:\Archive\SSL-Certificates\foo.example.com\2021\cert-12482084320823734707339770201.pem

该脚本应遍历所有目录/文件以识别最新/最近的证书。根据上面的五个子文件夹,它应该返回仅有的最近的文件包括完整路径,如下所示:

X:\Archive\SSL-Certificates\foo.example.com\2021\cert-12482084320823734707339770201.pem

为了将结果传递到openssl进一步处理,需要包含完整路径的文件名。

答案1

阅读你的问题并查看文件夹结构,你只想获取第一级的目录。
然后,Get-ChildItem再次使用递归获取文件并选择最新的文件。

尝试

Get-ChildItem -Path 'X:\Archive\SSL-Certificates' -Directory | ForEach-Object {
    (Get-ChildItem -Path $_.FullName -Filter 'cert*.pem' -File -Recurse |
     Sort-Object LastWriteTime | Select-Object -Last 1).FullName
}

答案2

您可以在 foreach 循环内使用此命令:

gci | sort LastWriteTime | select -last 1 | % { $_.FullName }

相关内容