Powershell folder management problem

Posted on 2009-02-20
Last Modified: 2012-05-06
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.  
Question by:itbean
    LVL 16

    Expert Comment

    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

    LVL 1

    Author Comment

    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.  

    LVL 16

    Accepted Solution

    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


    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Join & Write a Comment

    How to sign a powershell script so you can prevent tampering, and only allow users to run authorised Powershell scripts
    Create and license users in Office 365 in bulk based on a CSV file. A step-by-step guide with PowerShell script examples.
    Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
    The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

    729 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now