Create a new stencil and populate master shapes from image files via PowerShell?

Started by PinPinPoola, March 21, 2024, 03:58:05 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.


Has anyone any example PowerShell code to create a new stencil and populate it's master shapes from external image files (.png | .svg)?

I have tried recording a VBA macro and then 'converting' it to Powershell, but I am getting nowhere fast. Even ChatGPT eventually gave up giving suggestions.

I will appreciate any help/suggestions.



Hi, Pin!
Quote from: PinPinPoola on March 21, 2024, 03:58:05 PM
I have tried recording a VBA macro and then 'converting' it to Powershell, but I am getting nowhere fast.
Not all actions can be write via macro-recorder!  :(
Right now I have not time for PowerShell coding, but I prepare this VBA-code for 5 minutes...
Sub PicturesImportToDocStencil()
    Dim strPath As String
    Dim strFile As String, fullname As String
    Dim cnt As Integer
    Dim mst As Visio.Master
    Dim wn As Window
    cnt = 0
    strPath = "C:\Users\surrogate-tm\Pictures\VisioObjectModel\"
    strFile = Dir(strPath & "*.*") ' Searches for all files
    Do While strFile <> ""
        cnt = cnt + 1
        Debug.Print cnt, strFile
        Set mst = ActiveDocument.Masters.Add
        mst.Name = cnt
        mst.Prompt = ""
        mst.IconSize = visNormal
        mst.AlignName = visCenter
        mst.MatchByName = False
        mst.IconUpdate = visAutomatic
        Set wn = mst.Open.OpenDrawWindow
        fullname = strPath & strFile
        wn.Master.Import fullname
        strFile = Dir()
End Sub


Thank you Surrogate.

I am still struggling with VBA, but getting much better with PowerShell these days; as my job uses it more & more.

As always, I really appreciate your help.

Take care,




Thank you both for Saveenr's details. I will take a look.

In the mean time @Surrogate I have had time to try your suggested code and nothing happens when I run it.

I have updated the strPath to my own path and strFile to (*.svg)

When I run the code, the Visio session 'flashes' or refreshes for each file, but no new shapes appear.

I have tried opening the new stencil file for edits.

Am I doing something wrong?



Quote from: PinPinPoola on March 22, 2024, 01:50:46 PMAm I doing something wrong?
My simple code add new master-shapes to local document stencil, it not create new external stencil!!!

Please check Show Document Stencil option...


Quote from: PinPinPoola on March 21, 2024, 05:09:21 PMbut getting much better with PowerShell these days; as my job uses it more & more.
Sorry, I am not PowerShell exert :-\

$visio = [Runtime.Interopservices.Marshal]::
GetActiveObject('Visio.Application')   # Get Visio.App session   
# Get Visio ActiveDocument
$Doc = $visio.ActiveDocument     
# Set Masters counter 
$n = 0   
# Set folder path   
    $Path= 'C:\Users\surrogate-tm\Pictures\VisioObjectModel' 
    Get-ChildItem -Path $Path | ForEach-Object {
# Iterate SVG files
        If ($_.Name -like "*.svg") {
# Increment counter
            $n = $n+1
# Get current SVG fullname
            $fn = $_.FullName
# Create new master
            $mst = $doc.Masters.Add()
# Rename new master
            $mst.Name = $n
# Set normal iconsize (visNormal = 1)
            $mst.IconSize = 1
# Set align name (visCenter)
            $mst.AlignName = 2
# No MatchByName option
            $mst.MatchByName = $False 
# Set IconUpdate mode (visAutomatic = 1)
            $mst.IconUpdate = 1
# My code cant open master window
            $wn = $mst.Open.OpenDrawWindow
# I want Activate window,  but I cant do this
# Import SVG picture
            $wn.Master.Import, $fn
# Close master's window
# Debug output
            Write-Host -Object "Added master: $fn"
        } ElseIf ($_.PSIsContainer) {
# ???
        } # End If-ElseIf.

I cant translate VBA code row
Set wn = mst.Open.OpenDrawWindow


Visio Super Utilities can do that:

Use Stencil -> Create Stencil From Images

You will be prompted for the stencil name, and to pick the images to create the stencil from.


Quote from: Nikolay on March 23, 2024, 09:07:34 PM
Visio Super Utilities can do that
Sorry, I forgot!
My code is just for memory!
I had a problem with importing a picture. I couldn't do it without drawing a rectangle before importing the picture. $visio = [Runtime.Interopservices.Marshal]:: GetActiveObject('Visio.Application') # Get active Visio session
$visio.AlertResponse = $true # AlertResponse change to
$target = 'C:\Forum_BU\gifs\test1.vss' # Path for new stencil
$st = $visio.Documents.Addex('', 0, 516) # Create new stenctl
$n = 0
$Path= 'C:\surrogate-tm\Pictures\VisioObjectModel'

    Get-ChildItem -Path $Path | ForEach-Object {
        If ($_.Name -like "*.*") { #
            $n = $n+1
            $fn = $_.FullName
            $mst = $st.Masters.Add()
            $mst.Name = $n
            $mst.Prompt = ""
            $mst.IconSize = 1 #visNormal
            $mst.AlignName = 2 #visCenter
            $mst.MatchByName = $False
            $mst.IconUpdate = 1 #visAutomatic
            $wn = $mst.OpenDrawWindow()
            $sh1 = $wn.Master.DrawRectangle(0,0,0,0) # Draw rectangle
            $sh2 = $wn.Master.Import($fn) # Import picture
            $sh2.Cells("LocPinX").Formula = 'Width*0'
            $sh2.Cells("PinX").Formula = '0 mm'
            $sh2.Cells("LocPinY").Formula = 'Height*0'
            $sh2.Cells("PinY").Formula = '0 mm'
            $wn.Master.Close() # Close master

        } ElseIf ($_.PSIsContainer) {

        } # End If-ElseIf.
    } # End ForEach-Object.
    $visio.AlertResponse = $false #
    $st.SaveAs($target) # Save stencil
    $st.close() # Close stencil
    $visio.Documents.OpenEx($target, 6) # Open stencil for RO


Visio 2019 Pro


That's not fair. PS got a super hero as mascot, we've haven't got more than a funny nerd head.


Well, desperate does as desperate needs.  Obviously PowerShell feels creative need to expand user base. 

I was perusing PowerShell to see if there's any utility gained for Visio users.  I have mixed feelings.  I'm am most doubt.  Visio is so inherently powerful, I see little point, if any, to use Visio PowerShell.  The idea of Visio was to be visual object oriented, and, for the most part, avoid doing design/entry via a textual input.  PowerShell seems like a step backwards...use a textual input to drive a graphics tool?  Yes, there are unforeseen missing tools, but these can be provided from within Visio.  This topic, case in point.  Nikolay has tool that does what was requested of PowerShell. 

I even tried using binges to do this.  It failed.  It created a solution, code failed, pointed out error, fix failed.  Yada. Yada.  So, then I tried...and failed.    There are a couple sites, and YouTube vids, but this is too much of a niche topic to motivate investment time to learn something I'll not use again. 

Perhaps some of the other power users will pick up on this.
Visio 2019 Pro


OK.  So I am officially off my rocker!  Why? Well, 1) Nikolay has a working solution from inside Visio, 2) I know nothing about PowerShell, com stuff, etc., and 3) I hate programming.

Well, with the help of BingAI, below is working PowerShell code (script, I guess).

Some things to note:
1) translating image files into Visio shapes requires, uh, Visio.  That then begs the question, why not use Nikolay's solution.
2) the code works, mostly.  Issue with quitting VisiThe use and the pop-up dialog asking yes, no, cancel. 
3) this is proof of concept, so, code only grabs a single image.  Some sort of loop would be needed to grab more than 1
4) User must use appropriate file locations and names.
5) this code is a collaborative effort between me and BingAI

# Define the path to the image file you want to add
$imagePath = "C:\VisioPix\MyImage1.jpg"

# Define the name for the new master
$masterName = "MyImage1"

# Create a new Visio application object
$visioApp = New-Object -ComObject Visio.Application

# Make Visio invisible to the user (no UI)
$visioApp.Visible = $false

# Create a new document for importing the image
$doc = $visioApp.Documents.Add("")

# Import the image to the new document
$importedShape = $doc.Pages.Item(1).Import($imagePath)

# Define the path to the Visio stencil file
$stencilPath = "C:\VisioPix\Pix.vssx"

# Open the stencil file
$stencil = $visioApp.Documents.OpenEx($stencilPath, 64)

# Create a master of the imported image in the stencil
$master = $stencil.Drop($importedShape, 0, 0)

# Set the name for the new master
$master.Name = $masterName

# Save the modified stencil

# Close the stencil and the new document

# Quit Visio

# Release the COM objects

# Print a success message
Write-Host "Task execution done."
Visio 2019 Pro


Apologies that I have not replied sooner, but I had to go away with work for a few days.

Thank you all so much for your help; especially to Surrogate, as your second PowerShell script worked perfectly for me.