SuperDOS
SuperDOS

Reputation: 331

powershell move/delete directories not containing certain folders

Let's say we have a folder with a number of sub folders, in each sub folder there is a different number of folders named after years start and end date. All folders contain a different set of "year folders".

for example:
C:\Test\A\20050101-20051231
C:\Test\A\20060101-20061231
C:\Test\A\20070101-20071231
C:\Test\B\20140101-20141231
C:\Test\B\20150101-20151231
C:\Test\B\20160101-20161231
C:\Test\C\20090101-20091231
C:\Test\C\20100101-20101231
C:\Test\C\20110101-20111231

I need help with creating a powershell script that searches through these folders and then move the root folder, in this example "C:\A", that doesn't have any year folder from 2009 to 2016. Unfortunately I can't use time stamps.

Tried a start with this but it will just exclude the subfolders from the result.

Get-ChildItem -Depth 1 | ?{ $_.PSIsContainer } | where {$_.name -notlike "2013"}|  Select-Object FullName

Thanks

Upvotes: 0

Views: 545

Answers (4)

Patrick Meinecke
Patrick Meinecke

Reputation: 4173

This would work if the folder structure is always the same.

Get-ChildItem -Path C:\Test -Directory | Where-Object -FilterScript {
    -not (
        Get-ChildItem -Path $_.FullName -Directory | 
        Where-Object -Property Name -In -Value (2009..2016)
    )
}

Returns a file system object for each folder that doesn't have a year between 2009 and 2016, add | Remove-Item -Recurse next to the last } to remove the folders.

Edit:

thanks! just noticed the folders are in this format, 20090101-20091231, 20100101-20101231. how do I go about it then?

Changed it up a little. Using the Name parameter for Get-ChildItem and switching the sides of the inner where statement so we can use the like operator with a wild card appended to the name. Nevermind that was all sorts of wrong. Just switch to FilterScript to use the SubString() method.

Get-ChildItem -Path C:\Test -Directory | Where-Object -FilterScript {
    -not (
        Get-ChildItem -Path $_.FullName -Directory -Name | 
        Where-Object -FilterScript { $_.SubString(0,4) -in (2009..2016) }
    )
}

Upvotes: 1

Esperento57
Esperento57

Reputation: 17462

Get-ChildItem "c:\test\*\*"  | 
select  @{N="YearDir";E={[int]$_.Name.substring(0, 4)}} , @{N="ParentDir";E={$_.Parent.fullname}} | 
group ParentDir |
%{ $year=$_.Group.YearDir; $dir=$_.Name; 2009..2016 | % { if ($_ -notin $year) {[pscustomobject]@{Dir=$dir;Year=$_}}} }

#explication:

#list dir with date
Get-ChildItem "c:\test\*\*"  | 

#build lisrt with extract year and parent dir
select  @{N="YearDir";E={[int]$_.Name.substring(0, 4)}} , @{N="ParentDir";E={$_.Parent.fullname}} | 

#group by parent dir
group ParentDir |

#filter between 2009 and 2016
%{ $year=$_.Group.YearDir; $dir=$_.Name; 2009..2016 | % { if ($_ -notin $year) {[pscustomobject]@{Dir=$dir;Year=$_}}} }

Upvotes: 0

Esperento57
Esperento57

Reputation: 17462

other solution (PowerShell V5)

Get-ChildItem "c:\test\*" -directory | % {
$currentdir=$_.FullName
$listcurrentdir=gci $currentdir -Directory | % {$_.name.Substring(0, 4)}
2009..2016 | % { if ($_ -notin $listcurrentdir) {[pscustomobject]@{Dir=$currentdir; Year=$_}} }
}

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174475

You'll need to loop through the years and compare them to the subfolder names.

You can do this in the Where-Object expression:

Get-ChildItem -Depth 1 -Directory |Where-Object {
    $Subfolders = Get-ChildItem $_.FullName |Select -Expand Name
    foreach($year in 2009..2016){
        if($Subfolders -contains $year){
            return $false
        }
    }
    return $true
}

Upvotes: 1

Related Questions