Powershell query - list all old files in set of folders

Nancy J 41 Reputation points
2022-04-07T14:03:50.39+00:00

I need to build a script that does the following:

1 - Checks if a network drive is mapped, if it is not then it maps it.
2 - Lists all folders in the root of a network drive
3 - For each folder in that list, it exports a list of all files older than 7 years to a CSV
4 - Renames the CSV files

I put together something that works when I specify a folder in part 3 but if I try to make it work with a foreach it just hangs.

How do I modify this so I get 1 CSV file for each root folder on the network drive? Lines 27-31 are not commented out on my side, not sure why they show as commented when I paste the code here.

This is the code:

#Variables
$testmapdrive = "S:\test" 
$folderpath = "S:\"+$Name
$csvpath = "S:\IT Records\Data Lifecycle Reviews\2022-04"
$csvfilename = $csvpath + "\" + $Name + ".csv"
$minage = (get-date).AddYears(-7)

#Check if S:\ mapped, if not it maps the drive

If (Test-Path -Path $testmapdrive) {
    Write-Host "Drive Exists already"
}
Else {
    #map network drive
    (New-Object -ComObject WScript.Network).MapNetworkDrive("s:","\\dfspath\dfs")

    #check mapping again
    If (Test-Path -Path $testmapdrive) {
        Write-Host "Drive has been mapped"
    }
    Else {
        Write-Host "Something went very wrong"
    }
}

#Get folder names and generate lists of files in each older than 7 years
$folder = Get-ChildItem -Path "S:\" -Depth 0 | Select Name
foreach ($Name in $folder)
{
Get-ChildItem -Path $folderpath -File -Recurse -Force -ErrorAction SilentlyContinue | ?{$_.lastwritetime -lt $minage} | Select Directory,Name,CreationTime,LastWriteTime| Export-csv $csvfilename -NoTypeInformation
}
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,355 questions
0 comments No comments
{count} votes

Accepted answer
  1. Andreas Baumgarten 95,496 Reputation points MVP
    2022-04-07T21:22:24.96+00:00

    Hi @Nancy J ,

    the issue why your script is not working ist this:

    191123-image.png

    This script below works here. I just modified the path and removed the | Select Name in line 6. Also make sure the folders records and 2022-04 exists in file system.

    #Variables   
    $rootfolder = "C:\Junk"  
    $csvpath = "C:\Junk\records\2022-04"  
    #Get folder names and generate lists of files in each  
    $folder = Get-ChildItem -Path $rootfolder -Depth 0 -Directory  
    foreach ($Name in $folder) {  
      $Name  
      $folderpath = "$rootfolder\$Name"  
      $csvfilename = "$csvpath\$Name.csv"  
      Get-ChildItem -Path $folderpath -Recurse -Force -ErrorAction SilentlyContinue |  
       Select-Object Directory, Name, CreationTime, LastWriteTime |  
        Export-Csv $csvfilename -NoTypeInformation  
    }  
    

    ----------

    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten


5 additional answers

Sort by: Most helpful
  1. Andreas Baumgarten 95,496 Reputation points MVP
    2022-04-07T14:38:44.023+00:00

    Hi @Nancy J ,

    you are setting the $folderpath variable containing the $Name variable at the beginning in your script (line 3). At this time the $Name variable should be still empty ($Name will be set in the foreach (line 28).
    I would suggest to move the line 3 in the foreach part. like this, and try again:

     foreach ($Name in $folder)  
     {  
      $folderpath = "S:\"+$Name  
     Get-ChildItem -Path $folderpath -File -Recurse -Force -ErrorAction SilentlyContinue | ?{$_.lastwritetime -lt $minage} | Select Directory,Name,CreationTime,LastWriteTime| Export-csv $csvfilename -NoTypeInformation  
     }  
    

    ----------

    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    0 comments No comments

  2. Nancy J 41 Reputation points
    2022-04-07T14:49:01.363+00:00

    Hi Andreas,

    I get the same result with that change.

    In the foreach, I tried replacing
    Get-ChildItem -Path $folderpath -File -Recurse -Force -ErrorAction SilentlyContinue | ?{$_.lastwritetime -lt $minage} | Select Directory,Name,CreationTime,LastWriteTime| Export-csv $csvfilename -NoTypeInformation

    with

    write-host $Name
    write-host "next"

    and it correctly lists each folder name followed by the word next

    Based on that, I suspect the problem is somewhere in my get-childitem command. This comand works if I replace $folderpath with a set folder (i.e. S:\tech) but not with the variable.

    0 comments No comments

  3. Andreas Baumgarten 95,496 Reputation points MVP
    2022-04-07T18:40:22.87+00:00

    Hi @Nancy J ,

    I just modified a part of your script for my needs and run it successful (different folder, different $minage):

    $testFolder = "C:\Junk"  
    $minage = (Get-Date).AddDays(-7)  
    $folder = Get-ChildItem -Path "C:\Junk" -Depth 0 -Directory  
    $csvfilename = $csvpath + "\" + $Name + ".csv"  
    foreach ($Name in $folder) {  
      $Name   
      $folderpath = "$testFolder\$Name"  
      $csvfilename = "$testfolder\$Name.csv"  
      Get-ChildItem -Path $folderpath -Recurse -Force -ErrorAction SilentlyContinue |  
       Where-Object { $_.lastwritetime -lt $minage } |   
       Select-Object Directory, Name, CreationTime, LastWriteTime |  
       Export-Csv $csvfilename -NoTypeInformation  
    }  
    

    Maybe you like to test it.

    ----------

    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    0 comments No comments

  4. Nancy J 41 Reputation points
    2022-04-07T19:36:14.74+00:00

    Thank you, I really appreciate the assistance with this.

    Unfortunately, I get the same result wth your modifications.

    The first get-childitem returns a list of 30 folders which are in the root of the S:\ drive for us, this is correct.

    I am expecting (or wanting) the second get-childitem that is under the foreach to output 30 separate CSV files, one for each of those folders containing a listing of files in that folder.

    I do see it generate the first CSV with the expected file name but it just sits at 0 bytes forever. I am logged in with a user that has full access to all of the folders on the drive (I can access each through explorer). It works if I specify the folder, it's only when I use the variable that it hangs.

    As a test, I stripped it down to the bare minimum to generate the files but it still doesn't work:

    #Variables 
    $rootfolder = "S:"
    $csvpath = "S:\records\2022-04"
    
    #Get folder names and generate lists of files in each
    $folder = Get-ChildItem -Path "S:\" -Depth 0 -Directory | Select Name
    foreach ($Name in $folder)
    {
    $Name
    $folderpath = "$rootfolder\$Name"
    $csvfilename = "$csvpath\$Name.csv"
    Get-ChildItem -Path $folderpath -Recurse -Force -ErrorAction SilentlyContinue | Export-Csv $csvfilename -NoTypeInformation
    }
    
    0 comments No comments