Using PowerShell to update Visio diagrams

Being in IT or architecture generally means using Visio, FACT!

I have been completing lots of work in Visio recently as part of document migration into a Enterprise Architecture tool called iServer.  This required me to dust off my knowledge of VBA and creating lots of macros.  I am not a massive fan of macros, they seem really archaic.

In the more recently iterations of these scripts, I realised that I could use PowerShell to complete the same tasks.  PowerShell is something I am far more comfortable with and because it sits outside of the application itself, there is more opportunity to run scripts against a larger set of files.

Rather than bore you with some of the scripts I created for my business process diagrams, the below example is a script which you can use to update IT related documents.

Below I have a rack diagram I created in Visio.  It has four servers and one router with their names added to ShapeData and a Data Graphic which shows this as a bubble.

Before


Now, wouldn't be cool if you could update all of your documents with IP address without having to sit there typing it in?  Well that is what I did!


This is the result

After
Here is the script which completes this task

#Ask the user which folder the files are stored
$location = read-host "Where are the files stored"
#Get all visio files in the location specifed
$files = get-childitem $location | where {$_.Name -match ".vsd"}

#loop that will go through each visio file in the folder
ForEach ($File in $Files){

#create Visio com object
$visio = New-Object -comobject Visio.Application

#open next file in list
$Visio.Documents.Open($file.fullname)

#loop that will go through each shape on the page
ForEach ($vsoShape In $visio.application.activepage.shapes) {

#get master, if Server or Router, then do an NSlookup of the name and apply the resultant IP address to the shape in question
$master = $vsoShape | select -expand Master 
If($master.name -eq "Server" -or $master.name -eq "Router 1")
{

$networkname = $vsoshape.cells("Prop.NetworkName").ResultStr(0)
$ipaddress = Resolve-DnsName $networkname | select IPaddress | foreach {$_.IPaddress}
$vsoCell = $vsoShape.Cells("Prop.IPaddress")
$vsoCell.formula = """$ipaddress""" 

}
}

#save the document
$visio.Application.ActiveDocument.Save()
#quit visio afterwards
$visio.Application.Quit()

}

You can see how this script could be edited to complete any manner of tasks.  If the information was in the Shape text itself you could use this

$characters = $vsoShape | select -Expand Characters
$char = $characters.textasstring

To see what else you can do programmatically with Visio, please see the MSDN page.

Got any tedious Visio task that you could do with automating?  Let me know in the comments.

Comments

  1. this is great. where are the ips assigned from? an excel doc?

    ReplyDelete
    Replies
    1. No, the beauty of the script is that it will do a DNS lookup and get the IP directly!

      Delete

Post a Comment

Popular posts from this blog

Assigning Windows 10/11 Enterprise Subscription Activation Licences to Hybrid Azure AD Joined Devices

Autopilot Hybrid Azure AD Join with Customised First Login Status

Exchange Hybrid Mailbox Move - Corruption Due To Missing Security Principals (ACL issues) - TooManyBadItemsPermanentException