View And Data API


Wouldn’t it be cool to access your 3D models from the web? Autodesk came out with a new technology called View And Data API, which allows displaying several file formats directly in your web-browser without the need of any plugin. Here’s a sample.

I know, as soon the word “cloud” is spoken, some of you are getting skin irritations, but sooner or later, accessing data in a meaningful way will be mandatory.

With this post, I’d like to show you how the View And Data API can be consumed via PowerShell, and to be more precise, via powerJobs. The following job will take an assembly from Vault and upload the files to the cloud services so that it can be viewed. The steps are more or less simple: login, create a folder (bucket), upload the files, create the references between the files, and start the translation.

Now, the entire world is moving toward REST API, which is the de-facto API language used in the web/cloud. Microsoft added a handy command-let with PowerShell 3.0. The command-let is called Invoke-RestMethod.

And here is the job

Add-Log -Text ">> starting cloud upload job"
$ConsumerKey="your consumer key"
$ConsumerSecret="your consumer secret"
$bucketName = "coolorange" #must be lower case and/or numbers
$policy = "transient" #transient

$file = PrepareEnvironmentForFile "Suspension.iam"

Add-Log -Text "Log in to ViewAndData..."
$login = Invoke-RestMethod -Uri "" -ContentType "application/x-www-form-urlencoded" -Method Post -Body "client_id=$ConsumerKey&client_secret=$ConsumerSecret&grant_type=client_credentials"
$auth = $login.token_type + " " + $login.access_token
$json = '{"bucketKey":"'+$bucketName+'","policy":"'+$policy+'"}'
Add-Log -Text "Creating bucket $bucketName ..."
$bucket = Invoke-RestMethod -Uri "" -ContentType "application/json" -Method Post -Body $json -Headers @{"Authorization"=$auth}

Add-Log -Text "Downloading file $($file.Name)"
$localTempPath = "c:\Temp\webview"
$assembly = Get-VaultFile -File $file.'Full Path' -DownloadPath $localTempPath
Get-ChildItem $localTempPath -Recurse -File | ForEach-Object { $_.IsReadOnly = $false }

$json = '{ "master" : "urn:adsk.objects:os.object:coolorange/'+$assembly.Name+'", "dependencies" : ['

$localFullPath = $assembly.'Full Path'
Add-Log -Text "-$localFullPath"
$localFullPath = $localFullPath.Replace("$",$localTempPath).Replace("/","\")
Add-Log -Text "uploading $localFullPath ..."
$filesInWeb =  @()
$fileInWeb = Invoke-RestMethod -Uri "$bucketName/objects/$($assembly.Name)" -ContentType "application/octet-stream" -Method Put -Headers @{"Authorization"=$auth;"Content-Length"=$assembly.'File Size';"Expect"=""} -InFile $localFullPath
$filesInWeb += $fileInWeb

$children = Get-VaultFileAssociations -File "$/Designs/Suspension/Suspension.iam" -Dependencies
foreach ($child in $children) {
  $json += '{ "file" : "urn:adsk.objects:os.object:coolorange/'+$child.Name+'", "metadata" : { "childPath" : "'+$child.Name+'", "parentPath" : "'+$assembly.Name+'" } },'
  $localFullPath = $child.'Full Path'
  $localFullPath = $localFullPath.Replace("$",$localTempPath).Replace("/","\")
  Add-Log -Text "uploading $localFullPath ..."
  $fileInWeb = Invoke-RestMethod -Uri "$bucketName/objects/$($child.Name)" -ContentType "application/octet-stream" -Method Put -Headers @{"Authorization"=$auth;"Content-Length"=$child.'File Size';"Expect"=""} -InFile $localFullPath
  $filesInWeb += $fileInWeb
$json = $json.Substring(0,$json.Length-1)
$json += ']}'
Add-Log -Text "Set the references"
$references = Invoke-RestMethod -Uri "" -ContentType "application/json" -Method Post -Body $json -Headers @{"Authorization"=$auth}

$services = @()
foreach($fileInWeb in $filesInWeb)
  $fileName = $fileInWeb.objects[0].key
  Add-Log -Text "Start conversion for $fileName"
  $fileName = [System.Web.HttpUtility]::UrlEncode($fileName)
  $urn = "urn:adsk.objects:os.object:$bucketName/$fileName"
  $base64 = [convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($urn))
  $json = '{"urn":"'+$base64+'"}'
  $service = Invoke-RestMethod -Uri "" -ContentType "application/json" -Method Post -Body $json -Headers @{"Authorization"=$auth}
  $services += $service

Add-Log -Text "<< Job completed!"

You can just copy paste it into a PS1 file within the C:\ProgramData\coolOrange\powerJobs\Jobs folder. Then go to an assembly in Vault and queue this job via powerJobs.

For the sake of simplicity, this job just takes care about one level of children. So, for multilevel assemblies, the job would have to be executed recursively for each level.

The key thing here is that you can see how to consume the View And Data API within PowerShell, and so create your own scripts, and how to combine this with Vault.

In order to see the uploaded files you need your own little web page, which is not part of this post. But if you like to know more about this technique, you can follow the quick start guide. If you like to get this job running on your side, you need to create your own account and place the consumer key and secret at the top of this script.

We love this stuff and will play more and talk more about this in the next months, so, in case you like this too, share your ideas with us!


Posted in powerJobs, PowerShell | Leave a comment

New folder with subfolders

2015-02-20_00-16-46Some months ago, we made this post regarding creating a folder and automatically copying the subfolder tree from a template. In that post, the folder tree was inside Vault. We received several comments asking whether it would be possible to hold the folder tree outside Vault, for instance in an XML file. This post will show you how to do it.

In an XML file we define which templates are available and how the folder structure looks like. In this case the XML file is called Templates.xml and looks like this

<?xml version="1.0" encoding="utf-8"?>
<Template Name="Production">
   <Folder Name="Folder1" Category="Project">
     <Folder Name="SubFolder1" Category="Folder">
       <Folder Name="SubSubFolder1" Category="Base" />
     <Folder Name="SubFolder2" Category="Project" />
   <Folder Name="Folder2" Category="Project"></Folder>
   <Folder Name="Folder3" Category="Project"></Folder>
<Template Name="Design">
   <Folder Name="Folder1" Category="Base">
     <Folder Name="SubFolder1" Category="Base">
       <Folder Name="SubSubFolder1" Category="Base" />
     <Folder Name="SubFolder2" Category="Base" />
   <Folder Name="Folder2" Category="Base"></Folder>
<Template Name="Marketing">
   <Folder Name="Folder1">
     <Folder Name="SubFolder1" Category="Base">
       <Folder Name="SubSubFolder1" Category="Base" />
     <Folder Name="SubFolder2" Category="Base" />
   <Folder Name="Folder2" Category="Base"></Folder>

As you can see, the first level of the XML contains the templates with an attribute name, while each template contains a nested folder tree structure with folder Name and folder Category.

The XAML file for the folder creation (Folder.xaml), will be extended by a combobox which reads the template names from the XML file. In order to do this, we add a resource in the MainWindow.Resources section of the XAML, like this

<XmlDataProvider x:Key="templates" Source="C:\ProgramData\Autodesk\Vault 2015 R2\Extensions\DataStandard\Vault\Configuration\FolderTemplates.xml" XPath="//Template"/>

later in the combobox, we can point to this resource and display the attribute name in the list, like this:

<ComboBox ItemsSource="{Binding Source={StaticResource templates}}" DisplayMemberPath="@Name" SelectedValuePath="@Name" SelectedValue="{Binding Prop[Template].Value}" IsEnabled="{Binding CreateMode}" Grid.Row="4" Grid.Column="1"/>

As you can see, we store the selected template in a custom property called Template, so that after the folder creation, we can identify the selected template and create the subfolders.

The PowerShell code is also fairly short. In the Menu/CreateFolder.ps1 we have a recursive function that goes into each level of the XML file and creates the according subfolders.

function recursivelyCreateFolders($childFolders, $newFolder,$folderCategories)
      if($childFolders -eq $null) { return }
      foreach ($folder in $childFolders) {
            $newSubFolder = $vault.DocumentServiceExtensions.AddFolderWithCategory($folder.Name, $newFolder.Id, $false, $folderCategories[$folder.Category])
            recursivelyCreateFolders -childFolders $folder.ChildNodes -newFolder $newSubFolder -folderCategories $folderCategories

Later in the same file, we will retrieve the selected template, load the XML file with the template definitions, also load the category definitions as we will need them later and then start the recursion of above.

$template = $dialog.ViewModel.Prop["Template"].Value
if($template -ne "")
   [xml]$xml = Get-Content "C:\ProgramData\Autodesk\Vault 2015 R2\Extensions\DataStandard\Vault\Configuration\FolderTemplates.xml"
   $folderTree = Select-Xml -Xml $xml -XPath "//Template[@Name='$template']"
   $folderCats = $vault.CategoryService.GetCategoriesByEntityClassId("FLDR",$true)
   $fc = @{}
   $folderCats | ForEach-Object { $fc[$_.Name]=$_.Id}
   recursivelyCreateFolders -childFolders $folderTree.Node.ChildNodes -newFolder $newFolder -folderCategories $fc

That’s it. In summary, we have an XML that contains the folder template definitions, a combobox for selecting the template and some lines of PowerShell code in order to create subfolders based on the XML definitions. Now the user can create a new folder and pick a template. The new created folder will have the subfolders as defined in the XML file.

Here you can download the ZIP file with the complete code.

Have fun!

Posted in Data Standard | 1 Comment

Numbering with Data Standard


When using Vault Numbering Schemes without Data Standard you will notice some shortcomings. Just to name some examples: The user always sees all active numbering schemes when creating new file in Inventor or AutoCAD. It cannot be enforced that a numbering scheme is used when creating new files (the user can skip the dialog). Numbering schemes don’t have fields that can be controlled by properties.

With Data Standard 2015 R2 support for Vault Numbering Schemes has been introduced. Together with the adaptability of Data Standard this can be used to solve the challenges mentioned above.

A numbering scheme requires actually a dynamic number of different controls such as labels, text- and combo boxes depending on the definition. The good news is that you don’t have to define each of these controls in your XAML file. Instead you just need to add one line to get a numbering scheme control:

<WPF:DSNumSchemeCtrl Grid.Column="1" Grid.Row="8" Scheme="{Binding ElementName=NumSchms, Path=SelectedItem}" GeneratedNumberProperty="_GeneratedNumber"/>

The control has built-in validation. For example when you’ve defined a free text field in your numbering scheme that requires exactly three characters, it would look like this:


Please note that for Inventor and AutoCAD the native Vault numbering scheme dialog doesn’t come up anymore as long as Data Standard is enabled.

Let’s do some modifications to the standard behavior!
The control has two mandatory attributes, so called dependency properties. It’s basically an input and an output “parameter” for the control.

“Scheme” (input)
Here the name of the numbering scheme definition has to be specified.
In the sample delivered with Data Standard this is bound to the selected element of a combo box, which gets its values from the PowerShell function “GetNumSchms”. With this the list of numbering schemes can be easily filtered by modifying the “GetNumSchms” function.

The following sample shows different numbering schemes based on the selected category when using the function “New Standard File …” in Vault.

First of all we need to change the function “GetNumSchms”:

function GetNumSchms
    $ret = @()
    $global:numSchems = $vault.DocumentService.GetNumberingSchemesByType([Autodesk.Connectivity.WebServices.NumSchmType]::Activated)
    foreach ($item in $numSchems)
        switch ($Prop["_Category"].Value)
                if ($item.Name.StartsWith("ENG")) {$ret += $item.Name}
                if ($item.Name.StartsWith("OFF")) {$ret += $item.Name}
                if ($item.Name.StartsWith("STD")) {$ret += $item.Name}
            default {$ret += $item.Name}
    return $ret

To run the sample you need to define numbering schemes starting with “ENG”, “OFF” and “STD”. When the dialog is shown the function “GetNumSchms” gets called. Based on the selected category (bound to property “_Category”) it adds only specific numbering schemes to the list that gets returned by this function.

The sample is not quite working yet. The combo box that shows the available numbering schemes has to be updated when another category is selected. To do this we need an event handler that gets called when the property “_Category” changes.

function InitializeWindow
                    param($object, $arg)
                    Category_OnPropertyChanged $arg

function Category_OnPropertyChanged
    $argname = $arg.PropertyName
    if($arg.PropertyName -eq "Value")
        $numSchmCtrl = $dsWindow.FindName("NumSchms")
        $numSchmCtrl.SelectedIndex = 0

“GeneratedNumberProperty” (output)
Here you have to tell the control to which property the generated number has to be saved, once the user clicks the OK button.
You still have the chance to modify the generated number before the file gets created.

For Inventor or AutoCAD the “GeneratedNumberProperty” is set to “DocNumber”. The following sample Inventor.cfg shows how to add the value of the title property to the generated number (don’t know if that makes sense but you get the point):

<?xml version="1.0" encoding="utf-8"?>
        <PropertyDefinition PropertyName="DocNumber" DataType="Text" InitialValue="{PathAndFileNameHandler.FileName}" />

To do more sophisticated things you can override the PowerShell function “OnPostCloseDialog” for Inventor and AutoCAD or the “GetNewFileName” function for Vault. These functions can be found in the “default.ps1″ file.

I hope this information was helpful to get started with numbering schemes in Data Standard.



Posted in Data Standard | Leave a comment

The DataGrid


We’ve recently received several questions around the DataGrid control, and I thought why not just talk about one control with more depth. The DataGrid is a very nice and simple control which allows to display data as a grid ;-). That means you have several rows and several columns. Now, the nice thing of this control is that with very little settings you can get already a nice looking result. Let’s have a first try. Just place the following XAML code at a meaningful position in your XAML file.

<DataGrid Name="myDataGrid"/>

Ok, our DataGrid now has a name (myDataGrid), so that we can address it via PowerShell. Now, as this control displays a list of values, it has a property called ItemsSource. We can either set the ItemsSource via PowerShell, for instance within the InitializeWindow, like this:

$dsWindow.FindName("myDataGrid").ItemsSource = @("test1","test2","test3")

or via the XAML, like this

<DataGrid Name="myDataGrid" ItemsSource="{Binding PsList[GetDataForTheGrid]}"/>

with the according PowerShell function called GetDataForTheGrid which provides data, like this

function GetDataForTheGrid
   return @("test1","test2","test3")

The difference between the first and second approach is that via PowerShell (first approach) we can set and change the ItemsSource whenever we like from within PowerShell. In case of the second way (binding via XAML) the user interface will take care to get the values as needed. This happens once, right at the beginning, when the dialog is generated. And unless there is no need to refresh the UI, the data will no longer be pulled. So, if you have all your information available at the beginning, then the second approach, loading via binding to a function, might be best. But if you have the data available just later in the process, then setting the ItemsSource via PowerShell, is what you are looking for. Of course you can mix those two techniques.

Anyway, let’s have a look at the result of this few lines:


Ok, we see three lines, which makes sense, as in our array we passed three values. Btw, if you didn’t know it already, now you know that with @(“”,””,””,””,….) you can create an array, either of strings “” or number or whatever. But why do we have a column called Length and all the values are set to 5??? Well, as the DataGrid displays information as a grid with columns, the control tries to interpret the information passed and map them into columns. We passed three strings, and each string has a property called Length, and the length of each text is 5 (“test1″ = 5 characters). So the DataGrid thought to do us a favour and instead of showing the data, it interprets the properties of the passed objects and show them as columns.

Well, now that we know this, we can just pass objects instead of strings (actually a string is an object, but not the kind we want). This means we have to create a little object with properties. Here, unfortunately, we have to write a bit C# code, as, as far as I know, there is no easy way to create an object with properties.

So, in case you use setting the ItemsSource via PowerShell code, for instance within the InitializeWindow, then your code might look like this. Place this code right at the beginning of your PowerShell script, outside of any function.

Add-Type @"
public class myRow
  public string Text {get;set;}

The reason is that this code should be executed just once in order to define the class, and cannot be executed every time the Data Standard dialog gets opened.

Within the InitializeWindow you can then place this code

$test1 = New-Object myRow -Property @{Text = "test1"}
$test2 = New-Object myRow -Property @{Text = "test2"}
$test3 = New-Object myRow -Property @{Text = "test3"}
$dsWindow.FindName("myDataGrid").ItemsSource = @($test1, $test2, $test3)

As you can see, we now generated 3 variables of type myRow and set the one property Text to the according value. The result now looks like this


Better!! Now, that we have one  property, why not add additional properties to our class and populate them. I’m adding an additional property of type bool (true, false).

Add-Type @"
public class myRow
   public string Text {get;set;}
   public bool Check {get;set;}

You will notice that when you change the class properties, you will have to restart either Inventor, AutoCAD or Vault in order to get these changes reflected. And this is the new PowerShell code:

$test1 = New-Object myRow -Property @{Text = "test1"; Check = $false }
$test2 = New-Object myRow -Property @{Text = "test2"; Check = $true}
$test3 = New-Object myRow -Property @{Text = "test3"; Check = $false}
$dsWindow.FindName("myDataGrid").ItemsSource = @($test1, $test2, $test3)

And this is how it looks


As you can see, the columns are added automatically, and the column header (title) is the same as the property name. So if you have more properties, then more columns will show up with according title and values, for free.

However, in case you want to have more control on the behavior of the DataGrid and columns, then there are more XAML attributes that can help. For instance, you will notice that by now you can also edit the text, which is cool as you can read the changed values (ItemsSource) anytime and do something with them. However, if you just want to show something, then you will set the DataGrid to IsReadOnly=True:

<DataGrid Name="myDataGrid" <strong>IsReadOnly="True"</strong>/>"

In the next step, let’s also make the columns a bit nicer and introduce sorting. We do have a Check property which is a bool (true,false), so let’s show a checkbox instead of displaying the text. In order to do that, we have to disable the AutoGenerateColumns and then define the columns by ourselves like this

<DataGrid Name="myDataGrid" IsReadOnly="True" <strong>AutoGenerateColumns="False"</strong>>
<strong>    <DataGridTextColumn Binding="{Binding Text}" Header="Text"/></strong>
<strong>    <DataGridCheckBoxColumn Binding="{Binding Check}" Header="Check"/></strong>
<strong>  </DataGrid.Columns></strong>

The result is that we have now columns that looks nicer and we can sort them, like this


As you can see, there are different types of DataGridxxxColumn types. Here we used the Text and CheckBox, but you can search the web for more types. Now, there is more to tell about the DataGrid, as for instance you can also display images in the list, such as the file thumbnails from Vault, and even more. Of course, the more you like to get, the more effort you have to put into it.

So far you (hopefully) have now a better understanding of the power of DataGrid and some simple approaches to get started! Now it’s up to your imagination.

Posted in Data Standard, PowerShell | Leave a comment

BreadCrumb control made simple


“Hard by a great forest dwelt a poor wood-cutter with his wife and his two children… Gretel took the bread under her apron, as Hansel had the pebbles in his pocket… Hansel, however, little by little, threw all the crumbs on the path…”

OK, ok, this was another story, however, the breadcrumb control is a great invention. It’s basically a horizontal way to navigate structures, like a folder structure, and generate a path through that structure. This is perfect for navigating through the Vault folder tree and select the path where to save our files with Data Standard.


Now unfortunately, there is no Microsoft default control we could just use in our Data Standard dialogs. Fortunately, there are several vendors that offer great looking breadcrumb controls such as Telerik, Actipro, and others. Unfortunately, if you like to purchase one of these, read well the user license agreement, as Vault and Data Standard are “development platforms” themselves, so finally the Vault customer would have to purchase the license.

I took another approach. I thought why not having a list of cascading comboboxes. The list should be flexible and somewhat intelligent, in the sense that when I choose to change the path, the superfluous combos should be removed and replaced with the new selected path.

I know, this is not a 100% breadcrumb control and all of you skilled developers will laugh at me, but this is a cheap, simple, functional solution, so give me a break!

I took advantage of the StackPanel, which is a simple control that just stacks child controls either horizontal or vertical. In my case, I want the comboboxes stacked horizontally. The next step is to create and add dynamic comboboxes as child controls to the StackPanel, and fill them with the according list of Vault folders. As the user selects one folder from the first combo, a second combo will be added with the according child folders. As the user selects a folder from the second combo, a third will be added, and so on, until no more child folders exists. In case the user changes one of the previous folders, the child combos will be removed and the game starts over. Here is the code in the XAML.

<StackPanel Grid.Column="1" Grid.Row="4" Name="BreadCrumb" Orientation="Horizontal"/>
<!--ComboBox Grid.Column="1" Grid.Row="4" SelectedValue="{Binding Prop[Folder].Value}" SelectedIndex="0" Style="{StaticResource FolderStyle}" /-->

As you can see I just commented the combo box for the folder selection in the standard dialog and instead I’ve added the StackPanel mentioned above. As you can see the StackPanel is empty by default, but has a name. The rest is done in PowerShell.

In the InitializeWindow (Default.PS1), we take the starting folder and add them to the function AddCombo. The rest is done in a separate PS1 called breadcrumb.ps1.

$mappedRootPath = $Prop["_VaultVirtualPath"].Value + $Prop["_WorkspacePath"].Value
$mappedRootPath = $mappedRootPath -replace "\\", "/" -replace "//", "/"
$rootFolder = $vault.DocumentService.GetFolderByPath($mappedRootPath)
$root = New-Object PSObject <em>-Property</em> @{ Name = $rootFolder.Name; ID=$rootFolder.Id }
AddCombo -data $root

The function AddCombo gets the child Folders for the selected folder, adds a first combobox to our StackPanel, fills the combobox with the child folders and registers the SelectionChanged event. You will notice that the child folders are not just a list of text, but are little objects. The reason is that we want to store both, the name of the folder and the ID, so when we have to look for the children, we have the ID of the parent already at our hand.

function AddCombo($data)
 $children = GetChildFolders -folder $data
 if($children -eq $null) { return }
 $breadCrumb = $dsWindow.FindName("BreadCrumb")
 $cmb = New-Object System.Windows.Controls.ComboBox
 $cmb.Name = "cmbBreadCrumb_" + $breadCrumb.Children.Count.ToString()
 $cmb.DisplayMemberPath = "Name"
 $cmb.ItemsSource = @($children)
 OnSelectionChanged -sender $sender

The OnSelectionChanged is fired every time the user selects another value from the combo. In such case, we just take the selected folder and call the AddCombo with such folder. Before we do so, we remove all child combos, if they exist. That way, in case the user decided to go another path, the superfluous child combos get removed and the game can start over again.

function OnSelectionChanged($sender)
  $breadCrumb = $dsWindow.FindName("BreadCrumb")
  $position = [int]::Parse($sender.Name.Split('_')[1]);
  $children = $breadCrumb.Children.Count - 1
  while($children -gt $position )
  $path = GetFullPathFromBreadCrumb -breadCrumb $breadCrumb
  $Prop["Folder"].Value = $path
  AddCombo -data $sender.SelectedItem

That’s it! there are two more little functions such as the GetFullPathFromBreadCrumb and GetChildFolders which contain few lines of code, but the real important functions are the two above. As you can see in the OnSelectionChanged the property Folder gets set whenever the user selects a new path.

If you like to try this code, you can download the complete sample from here


Posted in Data Standard, PowerShell, Vault API | 2 Comments

And the winner is…


Wow. We got a lot of valuable feedback. Thank you for that! We will keep the survey open in case some more people like to provide input. However, the trend is already clear. You definitely want technical stuff that can be packaged into your projects. The topics preference is somewhat distributed between Data Standard (1st), Vault API (2nd), powerJobs, powerGate, Vault migrations and other topics. The preferred day for reading posts is Monday (43%) and Friday (31%), and the frequency of one post per week (70%) is good.

So we will keep going with posts on Friday, which works well for both the Friday and Monday readers, and we will continue posting on Data Standard and other Vault related topics as well as our products. Based on your feedback, we will see to provide more tips on how the Vault behavior can be improved or extended and how technologies work better together. If you like to suggest other topics of interest, feel free to either fill out the survey, or send us an email to We will see to take your suggestion into account and post about it.

Thank you very much for the feedback so far and for the kind words! All bloggers knows the effort for driving a blog and such comments are fuel for our engines!

Posted in Uncategorized | Leave a comment

Let’s talk about…


Happy new year!!! We are back and like to share with you some more interesting topics. In order to provide the right content for you, we would like to better understand which topics you are interested in. Are you more technical or commercial oriented, a reseller or customer, do you like to know more about API, Data Standard, custom jobs, ERP integration, …

We prepared a short survey that I kindly ask you to fill out. It takes less then 5 minutes. All the information is anonymous. Based on the results we will create content that will help you in your business. Please take the time and follow this link

Looking forward to your feedback!

Posted in Uncategorized | Leave a comment