2
votes

I'm trying to create a script to delete all files in a folder and it's subfolders that are older than 45 days - I know how to do this, the problem is the parent folder in question has several links to other folders within itself - how do I prevent the script from deleting the links (as a link is a file), but instead treats the links like folders and to look "inside" the links for files older than 45 days.

If that's not possible, then is it possible to create a dynamic variable or array so that the script looks inside each folder I need it to and delete any files older than 45 days? If so, how do I do that.

Currently my only other option would be to create a separate script for each folder (or create code for each script in one file) and either call them individually or use yet another script to call each script.

For reference, this is in a Windows Server 2008 R2 environment

2
Really? Why the downvote? Seems like a valid question to me. It's even doable, but you would need to resort to using the WScript.Shell COM object to do it.EBGreen

2 Answers

2
votes

I can't work out a full solution right now. If I get time I'll come back and edit with one. Essentially I would create a function that would call itself recursively for folders anf for links where the .TargetPath was a folder. The creation of the recursive function is pretty standard fair. The only slightly opaque part is getting the .TargetPath of a .lnk file:

$sh = New-Object -COM WScript.Shell
$sc = $sh.CreateShortcut('E:\SandBox\ScriptRepository.lnk')
$targetPath = $sc.TargetPath

That is the PS way. The VBScript version is pretty much the same with a different variable naming convention and a different method for COM object instantiation.

So here is a more complete solution. I have not set up test folders and files to test it completely, but it should be pretty much what you need:

function Remove-OldFile{
    param(
            $Folder
         )
    $sh = New-Object -COM WScript.Shell
    foreach($item in Get-ChildItem $Folder){
        if ($item.PSIsContainer){
            Remove-OldFile $item.FullName
        }elseif($item.Extension -eq '.lnk'){
            Remove-OldFile $sh.CreateShortcut($item.FullName).TargetPath
        }else{
            if(((Get-Date) - $item.CreationTime).Days -gt 45){
                $item.Delete()
            }
        }
    }
}

Remove-OldFile C:\Scripts

Just for completeness, here is an untested off the cuff VBS solution. I warn you that it may have some syntax errors, but the logic should be fine.

RemoveOldFiles "C:\Scripts"

Sub RemoveOldFiles(strFolderPath)
    Dim oWSH : Set oWSh = CreateObject("WScript.Shell")
    Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")

    For Each oFolder in oFSO.GetFolder(strFolderPath).SubFolders
        RemoveOldFiles oFolder.Path
    Next
    For Each oFile in oFSO.GetFolder(strFolderPath).Files
        if LCase(oFSO.GetExtensionName(oFile.Name)) = "lnk" Then
            RemoveOldFiles oWSH.CreateShortcut(oFile.Path).TargetPath
        Else
            If DateDiff("d", oFile.DateCreated, Date) > 45 Then
                oFSO.DeleteFile(oFile)
            End If
        End If
    Next
End Sub
0
votes

Very high level answer:

Loop through all files in current folder.
If `file.name` ends with `.lnk` (we have a link/shortcut).
Get the path of the shortcut with `.TargetPath`

You can now pass .TargetPath the same way you would pass the name of a subdirectory when you find one to continue recursing through the directory tree.