Powershell folder management problem

I am trying to solve a problem and I have a couple of different ways to address it that might work, but I'm not sure how to script either one.

The problem is that we have a folder structure where each client has a folder and there is a very specific folder tree (with one variation) that each folder should contain.... and ONLY those folders.  For example, a client folder should contain only folders A, B, C and D, but sometimes folder A is allowed to contain a folder named "Backup".  Also, only the folders A, B, C and D should contain files... not the parent client folder.

So, what I'd like to do is generate a report that lists all client folders that deviate from the norm.  I'm envisioning a foreach loop and comparing to a list, but adding another subfolder layer is making things a bit complicated for my PowerShell newbie skills.

Alternatively, if I could just get a report that tells me with client folders have folders hierarchies that are more than 2 levels deep, that would be an immense help, but I can't seem to find any PowerShell commandlet that allows me to measure how deep a folder structure is.  Perhaps I need to parse the output of something and delimit based upon backslash characters?  That seems very un-PowerShell, though.  

If anyone can point me in the right direction or another alternative for these issues, that would be fantastic.  Ideally the application that's supposed to manage these folders would set permissions properly to prevent these issues.  
Who is Participating?
LearnctxConnect With a Mentor EngineerCommented:
To check if a file type is a directory or a file you can query a few properties (or check that all 3 are met).

PSIsContainer (returns either true or false)
Mode (look for "d")
Attributes (look for "directory")

Examples below (each of these will return the same number of directories).

If you want post up what you're using that is returning false positives.

(Get-ChildItem -r | ? {$_.mode -match "d" -and $_.attributes -match "directory" -and $_.psiscontainer -eq $true}).Count
(Get-ChildItem -r | ? {$_.mode -match "d"}).count
(Get-ChildItem -r | ? {$_.attributes -match "directory"}).count
(Get-ChildItem -r | ? {$_.psiscontainer -eq $true}).count

Open in new window

You'll probably want to write something a whole lot cleaner than this. Just thrown it together. Hopefully it gives you some ideas.
# Array of valid subdirectory names
$arrValidDir = New-Object system.collections.arraylist
# Root directory
$directory = "C:\temp\ClientFolders"
# Gather client directories
$clientfolders = gci $directory
# Iterate through the client directories matching your criteria
$clientfolders | % {
	$problem = $false
	Write-Host "Searching $_"
	Write-Host "--------------------------"
	# Find if there are any files in parent directory
	if (gci $_.FullName | ? {$_.PSIsContainer -eq $false}){Write-Host -foregroundcolor red `
	"> Parent directory contains files";$problem = $true}
	# Find invalid directories in parenty directory (not matching the list in the array)
	gci $_.FullName | ? {$_.PSIsContainer} | %{if (!($arrValidDir.Contains($_.Name))){ `
	Write-Host -foregroundcolor red "> Invalid directory found in parent directory: $_";$problem = $true}}
	# Find Backup directory indirectories other than A
	gci $_.FullName | ? {$_.PSIsContainer -eq $true -AND $_.Name -ne "A"} | % {if `
	($arrValidDir.Contains($_.Name)){if (gci $_.FullName){Write-Host -foregroundcolor red `
	"> Backup directory found under directory $_";$problem = $true}}}
	if (!($problem)){Write-Host -foregroundcolor green "No problems found.";Write-Host}

Open in new window

itbeanAuthor Commented:
Thank you!  That's very helpful and gets me well on my way to a solution.  

It appears the third test is returning false positives when one of the folders in the array contains files (of any type).  How best could that be tweaked just to test for folders with names other than "Backup", for example?

I really appreciate your help on this.  I think I should be able to turn this into a good cleanup tool thanks to the framework you have provided.  

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.