vDiagram – Draw your VI with one script

Every good blog post should have some real life story to help you visualise why things happen so here goes:

The Story
One day whilst sat in the office updating the disaster recovery documentation I needed to document the Virtual Infrastructure, we all know that managers like pretty pictures so the first thing they asked for was a pretty diagram of how the infrastructure looked.
After dropping my 40th VM object on the page I started to get a bit bored, i looked at other options.  There is already a great tool on the market that performs this job, Veeam Reporter produces multiple documents and does a great job, but being a contractor I have a nil budget.  Knowing that you can do some very cool things with Powershell I wondered how easy it would be to hook into the Visio com object to get powershell to create the document for me.
As it turns out it wasn’t that hard, there were a few sticky moments where I had to refer to the Visio forums, and a great starting point by the only powershell reference using Visio I could find (Check out CommandBreak_ Thanks Joeseph) after explaining what powershell was to the guys in the Visio Forum and explaining why I was using powershell as I think this is the first time these people had heard of it, I started to relate some of there c# examples back into powershell.
The Result
The result is by no means a totally polished all singing all dancing documenter that documents your VI from the left, from the right and upside down but what it is, is an example of what you can do with the Visio COM objects and powershell combined.
I have not yet included all the options I would like, in future versions I would like to be able to document the networking setup / storage paths etc but I’m working on something else so wanted to get this script out into the public.
Instructions
You will need:
  • Powershell V1 (I haven’t tried it on V2 yet)
  • The VI Toolkit
  • Microsoft Visio (I have only tried 2003 +)
How to use:
  1. Download the zip file from the bottom of this page
  2. Once extracted copy the  ‘My-VI-Shapes.vss‘ file to your ‘My Documents\My Shapes’ folder.  If the folder does not exist create it and copy the file in.
  3. Run the powershell script with the following options:
To diagram the entire Infrastructure:
vDiagram.ps1 –VIServer MYVISERVER

To diagram a specific cluster use the following:
vDiagram.ps1 –VIServer MYVISERVER -Cluster “Production Cluster’

Example Output

71 thoughts on “vDiagram – Draw your VI with one script”

  1. I love this script, question, when I run it, I cannot get it to populate the server names, below is the error:

    Exception setting “Text”: Cannot convert the “SRVFORMS01” value of type “VirtualMachineImpl” to type “string”.

    Please advise on any solution you may have.

  2. Hi Alan,

    I get these errors when I run the script:

    PowerCLI C:\temp> .\vDiagram01.ps1 -VIServer vc01.neverland.local
    Connecting to vc01.neverland.local
    Exception calling “Add” with “1” argument(s): ”
    File not found.”
    At C:\temp\vDiagram01.ps1:62 char:34
    + $stnObj = $AppVisio.Documents.Add <<<< ($stnPath + $shpFile)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:63 char:30
    + $VCObj = $stnObj.Masters.Item <<<< ("Virtual Center Management Console")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:64 char:32
    + $HostObj = $stnObj.Masters.Item <<<< ("ESX Host")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:65 char:30
    + $MSObj = $stnObj.Masters.Item <<<< ("Microsoft Server")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:66 char:30
    + $LXObj = $stnObj.Masters.Item <<<< ("Linux Server")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:67 char:34
    + $OtherObj = $stnObj.Masters.Item <<<< ("Other Server")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:68 char:31
    + $CluShp = $stnObj.Masters.Item <<<< ("Cluster")
    + CategoryInfo : InvalidOperation: (Item:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Adding vc01.neverland.local
    Exception calling "Drop" with "3" argument(s): "
    An exception occurred."
    At C:\temp\vDiagram01.ps1:40 char:27
    + $shpObj = $pagObj.Drop <<<< ($mastObj, $x, $y)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Property 'Text' cannot be found on this object; make sure it exists and is sett
    able.
    At C:\temp\vDiagram01.ps1:42 char:13
    + $shpObj. <<<< Text = $item.name
    + CategoryInfo : InvalidOperation: (Text:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : PropertyNotFound

    Adding Neverland Cluster
    Exception calling "Drop" with "3" argument(s): "
    An exception occurred."
    At C:\temp\vDiagram01.ps1:40 char:27
    + $shpObj = $pagObj.Drop <<<< ($mastObj, $x, $y)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Property 'Text' cannot be found on this object; make sure it exists and is sett
    able.
    At C:\temp\vDiagram01.ps1:42 char:13
    + $shpObj. <<<< Text = $item.name
    + CategoryInfo : InvalidOperation: (Text:String) [], RuntimeExcep
    tion
    + FullyQualifiedErrorId : PropertyNotFound

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:30 char:67
    + $connectBegin = $shpConn.CellsU("BeginX").GlueTo($firstObj.CellsU <<<< ("
    PinX"))
    + CategoryInfo : InvalidOperation: (CellsU:String) [], RuntimeExc
    eption
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At C:\temp\vDiagram01.ps1:33 char:64
    + $connectEnd = $shpConn.CellsU("EndX").GlueTo($secondObj.CellsU <<<< ("Pin
    X"))
    + CategoryInfo : InvalidOperation: (CellsU:String) [], RuntimeExc
    eption
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Any thoughts?

  3. This is great, however when I run it, it doesn’t add the machine names. I’m getting the following error…

    Exception setting “Text”: Cannot convert the “SERVER NAME” value of type “VirtualMachineImpl” to type “string”.

    Any ideas?

    Visio 2013

  4. WOW! Not only is this script worthy of an innovation award, it looks extremely familiar to me. Great share! I’m sure others can use it for extreme gainz within their company.

  5. All,

    I’m currently working on adding an additional functionality to the script. Specifically, eliminating the ESX host within the ESX cluster visio plotting due to the diagram being inconsistent if vmotion via DRS is enabled for the cluster. I have already modified the script to connect the VM guest directly to ESX cluster. I’m also adding additional information to be added for each VM guest (OS version, IP address (Nic1), MemoryGB, NumCPU) as well as updating the stencil objects being used.

    More Information to follow, so stay tuned

    Best,

    Blairzy
    VCP6-DCV
    MCSE 2012 Server Infrastructure
    MCSA: Windows Server 2012
    MCSA: Windows Sever 2008

    1. Did you find a way to add the VM guest (OS version, IP address (Nic1), MemoryGB, NumCPU) when it is doing the visio diagram?

  6. Works fine with PowerCLI 6.0 R3 with Visio 2013 with one minor tweak for VM names to be displayed in. Line 42: “$shpObj.Text = $item” needs to be updated to “$shpObj.Text = $item.name”

  7. I was able to get this working with Visio 2013, on Windows 8.1 on a Vsphere 5.5 VC today! Once I installed VMware-PowerCLI-5.5.0-1295336, I had to ‘Set-ExecutionPolicy Unrestricted’ for Powershell to allow it to run.

    1. I tried this but get –

      Index was outside the bounds of the array.
      At D:\Documents\VMware\PowerCLI\vDiagram\vDiagram.ps1:42 char:5
      + $shpObj.Text = $item
      + ~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : OperationStopped: (:) [], IndexOutOfRangeException
      + FullyQualifiedErrorId : System.IndexOutOfRangeException

      Any thoughts?

  8. Hi alan, Thanks for sharing, I followed the instructions by copying ‘My-VI-Shapes.vss‘ file to ‘My Documents\My Shapes’ folder. I ran the script, it ran successfully and it showed it saved the file with the name of my_vdiagram.vsd but i do not see any file in that path, I searched entire C drive with file name or *.vsd. There is none. I am wondering did it actually create something?

  9. This is a great script – however i’m having an issue where it wants to draw each cluster twice before it ends.

    Any ideas.

    Also i’ve modified it to produce a view of datastores.

    Added:
    $Storage = $stnObj.Masters.Item(“Folder”) under # Load a set of stencils and select one to drop

    Then Added:
    ForEach ($VMHost in (Get-Cluster $Cluster | Get-VMHost))
    {
    $Object1 = add-visioobject $HostObj $VMHost
    connect-visioobject $CluVisObj $Object1
    ForEach ($DataStore in (Get-vmhost $VMHost | Get-Datastore))
    {
    $x += 1.50

    $object2 = add-visioobject $Storage $DataStore

    Again i’m up against the issue where it wants to diagram everything twice.

    Cheers,
    Nathan.

  10. I am looking for the updated script on thevesi.
    I have PowerGUI and the power pack installed and would like to use the updates vDiagram script as mu vurrent visio is a litte crazy due to hundreds of VMs.

  11. Will this script also work to display the same volumes information for vfilers? If so how do I modify this script to display this information.

  12. Would it be possible to populate each object with VM machine detail? like IP MAC, CPU count , RAM etc?

    I’m saving the detail to an htm doc and publishing this for non VC users to see.

    Thanks for everything

  13. Maybe you could change the blog subject title vDiagram – Draw your VI with one script | Virtu-Al to something more better for your blog post you create. I loved the post however.

  14. Sorry for the stupit question but I’ll get always this error:

    The term ‘.\vDiagram.ps1’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check
    the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:15
    + .\vDiagram.ps1 <<<< -VIServer em1apvm001
    + CategoryInfo : ObjectNotFound: (.\vDiagram.ps1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Thanks
    Guido

  15. How would this work in a large environment, say 110 ESX hosts and 1500 VMs? Would the resulting file be usable or printable? Maybe on a plotter?

  16. Hello thanks for that however the power gui version seems to only work with visio 2007 and our desktop soe is office 2003.

    1. Josh,

      That is true for the moment buy I happen to have a little inside knowledge and don’t worry, you will be a happy man soon 😉

    1. Yeah this is easy enough and I was planning on a V2 of this script but….. If you check out what has been done in the PowerGUI Powerpack with this script and also look out on http://www.thevesi.org they will be adding this to there version (which is better than this one) in the near future.

      Hope that helps.

  17. Alan,
    For the “My Shapes” path, try this instead:

    $stnPath = $AppVisio.MyShapesPath

    Thanks for the great script.

    Cameron

  18. Errors out with:

    Adding
    Get-VMHost : The argument cannot be null or empty.
    At C:\scripts\vDiagram.ps1:136 char:30

    Any ideas?

  19. Alan,
    Nice work, especially given the always tough to find documentation for Visio. Can’t wait for version 2, maybe add a title to page?
    gb

  20. Can someone post instructions on how to wrap the VMs to a second line (ie. 50 VMs on one host makes a big long diagram)…

  21. Joe,

    Im so sorry, I knew I missed someone out of the credits, I have ammended the post to include a link to the great CommandBreak_ site. Thanks for all of Ben’s help.

    Alan

  22. If 46 VMs on one host makes your diagram a little on the wide side, it is possible to wrap them onto additional rows.

    The changes will take too long to describe here but it is possible.

  23. Brilliant!

    My current client has a bizarre policy of using very long VM names however for clones that they have produced for backup purposes. To get around that I have added the following:

    1. A line beneath the $Savefile declaration:

    [int]$maxtextlength = 15

    2. A function in with the other functions:

    function format-itemtext($item)
    {
    $itemtext = $item.Name
    if($maxtextlength -lt [int]$itemtext.length)
    {
    $itemtext = $itemtext.substring(0,$maxtextlength) + “…”
    }
    return $itemtext
    }

    3. Modified one line in the function add-visioobject:

    $shpObj.Text = format-itemtext($item)

    The result is VM names truncated to 15 characters plus “…” to indicate that they are not the full name.

  24. Awesome stuff Alan,

    Changed Line 93 from:
    ForEach ($VM in (Get-vmhost $VMHost | get-vm))

    To:
    ForEach ($VM in (Get-vmhost $VMHost | get-vm -NoRecursion))

    This fixes all VMs showing up under all hosts. Also fixed some of the Visio shapes with font size, etc. Was easy since I made the originals! Awesome awesome stuff.

  25. Thanks Chris, couldn’t have done it without your brilliant forum and help !

    Hopefully others on your forum will see the power of using Visio and PowerShell together 🙂

    Alan

Leave a Reply