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




The Download
This project has now moved to Github so please do add any changes you have back to the project for everyone to take advantage of here: https://github.com/alanrenouf/VisioPowerShell

85 thoughts on “vDiagram – Draw your VI with one script

  1. suresh

    can some one help me on this script. I am getting few errors while running this script.

  2. suresh

    Hi Alan, I am getting few errors while running this script. could you please help me on this

  3. Jim Journeay

    Hi Alan
    I love the script but I am finding it creates a visio diagram with 4 of each host an d 4 of each VM. I haven’t been able to find out why. If I could get it to just show one of each it would be perfect! Where is the script would it be doing this 4 times each?Thank you

  4. Jaspreet

    Hello
    Is new script with OS version, IP address (Nic1), MemoryGB, NumCPU parameters awailable

  5. Lovie L. Luckie, Jr.

    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.

  6. dindiyala@stlucieco.org

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

  7. laurent

    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?

  8. scottsmail

    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

  9. Securing Your Vision

    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.

  10. Blairzy

    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

  11. Darren

    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”

  12. Eoghan

    This Script runs fine but only produces a single object of the root vcenter, nothing else is displayed

  13. cchilderhose

    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?

  14. Mark H

    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.

  15. vmware_vs

    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?

  16. Graham F French

    This script saves me at least 1 to 2 days each time I run it. Capturing the Virtual Infrastructure by hand is a non-starter! Thanks for a great piece of work!

  17. Nathan Currie

    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.

  18. Darren

    sorry i know that thevesi is dead. What I mean is where is the updated vDiagram script now.
    Sorry

  19. Darren

    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.

  20. Pingback: Netapp Powershell & PowerCLI Scripts « NetApperos.com

  21. TR

    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.

  22. Pingback: Virtu-Al | Virtually everything is poshable

  23. Alan Post author

    Sorry Imy, someone hacked my site last week and im only just restoring things fully now, hopefully it should be there now.

  24. Nathan

    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

  25. Player Profiles

    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.

  26. Guido

    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

  27. Pingback: vSphere Documenters « Roshan Ratnayake – IT Architect

  28. Pingback: Draw your VI environment with a script « a CraZy PeNguIn

  29. Bill

    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?

  30. Pingback: Beta: Vizioncore Virtualization EcoShell « ICT-Freak.nl

  31. Virtu-Al

    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 😉

  32. Josh williams

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

  33. Virtu-Al

    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.

  34. Pingback: Travel back in time with Veeam Reporter - Storage Informer

  35. Pingback: VMware Infrastructure PowerPack 2.1.5 released « Poshoholic

  36. Virtu-Al

    Cameron, Thanks, neat trick, BTW I think you may need to invest in some knee pads by the looks of your blog !

  37. Cameron

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

    $stnPath = $AppVisio.MyShapesPath

    Thanks for the great script.

    Cameron

  38. Virtu-Al

    Patrick, Thanks for your Translation 🙂

    David, Can you send me a little detail about your envionment. Thanks

  39. Patrick

    For all german Users out there:

    Chage Line 61 to “Meine Shapes” instead of “My Shapes”

  40. David

    Errors out with:

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

    Any ideas?

  41. Anonymous

    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

  42. Stephen

    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)…

  43. Virtu-Al

    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

  44. Michael Poore

    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.

  45. Michael Poore

    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.

  46. Scott Herold

    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.

  47. Virtu-Al

    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

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.