PowerShell: Populating TreeView with Directory Hierarchy

powershell

So I'm attempting to write a PowerShell script with a GUI input; idea being that the end users see a nested TreeView of the file system. They tick a some folders, hit a button, …magic happens.

I have the mount points (Not sure what's happening with C yet), problem is i can't seem to figure out / find how to enumerate through and add as nested nodes.

My search results all seems to point me to C#, C++, etc examples; not the helpful.

Ideas?


This is what i got

What i got

This is what i want (but keeps going deeper)

What i want

So this is my code so far

$objDriveLetters = GET-WMIOBJECT –query "SELECT * from win32_logicaldisk"
$form = New-Object System.Windows.Forms.Form
$treeView = New-Object System.Windows.Forms.TreeView
$treeView.Dock = 'Fill'
$treeView.CheckBoxes = $true

foreach ($iDrive in $objDriveLetters)
    {
        $DriveRoot = Get-Item $iDrive.DeviceID
        #$FolderRoot = Get-ChildItem -Path $iDrive.DeviceID
        $FolderRoot = Get-Item -Path $iDrive.DeviceID
        $treeView.Nodes.Add($FolderRoot.FullName, $FolderRoot.FullName)
    }

$form.Controls.Add($treeView)
$form.ShowDialog()

Best Answer

It's simple as treeView.Nodes.Add method returns the TreeNode that was added to the collection i.e. an object of [System.Windows.Forms.TreeNode] type. Therefore, you can apply Add method on it to create new tree nodes corresponding to filesystem nested items as follows:

Set-StrictMode -Version latest
Function AddNodes ( $Node, $FSObject ) {
    $NodeSub = $Node.Nodes.Add($FSObject.FullName, $FSObject.Name)
    if ( $FSObject -is [System.IO.DirectoryInfo] ) {
        $FSObjSub = $FSObject | 
                Get-ChildItem <#-Directory<##> -ErrorAction SilentlyContinue
        foreach ( $FSObj in $FSObjSub ) {
            AddNodes $NodeSub $FSObj
        }
    }
}

$objDriveLetters = GET-WMIOBJECT –query "SELECT * from win32_logicaldisk where Drivetype=4"
$form = New-Object System.Windows.Forms.Form
$treeView = New-Object System.Windows.Forms.TreeView
$treeView.Dock = 'Fill'
$treeView.CheckBoxes = $true

foreach ($iDrive in $objDriveLetters)
{
    # ensure that a drive is accessible (e.g. a medium is inserted into DVD drive)
    if ( Test-Path $iDrive.DeviceID ) {
        # get a drive root e.g. C:\ as C: refers to current directory
        $DriveRootPath = Join-Path -ChildPath \ -Path $iDrive.DeviceID
        $DriveRoot = Get-Item -Path $DriveRootPath
        AddNodes $treeView $DriveRoot
    }
}

[void]$form.Controls.Add($treeView)
[void]$form.ShowDialog()

Result:

File System Tree View

Explanation (note comment lines inside code as well): chiefly notice that:

  • above example is limited to network drives using where Drivetype=4 clause merely for my debugging purposes, and
  • AddNodes subroutine calls itself recursively for subfolders if any.