Graphing with Glee

Doug Finke has a blog HERE which shows you how to use PowerShell to program GLEE – Graph Layout Execution Engine.  GLEE is a .NET tool for graph layout and viewing developed by Lev Nachmanson of Microsoft Research.  You can read more about GLEE HERE.


I got pretty excited about this and grabbed Doug’s example and hacked up a few functions to explore the GLEE a little bit more.  I’m happy with the direction these are going because it is much more PowerShell like in that it operates against sets of objects and utilizes metaprogramming which allows you to do a ton of work with a tiny amount of specification.  For instance, I defined an OBJECT Map which says how to graph objects based upon what type of object you have.  I also wrote a Set-GleeNodeAttribute which takes a graph and then a SCRIPTBLOCK where clause to select which nodes work against and then what attribute to apply.  It would have been better if it took a hash table of values so I could change the font, the fontsize, the fillcolor, etc all with one pass.  Here is an example of coloring all the nodes that have handles -ge 800 to RED.



Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red)


If you follow the GLEE link, you’ll see that it is a very rich surface.  My examples do not do it justice.  The first example shows a set of processes which map to their modules which map to their Products.  The second example shows a Dependency graph for a set of SERVICES.


image


image


function New-GleeViewer
{
    Param(
    [Drawing.Size]$size = $(New-Object Drawing.Size @(600,600))
    )
    [void] [Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
    [void] [Reflection.Assembly]::LoadFrom(“C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.GraphViewerGDI.dll”)
    [void] [Reflection.Assembly]::LoadFrom(“C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.Drawing.dll”)
    [void] [Reflection.Assembly]::LoadFrom(“C:\Program Files\Microsoft Research\GLEE\samples\WindowsApplication\WindowsApplication\bin\Debug\Microsoft.GLEE.dll”)


    $form = New-Object Windows.Forms.Form
    $form.Size = $size


    $viewer = New-Object Microsoft.Glee.GraphViewerGdi.GViewer
    $viewer.Dock = “Fill”
    $form.Controls.Add($viewer)
    $form.Add_Shown( { $form.Activate() } )
    return $form
}


function New-GleeGraph()
{
    $g = New-Object Microsoft.Glee.Drawing.Graph(“graph”);
    return $g
}


function Show-GleeGraph
{
    param(
    [Windows.Forms.Form]$viewer,
    [Microsoft.Glee.Drawing.Graph]$Graph
    )
    $viewer.Controls[0].Graph = $graph
    $result = $viewer.ShowDialog()
    $viewer.Controls[0].Graph = $null
}


function Graph-Object
{
    param(
        [Microsoft.Glee.Drawing.Graph]$graph,
        $inputObject,
        [HashTable]$objectMap
    )
    foreach ($o in @($inputObject))
    {  
        $oMap = $ObjectMap.$($o.PsTypenames[0])
        if ($oMap)
        {
            $node = $graph.AddNode($o.$($oMap.Label_Property))
            $node.UserData = $o
            foreach ($property in  @($o.$($oMap.Follow_Property)) |WHERE {$_})
            {  
                $pMap = $ObjectMap.$($property.PsTypeNames[0])
                if ($pmap)
                {
                    [void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.$($pMap.Label_Property))
                    if ($pMap.Follow_Property)
                    {
                        Graph-Object -graph $graph -inputObject $Property -ObjectMap $ObjectMap
                    }
                }else
                {
                    [Void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.ToString())
                }
            }
        }
    }
}

function Set-GleeNodeAttribute
{
    param(
    [Microsoft.Glee.Drawing.Graph]$Graph,
    [ScriptBlock]$Where,
    $Property,
    $Value
    )
    foreach ($node in ($graph.NodeMap.Keys | %{$graph.NodeMap.$_}))
    {
     if ($Node.UserData |where $where)
        {   $Node.Attr.$Property = $Value
        }
    }
}

###################################################
# now Let’s ahve some fun!
##################################################
$ObjectMap = @{
    “System.ServiceProcess.ServiceController” = @{
        Follow_Property = “ServicesDependedOn”
        Follow_Label = “DependsUpon”
        Label_Property = “Name”
        }
     “System.Diagnostics.Process” = @{
        Follow_Property = “MainModule”
        Follow_Label = “Module”
        Label_Property = “ProcessName”
     }
     “System.Diagnostics.ProcessModule” = @{
        Follow_Property = “FileVersionInfo”
        Follow_Label = “Product”
        Label_Property = “ModuleName”
     }
     “System.Diagnostics.FileVersionInfo” = @{
        Label_Property = “ProductName”
     }
     “System.DateTime” = @{
        Label_Property = “Day”
     }
}

$viewer = New-GleeViewer

$g1 = New-GleeGraph
Graph-Object -Graph $g1 -InputObject (gsv net*p*) -ObjectMap $ObjectMap
$g2 = New-GleeGraph
Graph-Object -Graph $g2 -InputObject (gps *power*,*ss) -ObjectMap $ObjectMap


Show-GleeGraph $viewer $g1
Show-GleeGraph $viewer $g2
# NOW Let’s color some of the elements
Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red)
Show-GleeGraph $viewer $g2


Cheers!


Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

show-ServiceDependencies.ps1