1

Intention/Task

Retrieve the newest file from a nested directory structure. Let's assume the following given directory structure:

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

The script I have so far:

$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
    }
}

Unfortunately, this script comes along with the following constraints:

  1. It shows all files from all years, whereas it should only return the latest (i. e. recent) file per domain.

  2. After a full path length of 85 characters it strips the trailing characters by replacing it with three dots. This happens even if its piped to a file like get_certificates.ps1 > cert_list.txt

Here is an excerpt about the stripped path:

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 [...]

Expected result

From the example directory structure given above the following list with the full path and the latest (i. e. newest) file per domain (not year) is expected. Domain means foo.example.com, bar.example.com and baz.example.com.

So, the script should return only one (the recent) file per domain:

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

(Revised) Question

In order to make the challenge more clear let me throw the spot on one single directory, the domain foo.example.com. The subfolders 2014, 2016, 2019, 2020 contain outdated certificates, whereas the subfolder 2021 carries the newest and therefore valid certificate.

In total there are the following directories and files (remember, this example is restricted to the path X:\Archive\SSL-Certificates\foo.example.com to ease the understanding what result should be achieved):

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

The script should iterate over all directories/files in order to recognize the newest/recent certificate. Based on the five subfolders above it should return only the recent file including the full path as shown below:

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

The file name including the full path is needed in order to pass the result to openssl for further processing.

2 Answers 2

0

Reading your question and looking at the folder structure, you only want to get the directories in the first level.
Then, use Get-ChildItem again to recursively get the files and select the newest one.

Try

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
}
3
  • Thanks for your effort, @Theo. Unfortunately, your suggested code returns multiple directories/files for a domain whereas it should return only one (the latest/recent one). In order to make the needed result more clear have a look at the revised question.
    – HRitter
    Commented Jan 9, 2022 at 9:01
  • @HRitter Just tested it again and... The code above returns only one (the newest) file per domain folder. Exactly as you asked for. Did you try it at all? or is the folder structure different from what you show us?
    – Theo
    Commented Jan 9, 2022 at 12:24
  • 1
    As there are hundreds of subdirectories I tried it with a reduced hierarchy which gave me a missleading output. In fact, your code works perfectly. Thus, thank you one more time for your effort and patience! I mark your code as accepted answer.
    – HRitter
    Commented Jan 10, 2022 at 14:06
0

You could use this command inside the foreach loop:

gci | sort LastWriteTime | select -last 1 | % { $_.FullName }
1
  • Just replacing the line Get-ChildItem $directory.FullName -Filter "cert*.pem" | Select-Object FullName with gci | sort LastWriteTime | select -last 1 | % { $_.FullName } doesn't give any results. So I replaced the line Get-ChildItem $directory.FullName -Filter "cert*.pem" | Select-Object FullName with Get-ChildItem $directory.FullName -Filter "cert*.pem" | sort LastWriteTime | select -last 1 | % { $_.FullName } which still returns multiple entries for a domain with different years.
    – HRitter
    Commented Jan 5, 2022 at 19:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .