{"id":6951,"date":"2007-11-27T02:31:00","date_gmt":"2007-11-27T02:31:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2007\/11\/27\/graphing-with-glee\/"},"modified":"2019-02-18T13:16:22","modified_gmt":"2019-02-18T20:16:22","slug":"graphing-with-glee","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/graphing-with-glee\/","title":{"rendered":"Graphing with Glee"},"content":{"rendered":"<p>Doug Finke has a blog <a href=\"http:\/\/dougfinke.com\/blog\/?p=291\">HERE<\/a> which shows you how to use PowerShell to program GLEE &#8211; Graph Layout Execution Engine.&nbsp; GLEE is a .NET tool for graph layout and viewing developed by <a href=\"http:\/\/research.microsoft.com\/~levnach\">Lev Nachmanson<\/a> of Microsoft Research.&nbsp; You can read more about GLEE <a href=\"http:\/\/research.microsoft.com\/~levnach\/GLEEWebPage.htm\">HERE<\/a>. <\/p>\n<p>I got pretty excited about this and grabbed Doug&#8217;s example and hacked up a few functions to explore the GLEE a little bit more.&nbsp; I&#8217;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.&nbsp; For instance, I defined an OBJECT Map which says how to graph objects based upon what type of object you have.&nbsp; 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.&nbsp; 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.&nbsp; Here is an example of coloring all the nodes that have handles -ge 800 to RED.<\/p>\n<blockquote>\n<p>Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red) <\/p>\n<\/blockquote>\n<p>If you follow the GLEE link, you&#8217;ll see that it is a very rich surface.&nbsp; My examples do not do it justice.&nbsp; The first example shows a set of processes which map to their modules which map to their Products.&nbsp; The second example shows a Dependency graph for a set of SERVICES.<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/BlogFileStorage\/blogs_msdn\/powershell\/WindowsLiveWriter\/GraphingwithGlee_14AC3\/image_2.png\"><img decoding=\"async\" height=\"221\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/BlogFileStorage\/blogs_msdn\/powershell\/WindowsLiveWriter\/GraphingwithGlee_14AC3\/image_thumb.png\" width=\"684\" border=\"0\"><\/a><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/BlogFileStorage\/blogs_msdn\/powershell\/WindowsLiveWriter\/GraphingwithGlee_14AC3\/image_4.png\"><img decoding=\"async\" height=\"290\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/BlogFileStorage\/blogs_msdn\/powershell\/WindowsLiveWriter\/GraphingwithGlee_14AC3\/image_thumb_1.png\" width=\"691\" border=\"0\"><\/a> <\/p>\n<p>function New-GleeViewer <br \/>{ <br \/>&nbsp;&nbsp;&nbsp; Param( <br \/>&nbsp;&nbsp;&nbsp; [Drawing.Size]$size = $(New-Object Drawing.Size @(600,600)) <br \/>&nbsp;&nbsp;&nbsp; ) <br \/>&nbsp;&nbsp;&nbsp; [void] [Reflection.Assembly]::LoadWithPartialName(&#8220;System.Windows.Forms&#8221;) <br \/>&nbsp;&nbsp;&nbsp; [void] [Reflection.Assembly]::LoadFrom(&#8220;C:\\Program Files\\Microsoft Research\\GLEE\\samples\\WindowsApplication\\WindowsApplication\\bin\\Debug\\Microsoft.GLEE.GraphViewerGDI.dll&#8221;) <br \/>&nbsp;&nbsp;&nbsp; [void] [Reflection.Assembly]::LoadFrom(&#8220;C:\\Program Files\\Microsoft Research\\GLEE\\samples\\WindowsApplication\\WindowsApplication\\bin\\Debug\\Microsoft.GLEE.Drawing.dll&#8221;) <br \/>&nbsp;&nbsp;&nbsp; [void] [Reflection.Assembly]::LoadFrom(&#8220;C:\\Program Files\\Microsoft Research\\GLEE\\samples\\WindowsApplication\\WindowsApplication\\bin\\Debug\\Microsoft.GLEE.dll&#8221;) <\/p>\n<p>&nbsp;&nbsp;&nbsp; $form = New-Object Windows.Forms.Form <br \/>&nbsp;&nbsp;&nbsp; $form.Size = $size <\/p>\n<p>&nbsp;&nbsp;&nbsp; $viewer = New-Object Microsoft.Glee.GraphViewerGdi.GViewer <br \/>&nbsp;&nbsp;&nbsp; $viewer.Dock = &#8220;Fill&#8221; <br \/>&nbsp;&nbsp;&nbsp; $form.Controls.Add($viewer) <br \/>&nbsp;&nbsp;&nbsp; $form.Add_Shown( { $form.Activate() } ) <br \/>&nbsp;&nbsp;&nbsp; return $form <br \/>} <\/p>\n<p>function New-GleeGraph() <br \/>{ <br \/>&nbsp;&nbsp;&nbsp; $g = New-Object Microsoft.Glee.Drawing.Graph(&#8220;graph&#8221;); <br \/>&nbsp;&nbsp;&nbsp; return $g <br \/>} <\/p>\n<p>function Show-GleeGraph <br \/>{ <br \/>&nbsp;&nbsp;&nbsp; param( <br \/>&nbsp;&nbsp;&nbsp; [Windows.Forms.Form]$viewer, <br \/>&nbsp;&nbsp;&nbsp; [Microsoft.Glee.Drawing.Graph]$Graph <br \/>&nbsp;&nbsp;&nbsp; ) <br \/>&nbsp;&nbsp;&nbsp; $viewer.Controls[0].Graph = $graph <br \/>&nbsp;&nbsp;&nbsp; $result = $viewer.ShowDialog() <br \/>&nbsp;&nbsp;&nbsp; $viewer.Controls[0].Graph = $null <br \/>} <\/p>\n<p>function Graph-Object <br \/>{ <br \/>&nbsp;&nbsp;&nbsp; param( <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Microsoft.Glee.Drawing.Graph]$graph, <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $inputObject, <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [HashTable]$objectMap <br \/>&nbsp;&nbsp;&nbsp; ) <br \/>&nbsp;&nbsp;&nbsp; foreach ($o in @($inputObject)) <br \/>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $oMap = $ObjectMap.$($o.PsTypenames[0]) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($oMap) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $node = $graph.AddNode($o.$($oMap.Label_Property)) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $node.UserData = $o <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach ($property in&nbsp; @($o.$($oMap.Follow_Property)) |WHERE {$_}) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $pMap = $ObjectMap.$($property.PsTypeNames[0]) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($pmap) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.$($pMap.Label_Property)) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($pMap.Follow_Property) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Graph-Object -graph $graph -inputObject $Property -ObjectMap $ObjectMap <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Void]$graph.AddEdge($o.$($oMap.Label_Property), $oMap.Follow_Label, $Property.ToString()) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp; } <br \/>}<\/p>\n<p>function Set-GleeNodeAttribute <br \/>{ <br \/>&nbsp;&nbsp;&nbsp; param( <br \/>&nbsp;&nbsp;&nbsp; [Microsoft.Glee.Drawing.Graph]$Graph, <br \/>&nbsp;&nbsp;&nbsp; [ScriptBlock]$Where, <br \/>&nbsp;&nbsp;&nbsp; $Property, <br \/>&nbsp;&nbsp;&nbsp; $Value <br \/>&nbsp;&nbsp;&nbsp; ) <br \/>&nbsp;&nbsp;&nbsp; foreach ($node in ($graph.NodeMap.Keys | %{$graph.NodeMap.$_})) <br \/>&nbsp;&nbsp;&nbsp; { <br \/>&nbsp;&nbsp;&nbsp;&nbsp; if ($Node.UserData |where $where) <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; $Node.Attr.$Property = $Value <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp; } <br \/>}<\/p>\n<p>################################################### <br \/># now Let&#8217;s ahve some fun! <br \/>################################################## <br \/>$ObjectMap = @{ <br \/>&nbsp;&nbsp;&nbsp; &#8220;System.ServiceProcess.ServiceController&#8221; = @{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Property = &#8220;ServicesDependedOn&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Label = &#8220;DependsUpon&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label_Property = &#8220;Name&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8220;System.Diagnostics.Process&#8221; = @{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Property = &#8220;MainModule&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Label = &#8220;Module&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label_Property = &#8220;ProcessName&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8220;System.Diagnostics.ProcessModule&#8221; = @{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Property = &#8220;FileVersionInfo&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow_Label = &#8220;Product&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label_Property = &#8220;ModuleName&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8220;System.Diagnostics.FileVersionInfo&#8221; = @{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label_Property = &#8220;ProductName&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8220;System.DateTime&#8221; = @{ <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Label_Property = &#8220;Day&#8221; <br \/>&nbsp;&nbsp;&nbsp;&nbsp; } <br \/>} <\/p>\n<p>$viewer = New-GleeViewer <\/p>\n<p>$g1 = New-GleeGraph <br \/>Graph-Object -Graph $g1 -InputObject (gsv net*p*) -ObjectMap $ObjectMap <br \/>$g2 = New-GleeGraph <br \/>Graph-Object -Graph $g2 -InputObject (gps *power*,*ss) -ObjectMap $ObjectMap <\/p>\n<p>Show-GleeGraph $viewer $g1 <br \/>Show-GleeGraph $viewer $g2 <br \/># NOW Let&#8217;s color some of the elements <br \/>Set-GleeNodeAttribute -Graph $g2 -where {$_.handles -ge 800} -Property FillColor -Value ([Microsoft.Glee.Drawing.Color]::Red) <br \/>Show-GleeGraph $viewer $g2<\/p>\n<p>Cheers!<\/p>\n<p>Jeffrey Snover [MSFT] <br \/>Windows Management Partner Architect <br \/>Visit the Windows PowerShell Team blog at:&nbsp;&nbsp;&nbsp; <a href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/a> <br \/>Visit the Windows PowerShell ScriptCenter at:&nbsp; <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/a><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/06\/54\/51\/02\/show-ServiceDependencies.ps1\">show-ServiceDependencies.ps1<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Doug Finke has a blog HERE which shows you how to use PowerShell to program GLEE &#8211; Graph Layout Execution Engine.&nbsp; GLEE is a .NET tool for graph layout and viewing developed by Lev Nachmanson of Microsoft Research.&nbsp; You can read more about GLEE HERE. I got pretty excited about this and grabbed Doug&#8217;s example [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-6951","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>Doug Finke has a blog HERE which shows you how to use PowerShell to program GLEE &#8211; Graph Layout Execution Engine.&nbsp; GLEE is a .NET tool for graph layout and viewing developed by Lev Nachmanson of Microsoft Research.&nbsp; You can read more about GLEE HERE. I got pretty excited about this and grabbed Doug&#8217;s example [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6951","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=6951"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6951\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=6951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=6951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=6951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}