Question

I'm writing a PowerShell script that deletes all but the X most recent folders, excluding a folder named Data. My statement to gather the folders to delete looks like this:

$folders1 = Get-ChildItem $parentFolderName | 
     ? { $_.PSIsContainer -and $_.Name -ne "Data" } | 
     sort CreationTime -desc | 
     select -Skip $numberOfFoldersToKeep

foreach ($objItem in $folders1) {
    Write-Host $webServerLocation\$objItem
    Remove-Item -Recurse -Force $parentFolderName\$objItem -WhatIf
}

This works great when I pass a $numberOfFoldersToKeep that is fewer than the number of folders in the starting directory $parentFolderName. For example, with 5 subdirectories in my target folder, this works as expected:

myScript.ps1 C:\StartingFolder 3

But if I were to pass a high number of folders to skip, my statement seems to return the value of $parentFolderName itself! So this won't work:

myScript.ps1 C:\StartingFolder 15

Because the skip variable exceeds the number of items in the Get-ChildItem collection, the script tries to delete C:\StartingFolder\ which was not what I expected at all.

What am I doing wrong?

Was it helpful?

Solution

try this:

$folders1 = Get-ChildItem $parentFolderName | 
     ? { $_.PSIsContainer -and $_.Name -ne "Data" } | 
     sort CreationTime -desc | 
     select -Skip $numberOfFoldersToKeep
    if ($folder1 -neq $null)

{

foreach ($objItem in $folders1) {


        Write-Host $($objItem.fullname)




 Remove-Item -Recurse -Force $objItem.fullname -WhatIf
    }
    }

OTHER TIPS

I gave @C.B. credit for the answer, but there's another way to solve the problem, by forcing the output of Get-ChildItem to an array using the @( ... ) syntax.

$folders1 = @(Get-ChildItem $parentFolderName | 
     ? { $_.PSIsContainer -and $_.Name -ne "Data" } | 
     sort CreationTime -desc | 
     select -Skip $numberOfFoldersToKeep)

foreach ($objItem in $folders1) {
    Write-Host $webServerLocation\$objItem
    Remove-Item -Recurse -Force $parentFolderName\$objItem -WhatIf
}

This returns an array of length zero, so the body of the foreach statement is not executed.

As C.B. noted in the comments above, the problem is that if you pass a null collection into a foreach statement in PowerShell, the body of the foreach statement is executed once.

This was completely unintuitive to me, coming from a .NET background. Apparently, it's unintuitive to lots of other folks as well, since there's bug reports filed for this behavior on MSDN: https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=281908&SiteID=99

Apparently, this bug has been fixed in PowerShell V3.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top