Public/Export-PSGraph.ps1
function Export-PSGraph { <# .Description Invokes the graphviz binaries to generate a graph. .Example Export-PSGraph -Source graph.dot -OutputFormat png .Example graph g { edge (3..6) edge (5..2) } | Export-PSGraph -Destination $env:temp\test.png .Notes The source can either be files or piped graph data. It checks the piped data for file paths. If it can't find a file, it assumes it is graph data. This may give unexpected errors when the file does not exist. #> [cmdletbinding()] param( # The GraphViz file to process or contents of the graph in Dot notation [Parameter( ValueFromPipeline = $true )] [Alias('InputObject','Graph','SourcePath')] [string[]] $Source, #The destination for the generated file. [Parameter( Position = 0 )] [string] $DestinationPath, # The file type used when generating an image [ValidateSet('jpg','png','gif','imap','cmapx','jp2','json','pdf','plain','dot')] [string] $OutputFormat = 'png', # The layout engine used to generate the image [ValidateSet( 'Hierarchical', 'SpringModelSmall' , 'SpringModelMedium', 'SpringModelLarge', 'Radial', 'Circular' )] [string] $LayoutEngine, # launches the graph when done [switch] $ShowGraph ) begin { $graphViz = Resolve-Path -path 'c:\program files*\GraphViz*\bin\dot.exe' if($graphViz -eq $null) { throw "Could not find GraphViz installed on this system. Please run 'Find-Package graphviz | Install-Package -ForceBootstrap' or 'Install-GraphViz' to install the needed binaries and libraries. This module just a wrapper around GraphViz and is looking for it in your program files folder." } $useStandardInput = $false $standardInput = New-Object System.Text.StringBuilder $paramLookup = @{ # OutputFormat Version = 'V' Debug = 'v' GraphName = 'Gname={0}' NodeName = 'Nname={0}' EdgeName = 'Ename={0}' OutputFormat = 'T{0}' LayoutEngine = 'K{0}' ExternalLibrary = 'l{0}' DestinationPath = 'o{0}' AutoName = 'O' #LayoutEngine Hierarchical = 'dot' SpringModelSmall = 'neato' SpringModelMedium = 'fdp' SpringModelLarge = 'sfdp' Radial = 'twopi' Circular = 'circo' } Write-Verbose "Checking lookup table for options" $arguments = @() if($PSBoundParameters.ContainsKey('LayoutEngine')) { Write-Verbose 'Looking up and replacing rendering engine string' $PSBoundParameters['LayoutEngine'] = $paramLookup[$PSBoundParameters['LayoutEngine']] } if( -Not $PSBoundParameters.ContainsKey('DestinationPath')) { $PSBoundParameters["AutoName"] = $true; } if( -Not $PSBoundParameters.ContainsKey('OutputFormat')) { Write-Verbose "Tryig to set OutputFormat to match file extension" $PSBoundParameters["OutputFormat"] = $OutputFormat; $formats = @('jpg','png','gif','imap','cmapx','jp2','json','pdf','plain','dot') foreach($ext in $formats) { if($DestinationPath -like "*.$ext") { $PSBoundParameters["OutputFormat"] = $ext } } } Write-Verbose 'Walking parameter mapping' foreach($key in $PSBoundParameters.keys) { Write-Debug $key if($key -ne $null -and $paramLookup.ContainsKey($key)) { $newArgument = $paramLookup[$key] if($newArgument -like '*{0}*') { $newArgument = $newArgument -f $PSBoundParameters[$key] } Write-Debug $newArgument $arguments += "-$newArgument" } } } process { if($Source -ne $null) { # if $Source is a list of files, process each one $fileList = Resolve-Path -Path $Source -ea 0 if($fileList -ne $null) { foreach($file in $fileList ) { Write-Verbose "Generating graph from '$($file.path)'" & $graphViz @($arguments + $file.path) } } else { Write-Debug 'Using standard input to process graph' $useStandardInput = $true [void]$standardInput.AppendLine($Source) } } } end { if($useStandardInput) { Write-Verbose 'Processing standard input' if($DestinationPath -eq $null -or -Not(Test-path $DestinationPath)) { $DestinationPath = [System.IO.Path]::GetRandomFileName() Write-Verbose "Dest: $DestinationPath" $arguments = @($arguments) + @("-o$DestinationPath") } Write-Verbose " Arguments: $($arguments -join ' ')" $standardInput.ToString() | & $graphViz @($arguments) if($ShowGraph) { # Launches image with default viewer as decided by explorer Write-Verbose "Launching $(Resolve-Path $DestinationPath)" Invoke-Expression (Resolve-Path $DestinationPath) } Write-Output (Get-ChildItem $DestinationPath) } } } |