PowerShell

Easy way to create diagrams using PowerShell and PSWriteHTML

A few months ago, when I was working on PSWriteWord and PSWriteHTML, I thought to myself that in 2020 if I'll get time, I'll try to create PSWriteVisio. While I wasn't sure I would be able to make it past some concept, it was in my plans for 2020. It's still 2019 though, and while working on Testimo for Active Directory Healthchecks, I thought it would be nice to have a visual representation of network, forest schema or replication. I couldn't get this idea out of my head. I thought on using PSGraph from Kevin Marquette to generate image and import that to PSWriteHTML but it was a bit tricky and PSGraph requires external software to work – and has some additional steps for Windows, Mac or Linux.

Simple Diagram Example

Me being me, as I couldn't let it go… Let me introduce you to my implementation of Diagraming done in PowerShell (internally using open-source library Vis.js). I've tried to do it as easy and as simple as possible and at the same time visually attractive.

New-HTML -TitleText 'My diagram' -UseCssLinks -UseJavaScriptLinks -FilePath $PSScriptRoot\Example-Easy.html {
    New-HTMLPanel {
        New-HTMLDiagram {
            New-DiagramNode -Label 'One node' -To 'Second node','Third node' -ColorBackground Bisque
            New-DiagramNode -Label 'Second node'
            New-DiagramNode -Label 'Third node'
        }
    }

} -ShowHTML

So what happens above? As always with PSWriteHTML you have to use New-HTML to create HTML object. Within that object, I've decided that I will have my diagram on a Panel. Finally, the Diagram part is just four lines of code.

New-HTMLDiagram {
    New-DiagramNode -Label 'One node' -To 'Second node','Third node' -ColorBackground Bisque
    New-DiagramNode -Label 'Second node'
    New-DiagramNode -Label 'Third node'
}

The way it works is that you open up new diagram and within that diagram I've defined three nodes. I've also defined color for one of the  nodes and have told it to connect to two remaining nodes. Easy? Hope so. New-DiagramNode has multiple options available to work with.

Diagram - Icons and Images

I've decided to expand my diagram a bit and add some colors. As you can notice below, I've added to the third node IconBrands parameter along with IconColor. I've also added 4th node called Bart Simson and decided to use an internet image for it via a link. Finally, I've expanded Diagram height to 1000px because it was just too small on defaults.

New-HTML -TitleText 'My diagram' -UseCssLinks -UseJavaScriptLinks -FilePath $PSScriptRoot\Example-Easy2.html {
    New-HTMLDiagram -Height '1000px' {
        New-DiagramNode -Label 'One node' -To 'Second node', 'Third node' -ColorBackground Bisque
        New-DiagramNode -Label 'Second node'
        New-DiagramNode -Label 'Third node' -IconBrands amazon -IconColor Brown
        New-DiagramNode -Label 'Bart Simson' -Image 'https://cdn.imgbin.com/5/2/1/imgbin-bart-simpson-homer-simpson-supreme-drawing-bart-simpson-bard-simpsons-jAfrtPtYNPTK5rQrcKULn5XBn.jpg' -To 'Second node'
    }
} -ShowHTML

Looks cool? Hope so. There are two things to know here though. Currently, there are three Icon types. IconBrands, IconSolid, and IconRegular. Just like in tabs and other places. You can set an IconColor to it, so it's easy to let's say make your server RED if it has a problem or GREEN if it doesn't. There's a KNOWN ISSUE with that. Icons have problem loading as Icons and often don't load at all. This will be fixed in an external library that PSWriteHTML is using for diagram building. There's already fix provided, just not published. Expect it to show up soon enough! To understand what I'm talking about, let's see the next example.

New-HTML -TitleText 'My diagram' -UseCssLinks -UseJavaScriptLinks -FilePath $PSScriptRoot\Example-Easy3.html {
    New-HTMLDiagram -Height '1000px' {
        New-DiagramNode -Label 'One node' -To 'Second node', 'Third node' -ColorBackground Bisque
        New-DiagramNode -Label 'Second node'
        New-DiagramNode -Label 'Third node' -IconBrands amazon -IconColor Brown
        New-DiagramNode -Label 'Fourth node' -IconRegular building -IconColor Brown
        New-DiagramNode -Label 'Fifth node' -IconSolid align-left -IconColor Brown
        New-DiagramNode -Label 'Bart Simson' -Image 'https://cdn.imgbin.com/5/2/1/imgbin-bart-simpson-homer-simpson-supreme-drawing-bart-simpson-bard-simpsons-jAfrtPtYNPTK5rQrcKULn5XBn.jpg' -To 'Second node'
    }
} -ShowHTML

See, the icons didn't load correctly. If you click on it, resize (yes – diagrams do resize so you can Zoom in/zoom out) the icons may show up correctly. Till the external library publishes a fix I've developed a workaround. The workaround uses icons as images. You do that by adding IconAsImage switch to the node. It takes an Icon and uses it's external Image URL instead. The caveat for that is that there's no ability for colors.

New-HTML -TitleText 'My diagram' -UseCssLinks -UseJavaScriptLinks -FilePath $PSScriptRoot\Example-Easy3.html {
    New-HTMLDiagram -Height '1000px' {
        New-DiagramNode -Label 'One node' -To 'Second node', 'Third node' -ColorBackground Bisque
        New-DiagramNode -Label 'Second node'
        New-DiagramNode -Label 'Third node' -IconBrands amazon -IconColor Brown -IconAsImage
        New-DiagramNode -Label 'Fourth node' -IconRegular building -IconColor Brown -IconAsImage
        New-DiagramNode -Label 'Fifth node' -IconSolid align-left -IconColor Brown -IconAsImage
        New-DiagramNode -Label 'Bart Simson' -Image 'https://cdn.imgbin.com/5/2/1/imgbin-bart-simpson-homer-simpson-supreme-drawing-bart-simpson-bard-simpsons-jAfrtPtYNPTK5rQrcKULn5XBn.jpg' -To 'Second node'
    }
} -ShowHTML

Keep in mind this is a temporary workaround that I expect to be fixed within a short time frame. While speaking of images, it's a very cool feature because you can use any image you want. You can also connect it with all current PSWriteHTML features (charts, tables, code blocks, and other stuff that is already there and working).

Import-Module .\PSWriteHTML.psd1 -Force

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-Unifi.html {
    New-HTMLSection -HeaderText 'Diagram - My Network' -CanCollapse {
        New-HTMLPanel {
            New-HTMLDiagram {
                New-DiagramOptionsInteraction -Hover $true
                #New-DiagramOptionsManipulation
                New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch' -ImageType circularImage -Image 'https://cdn.imgbin.com/11/23/12/imgbin-ubiquiti-unifi-usg-ubiquiti-networks-router-ubiquiti-unifi-security-gateway-usg-pro-4-network-switch-wan-network-diagram-e1TN4dWJfRB7QnQNiZTDn1aLN.jpg'
                New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/17/21/14/imgbin-network-switch-power-over-ethernet-gigabit-ethernet-ubiquiti-unifi-switch-ubiquiti-networks-mimosa-network-uQpudFJ4K1UnMMZgzBsniKzyC.jpg'
                New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/4/14/3/imgbin-ubiquiti-networks-unifi-ap-ac-lr-wireless-access-points-ubiquiti-unifi-uap-ac-lr-ieee-802-11ac-ac-21pZgwQAbDF4bvA48D5cQgH5h.jpg'
                New-DiagramNode -Label 'EvoMac' -ImageType circularImage -Image 'https://cdn.imgbin.com/1/9/8/imgbin-macbook-ZAe8Jcn7qxxmEgMcSJcV9aWn6.jpg'
                New-DiagramNode -Label 'EvoWin' -To 'Exch1', 'Exch2', 'AD1', 'AD2', 'AD3', 'DC1', 'DC2' -Image 'https://cdn.imgbin.com/20/9/1/imgbin-hyper-v-virtual-security-switch-virtual-machine-network-switch-hypervisor-imran-cpLbwB53FHwHHeQ5h9g081hc4.jpg'
                New-DiagramNode -Label 'Exch1' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'Exch2' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'AD1' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD2' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD3' -ImageType circularImage -Image 'https://cdn.imgbin.com/6/11/3/imgbin-computer-icons-router-cisco-systems-computer-network-network-switch-network-S4pvESiV3pT4EzEjP4sZyc8Rf.jpg'
                New-DiagramNode -Label 'DC1' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
                New-DiagramNode -Label 'DC2' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
            } #-BundleImages
        }
        New-HTMLPanel {
            $DomainControllers = Get-WinADForestControllers
            New-HTMLTable -DataTable $DomainControllers
        }
    }
    # Below section isn't really nessecary. I've added it just to show CODE above on HTML page
    New-HTMLSection -HeaderText 'Code used to generate Diagram' {
        # Please notice I'm using it as PowerShell ScriptBlock which gives me formatting, but normally you would use it as a string for other types
        # PowerShell is smart so it will convert ScriptBlock to String so you can have proper code highligts
        New-HTMLCodeBlock -Style powershell -Highlight 2,5 -Title 'Diagram Example' -Theme enlighter {
            New-HTMLDiagram {
                New-DiagramOptionsInteraction -Hover $true
                #New-DiagramOptionsManipulation
                New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch' -ImageType circularImage -Image 'https://cdn.imgbin.com/11/23/12/imgbin-ubiquiti-unifi-usg-ubiquiti-networks-router-ubiquiti-unifi-security-gateway-usg-pro-4-network-switch-wan-network-diagram-e1TN4dWJfRB7QnQNiZTDn1aLN.jpg'
                New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/17/21/14/imgbin-network-switch-power-over-ethernet-gigabit-ethernet-ubiquiti-unifi-switch-ubiquiti-networks-mimosa-network-uQpudFJ4K1UnMMZgzBsniKzyC.jpg'
                New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/4/14/3/imgbin-ubiquiti-networks-unifi-ap-ac-lr-wireless-access-points-ubiquiti-unifi-uap-ac-lr-ieee-802-11ac-ac-21pZgwQAbDF4bvA48D5cQgH5h.jpg'
                New-DiagramNode -Label 'EvoMac' -ImageType circularImage -Image 'https://cdn.imgbin.com/1/9/8/imgbin-macbook-ZAe8Jcn7qxxmEgMcSJcV9aWn6.jpg'
                New-DiagramNode -Label 'EvoWin' -To 'Exch1', 'Exch2', 'AD1', 'AD2', 'AD3', 'DC1', 'DC2' -Image 'https://cdn.imgbin.com/20/9/1/imgbin-hyper-v-virtual-security-switch-virtual-machine-network-switch-hypervisor-imran-cpLbwB53FHwHHeQ5h9g081hc4.jpg'
                New-DiagramNode -Label 'Exch1' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'Exch2' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'AD1' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD2' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD3' -ImageType circularImage -Image 'https://cdn.imgbin.com/6/11/3/imgbin-computer-icons-router-cisco-systems-computer-network-network-switch-network-S4pvESiV3pT4EzEjP4sZyc8Rf.jpg'
                New-DiagramNode -Label 'DC1' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
                New-DiagramNode -Label 'DC2' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
            } #-BundleImages
        }
    }
} -ShowHTML

The code above may look scary, but it's just two times the same code. One time to create a diagram, the other one is to display the code on HTML so you can see the code used to generate a diagram next to your Diagram. The PowerShell code to create diagram within a section is much shorter and looks like below.

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-Unifi.html {
    New-HTMLSection -HeaderText 'Diagram - My Network' -CanCollapse {
        New-HTMLPanel {
            New-HTMLDiagram {
                New-DiagramOptionsInteraction -Hover $true
                New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch' -ImageType circularImage -Image 'https://cdn.imgbin.com/11/23/12/imgbin-ubiquiti-unifi-usg-ubiquiti-networks-router-ubiquiti-unifi-security-gateway-usg-pro-4-network-switch-wan-network-diagram-e1TN4dWJfRB7QnQNiZTDn1aLN.jpg'
                New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/17/21/14/imgbin-network-switch-power-over-ethernet-gigabit-ethernet-ubiquiti-unifi-switch-ubiquiti-networks-mimosa-network-uQpudFJ4K1UnMMZgzBsniKzyC.jpg'
                New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/4/14/3/imgbin-ubiquiti-networks-unifi-ap-ac-lr-wireless-access-points-ubiquiti-unifi-uap-ac-lr-ieee-802-11ac-ac-21pZgwQAbDF4bvA48D5cQgH5h.jpg'
                New-DiagramNode -Label 'EvoMac' -ImageType circularImage -Image 'https://cdn.imgbin.com/1/9/8/imgbin-macbook-ZAe8Jcn7qxxmEgMcSJcV9aWn6.jpg'
                New-DiagramNode -Label 'EvoWin' -To 'Exch1', 'Exch2', 'AD1', 'AD2', 'AD3', 'DC1', 'DC2' -Image 'https://cdn.imgbin.com/20/9/1/imgbin-hyper-v-virtual-security-switch-virtual-machine-network-switch-hypervisor-imran-cpLbwB53FHwHHeQ5h9g081hc4.jpg'
                New-DiagramNode -Label 'Exch1' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'Exch2' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'AD1' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD2' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD3' -ImageType circularImage -Image 'https://cdn.imgbin.com/6/11/3/imgbin-computer-icons-router-cisco-systems-computer-network-network-switch-network-S4pvESiV3pT4EzEjP4sZyc8Rf.jpg'
                New-DiagramNode -Label 'DC1' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
                New-DiagramNode -Label 'DC2' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
            } -BundleImages
        }
    }
} -ShowHTML

Did you notice BundleImage parameter for New-HTMLDiagram? While having lots of image links is great for many use case scenarios, there may be times when you don't want your diagrams to reach out to the internet for the picture to be loaded. BundleImage switch downloads those images, converts them to binary and inserts them into HTML. Please be careful as I don't know what will be the size of your Diagram when you do that on a large scale.

For comparison purposes, Diagram above without BundleImage switch is 20KB and with BundleImage 1MB. Up to you, really!

Diagram - Physics

By default, each diagram has Physics enabled. What that means the nodes try to position itself automatically, and you can try to change how it's placed and where. You can zoom in, zoom out, and even Save your diagram to disk as an image.

Cool right? Of course, you can disable that. There is command New-DiagramOpticsPhysics that has a couple of parameters currently, but if one wants this could be expanded with 20 or so options on how Physics works for Diagrams. I didn't want to spend too much time on it for now. As you can below, I've disabled physics.

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-Unifi2.html {
    New-HTMLSection -HeaderText 'Diagram - My Network' -CanCollapse {
        New-HTMLPanel {
            New-HTMLDiagram {
                New-DiagramOptionsPhysics -Enabled $false
                New-DiagramOptionsInteraction -Hover $true
                New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch' -ImageType circularImage -Image 'https://cdn.imgbin.com/11/23/12/imgbin-ubiquiti-unifi-usg-ubiquiti-networks-router-ubiquiti-unifi-security-gateway-usg-pro-4-network-switch-wan-network-diagram-e1TN4dWJfRB7QnQNiZTDn1aLN.jpg'
                New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/17/21/14/imgbin-network-switch-power-over-ethernet-gigabit-ethernet-ubiquiti-unifi-switch-ubiquiti-networks-mimosa-network-uQpudFJ4K1UnMMZgzBsniKzyC.jpg'
                New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', 'EvoWin' -ImageType circularImage -Image 'https://cdn.imgbin.com/4/14/3/imgbin-ubiquiti-networks-unifi-ap-ac-lr-wireless-access-points-ubiquiti-unifi-uap-ac-lr-ieee-802-11ac-ac-21pZgwQAbDF4bvA48D5cQgH5h.jpg'
                New-DiagramNode -Label 'EvoMac' -ImageType circularImage -Image 'https://cdn.imgbin.com/1/9/8/imgbin-macbook-ZAe8Jcn7qxxmEgMcSJcV9aWn6.jpg'
                New-DiagramNode -Label 'EvoWin' -To 'Exch1', 'Exch2', 'AD1', 'AD2', 'AD3', 'DC1', 'DC2' -Image 'https://cdn.imgbin.com/20/9/1/imgbin-hyper-v-virtual-security-switch-virtual-machine-network-switch-hypervisor-imran-cpLbwB53FHwHHeQ5h9g081hc4.jpg'
                New-DiagramNode -Label 'Exch1' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'Exch2' -Image 'https://cdn.imgbin.com/7/21/22/imgbin-microsoft-exchange-server-exchange-online-microsoft-outlook-office-365-email-email-1k5ceWxjFxVisLpLpxgJLF0Y0.jpg'
                New-DiagramNode -Label 'AD1' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD2' -Image 'https://cdn.imgbin.com/16/0/25/imgbin-active-directory-directory-service-computer-servers-windows-domain-computer-0MVUs58h9tPqF8nVb8RNxEi5w.jpg'
                New-DiagramNode -Label 'AD3' -ImageType circularImage -Image 'https://cdn.imgbin.com/6/11/3/imgbin-computer-icons-router-cisco-systems-computer-network-network-switch-network-S4pvESiV3pT4EzEjP4sZyc8Rf.jpg'
                New-DiagramNode -Label 'DC1' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
                New-DiagramNode -Label 'DC2' -Image 'https://cdn.imgbin.com/6/23/7/imgbin-computer-icons-electronics-active-directory-directory-service-others-A8ikiBt9nN77x6EbsXCWTc7M2.jpg'
            } #-BundleImages
        }
    }
} -ShowHTML

This could be useful if you want to position something on the screen before exporting to file quickly.

Diagram - Shapes and other options

One of the default options for New-DiagramNode is working with Shapes. By the default, the shape is an ellipse, but there are other types you can choose from. Shapes can have different colors for borders, highlighting, and hovering.

$ShapeTypes = @('circle', 'dot', 'diamond', 'ellipse', 'database', 'box', 'square', 'triangle', 'triangleDown', 'text', 'star', 'hexagon')

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-ShapesAndIcons.html {
    New-HTMLSection -HeaderText 'Diagram - My Network' -CanCollapse {
        New-HTMLPanel {
            New-HTMLDiagram -Height '1000px' {
                New-DiagramOptionsInteraction -Hover $true
                #New-DiagramOptionsManipulation
                New-DiagramOptionsPhysics
                New-DiagramOptionsLayout -RandomSeed 500
                New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch'
                New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', 'EvoWin'
                New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', 'EvoWin' -Shape hexagon
                New-DiagramNode -Label 'EvoMac' -Shape ellipse
                New-DiagramNode -Label 'EvoWin' -To 'Exch1','Exch2','AD1','AD2','AD3','DC1','DC2' -Shape database
                New-DiagramNode -Label 'Exch1' -Shape diamond
                New-DiagramNode -Label 'Exch2' -Shape box
                New-DiagramNode -Label 'AD1'
                New-DiagramNode -Label 'AD2' -IconBrands apple -IconColor Bisque
                New-DiagramNode -Label 'AD3' -IconRegular address-card
                New-DiagramNode -Label 'DC1' -IconSolid address-book
                New-DiagramNode -Label 'DC2' -IconSolid address-card -IconColor Green
                foreach ($_ in $ShapeTypes) {
                    New-DiagramNode -Label $_ -Shape $_ -To 'Unifi Switch'
                }
            }
        }
        New-HTMLPanel {
            New-HTMLTable -DataTable (Get-Process | Select-Object -First 5)
        }
    }
} -ShowHTML

Each diagram function provided offers multiple parameters that help you style, position node as you want. You can change fonts, styles, and do other things. Feel free to experiment, and see what's there in the shop.

By now, you probably noticed that I'm using Label and To parameters to define connections/links between nodes. What is essential to know that while I'm using Label to identify node, it's not always going to be this way. For example, if two nodes would have the same Label, they would overwrite each other (and that's how I've designed it). To be truly sure you want to have unique objects, there's an ID parameter. Below image shows three nodes that have the same Label, but thanks to using ID, there's no conflict between three nodes. Keep this mind when designing your diagrams.

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-ID.html {
    New-HTMLSection -HeaderText 'Diagram - My Network' -CanCollapse {
        New-HTMLDiagram -Height '1000px' {
            New-DiagramOptionsInteraction -Hover $true
            #New-DiagramOptionsManipulation
            New-DiagramOptionsPhysics
            New-DiagramOptionsLayout -RandomSeed 500
            New-DiagramNode -Label 'DC2' -IconSolid address-card -IconColor Green -To '17000', '17001'
            New-DiagramNode -ID '17000' -Label 'DC2'
            New-DiagramNode -ID '17001' -Label 'DC2'
        }
    }
} -ShowHTML
Diagram - Nodes and links

In all examples above, I've used one function New-DiagramNode to create both node and connection between nodes. While it's excellent and I will probably expand on that concept adding even more options for New-DiagramNode, it's sometimes hard to put everything in one command. That's why there's a New-DiagramLink function. You can use both one to create a node (with or without any links) and use New-DiagramLink to connect those nodes.

Please notice that I'm using a workaround for icons and convert them to Images using IconAsImage. This is only a temporary solution but fully functional. As you can see in below code, I have a few additional commands in use. Namely New-DiagramOptionsLinks, New-DiagramOptionsNodes and New-DiagramLink. The Options commands manage what the default setting for Node or Link is. This way, you can control colors, fonts on a global level rather than node/link level. You can also use New-DiagramOptionsLayout, New-DiagramOptionsInteraction, and New-DiagramOptionsPhysics to influence further how your diagram is behaving.

New-HTML -TitleText 'My Ubiquiti Network' -UseCssLinks:$true -UseJavaScriptLinks:$true -FilePath $PSScriptRoot\Example-NodesEdgesOptions.html {
    New-HTMLPanel {
        New-HTMLDiagram -Height '1024px' {
            New-DiagramOptionsInteraction -Hover $true
            New-DiagramOptionsPhysics -Enabled $false
            New-DiagramOptionsLayout -RandomSeed 0
            New-DiagramOptionsLinks -ArrowsToEnabled $true -Color BlueViolet -ArrowsToType arrow -ArrowsFromEnabled $false
            New-DiagramOptionsNodes -BorderWidth 1 -FontColor Brown -Size 20 -FontMulti true
            New-DiagramNode -Label 'Test' -IconBrands apple
            New-DiagramNode -Label 'USG Pro' -To 'Unifi Switch' -IconSolid cloud -IconAsImage
            New-DiagramNode -Label 'Unifi Switch' -To 'Unifi AP', "EvoWin" -IconSolid network-wired -IconAsImage
            New-DiagramNode -Label 'Unifi AP' -To 'EvoMac', "EvoWin" -IconSolid wifi -IconAsImage
            New-DiagramNode -Label 'EvoMac' -IconSolid laptop -IconAsImage
            New-DiagramNode -Id 'EvoWin' -Label "EvoWin`r`n192.168.20.15"  -To 'Exch1', 'Exch2', 'AD1', 'AD2', 'AD3', 'DC1', 'DC2' -IconSolid desktop -FontColor Green -IconAsImage
            New-DiagramNode -Label 'Exch1' -Shape diamond
            New-DiagramNode -Label 'Exch2' -IconBrands stack-exchange
            New-DiagramNode -Label 'Exch3' -IconBrands apple
            New-DiagramNode -Label 'Exch4' -IconBrands apple-pay -IconColor Silver -FontColor Green -X -300
            New-DiagramNode -Label 'AD1' -ColorBorder Black -ColorBackground Red -Image 'https://cdn.imgbin.com/18/1/14/imgbin-active-directory-microsoft-powershell-lightweight-directory-access-protocol-colossus-YaNhkKVhzC7F48Yd8YiNy2YKw.jpg'
            New-DiagramNode -Label 'AD2' -IconSolid ad -IconAsImage #-X 0 -Y 0 #-IconColor BlueViolet
            New-DiagramNode -Label 'AD3' -IconSolid ad -IconAsImage #-X 500 -Y -1000
            New-DiagramNode -Label 'DC1' -IconSolid ad -IconAsImage #-X -500 -Y -500 #-FixedX $true -FixedY $false
            New-DiagramNode -Label 'DC2' -IconSolid ad -IconAsImage #-X 500 -Y 500
            New-DiagramLink -From 'USG Pro', 'AD3' -To 'DC1', 'AD3' -ArrowsToEnabled $false -ArrowsMiddleEnabled $true -ArrowsFromEnabled $false -Color Green -Dashes $true -Label 'Test'
            New-DiagramLink -From 'DC1' -To 'DC2' -Label 'This is my label' -FontColor HotPink -ArrowsToEnabled $true
        }
    }
} -ShowHTML

Above you can see New-DiagramLink can have its Labels, Fonts, and Colors. Each link can have up to three Arrows (From / To / Middle). Each connection can have multiple relations. New-DiagramLink From and To parameters operate on ID which by default is the same as Label. But as I mentioned before if you have multiple ID's or more complicated Labels using new lines, very long text, it may be better to define ID parameter for nodes.

PSWriteHTML - Commands available for Diagramming

I've defined several commands that should help with creation of nice looking diagrams.

  • New-HTMLDiagram – defines diagram
  • New-DiagramLink – controls adding links to between nodes
  • New-DiagramNode – controls adding nodes/objects to diagram
  • New-DiagramOptionsInteraction – responsible for interaction options
  • New-DiagramOptionsLayout – responsible for layout
  • New-DiagramOptionsLinks – responsible for global settings to links
  • New-DiagramOptionsManipulation – responsible for ability to modify nodes/links online
  • New-DiagramOptionsNodes – responsible for global settings to nodes
  • New-DiagramOptionsPhysics – responsible for setting up Physics options

While I've defined some options already, the library I'm using to generate this has far more options. If you feel you can contribute to this project by expanding its features, I would be more than happy to accept it.

Dashimo is now integrated in PSWriteHTML

As part of this PSWriteHTML release, I've decided to close down Dashimo project. Dashimo project has now been integrated into PSWriteHTML and is fully compatible with it. You no longer need to download Dashimo if you want to use its syntax.

Uninstall-Module Dashimo -AllVersions
Install-Module PSWriteHTML -Force

That's it. Just remove Dashimo, update/install PSWriteHTML and all your Dashimo scripts will work as before, with the added benefit of all other options from PSWriteHTML. This means all below commands are fully supported within PSWriteHTML.

  • Dashboard
  • Container
  • Panel
  • Section
  • Tab
  • TabOptions
  • Chart
  • ChartAxisX
  • ChartAxisY
  • ChartBar
  • ChartBarOptions
  • ChartCategory
  • ChartDonut
  • ChartGrid
  • ChartLegend
  • ChartLine
  • ChartPie
  • ChartRadial
  • ChartTheme
  • ChartToolbar
  • Diagram
  • DiagramEdge
  • DiagramEdges
  • DiagramLink
  • DiagramNode
  • DiagramOptionsEdges
  • DiagramOptionsInteraction
  • DiagramOptionsLayout
  • DiagramOptionsLinks
  • DiagramOptionsManipulation
  • DiagramOptionsNodes
  • DiagramOptionsPhysics
  • Table
  • TableButtonCopy
  • TableButtonCSV
  • TableButtonExcel
  • TableButtonPageLength
  • TableButtonPDF
  • TableButtonPrint
  • TableConditionalFormatting
  • TableContent
  • TableHeader
  • TableReplace
  • Image
  • Text

I hope this change will make it easier to manage future updates. I'm thinking of integrating Emailimo back to PSWriteHTML as well, although this one has more code in place that doesn't have equivalent in PSWriteHTML. But since it heavily relies on PSWriteHTML, it may be the obvious choice.

This post was last modified on September 30, 2019 09:54

Przemyslaw Klys

System Architect with over 14 years of experience in the IT field. Skilled, among others, in Active Directory, Microsoft Exchange and Office 365. Profoundly interested in PowerShell. Software geek.

Share
Published by
Przemyslaw Klys

Recent Posts

Upgrade Azure Active Directory Connect fails with unexpected error

Today, I made the decision to upgrade my test environment and update the version of…

1 week ago

Mastering Active Directory Hygiene: Automating Stale Computer Cleanup with CleanupMonster

Have you ever looked at your Active Directory and wondered, "Why do I still have…

4 months ago

Active Directory Replication Summary to your Email or Microsoft Teams

Active Directory replication is a critical process that ensures the consistent and up-to-date state of…

8 months ago

Syncing Global Address List (GAL) to personal contacts and between Office 365 tenants with PowerShell

Hey there! Today, I wanted to introduce you to one of the small but excellent…

1 year ago

Active Directory Health Check using Microsoft Entra Connect Health Service

Active Directory (AD) is crucial in managing identities and resources within an organization. Ensuring its…

1 year ago

Seamless HTML Report Creation: Harness the Power of Markdown with PSWriteHTML PowerShell Module

In today's digital age, the ability to create compelling and informative HTML reports and documents…

1 year ago