├── README.md ├── changelog ├── devices.ps1 ├── example_full.bat ├── example_full_rackperfile.bat ├── example_longracknames.bat ├── example_showlabels.bat ├── input └── example.csv ├── output └── example_full.vsd └── rack.jpg /README.md: -------------------------------------------------------------------------------- 1 | DEVICES 2 | ======= 3 | 4 | Diagram Export in Visio from CSV (and in the future Excel and other Sources) 5 | 6 | License 7 | ------- 8 | 9 | This software is licensed as CC-BA (Creative Commons By Attrbution) 10 | 11 | http://creativecommons.org/licenses/by/4.0/legalcode 12 | 13 | Introduction 14 | ------------ 15 | 16 | A Powershell script for creating Visio Diagrams of DC racks and the hardware in them. 17 | 18 | The import can be in the form of CSV or Excel (still under development). 19 | 20 | This could also be used to automate Visio digram creations using exports from CMDBs (e.g. ServiceNow, Remedy, etc). 21 | 22 | At the moment the script is a proof of concept. It has support for a number of vendor stencils and provides a framework to expand on. 23 | 24 | Things to do: 25 | 26 | - Excel import support 27 | 28 | Background 29 | ---------- 30 | 31 | Originally I used the inbuilt OS applictation automation of Visio, then I tried VisioPS/Visio module. 32 | The inbuilt OS support would not let me set the active sheet so that I could do a rack per sheet in Visio. 33 | The VisioPS/Visio powershell module would let me set the active page correctly, but the current version 34 | does not appear to have the Stencil cmdlets or they have been moved in another Cmdlet and are not documented. 35 | 36 | Thus I started using VisioBot3000 which allows me to set the active page and use Stencils: 37 | 38 | https://github.com/MikeShepard/VisioBot3000 39 | 40 | I have rewritten the script to utilise this powershell module. 41 | 42 | Output 43 | ------ 44 | 45 | Example output (JPG of Visio Document) with visible stencil labels (-showlabels) and long rack names (-longrackname): 46 | 47 | ![alt tag](https://raw.githubusercontent.com/lateralblast/devices/master/rack.jpg) 48 | 49 | Requirements 50 | ------------ 51 | 52 | The following software is required: 53 | 54 | - Windows OS 55 | - Powershell 56 | - Visio 57 | - Visio Stencils for vendor products 58 | - VisioBot3000 Powershell Module 59 | 60 | Installing Powershell Module: 61 | 62 | ``` 63 | Y:\Code\devices>powershell "Install-Module VisioBot3000" 64 | ``` 65 | 66 | If you've got an existing Visio Powershell Module installed, you may need to uninstall it or use the -Clobber flag to overwrite conflicting Cmdlets 67 | 68 | If you want to clone the script and/or stencils: 69 | 70 | - Git for Windows 71 | 72 | Documentation 73 | ------------- 74 | 75 | You can copy the script manually from the git repository or clone it: 76 | 77 | ``` 78 | $ git clone https://github.com/lateralblast/devices.git . 79 | ``` 80 | 81 | Stencils are put in the 'stencils' subdirectory under a 'vendor' subdirectory. 82 | 83 | To help, I'm building a collection of Visio stencils here: 84 | 85 | https://github.com/lateralblast/vss 86 | 87 | This repository is getting rather large so I'd recommend you just copy the ones you need. 88 | 89 | If you wanted to clone the entire collection: 90 | 91 | ``` 92 | $ cd devices 93 | $ git clone https://github.com/lateralblast/vss.git stencils 94 | ``` 95 | 96 | Currently there is some support for the following vendor stencils: 97 | 98 | - Oracle 99 | - Dell 100 | - Pure 101 | 102 | Support for other vendors is relatively straight forward to add, 103 | you need to inspect the Visio file and look at the naming standard 104 | for front and rear views. Common naming is "Model Front" and "Model Rear". 105 | 106 | I plan to add some code to list the stencil names and do a match to make this process easier. 107 | 108 | Usage 109 | ----- 110 | 111 | To run the script from the command line you may need to alter the execution policy, 112 | by setting it globally or adding the following command line option: 113 | 114 | ``` 115 | -ExecutionPolicy ByPass 116 | ``` 117 | 118 | Getting help: 119 | 120 | ``` 121 | Y:\Code\devices>powershell -ExecutionPolicy ByPass -File devices.ps1 -help 122 | usage: devices.ps1 123 | --help 124 | --version 125 | --inputfile FILENAME 126 | --outputfile FILENAME 127 | --longracknames 128 | --showlabels 129 | --rackperfile 130 | --pagelabels 131 | ``` 132 | 133 | Example of a CSV file: 134 | 135 | ``` 136 | $ more example.csv 137 | Hostname,Component,Vendor,Architecture,Model,Operating System,Rack,Rack Units,Top Rack Unit,Serial Number,Asset Number,Installed Date,Warranty Exp,Location,Country 138 | server1,Chassis,Oracle,SPARC,M3000,,A1,2,2,12341,,,,, 139 | server2,Chassis,Oracle,SPARC,M5000,,A1,10,12,12342,,,,, 140 | server3,Chassis,Oracle,x86,X2-4,,A1,3,15,12343,,,,, 141 | array1,SH3,Pure,,Disk shelf,,A1,2,17,12344,,,,, 142 | array1,SH2,Pure,,Disk shelf,,A1,2,19,12345,,,,, 143 | array1,SH1,Pure,,Disk shelf,,A1,2,21,12346,,,,, 144 | array1,SH0,Pure,,Disk shelf,,A1,2,23,12347,,,,, 145 | array1,CH0,Pure,,FA-m70r2,,A1,3,26,12348,,,,, 146 | server5,Chassis,Dell,x86,R820,,A1,2,28,12349,,,,, 147 | flashblade1,CH1,Pure,,FlashBlade,,A1,4,32,123450 148 | server11,Chassis,Oracle,SPARC,M3000,,A2,2,2,12351,,,,, 149 | server12,Chassis,Oracle,SPARC,M5000,,A2,10,12,12352,,,,, 150 | server13,Chassis,Oracle,x86,X2-4,,A2,3,15,12353,,,,, 151 | array2,SH3,Pure,,Disk shelf,,A2,2,17,12354,,,,, 152 | array2,SH2,Pure,,Disk shelf,,A2,2,19,12355,,,,, 153 | array2,SH1,Pure,,Disk shelf,,A2,2,21,12356,,,,, 154 | array2,SH0,Pure,,Disk shelf,,A2,2,23,12357,,,,, 155 | array2,CH0,Pure,,FA-m70r2,,A2,3,26,12358,,,,, 156 | flashblade2,CH1,Pure,,FlashBlade,,A2,4,30,123459,,,,, 157 | ``` 158 | 159 | Importing CSV file and creating Visio diagrams: 160 | 161 | ``` 162 | Y:\Code\devices>powershell -ExecutionPolicy ByPass -File devices.ps1 -inputfile input\example.csv -outputfile output\example.vsd 163 | ``` 164 | -------------------------------------------------------------------------------- /changelog: -------------------------------------------------------------------------------- 1 | # 0.0.1: 2 | # Initial version 3 | # 0.0.2: 4 | # Added code to import stencils 5 | # 0.0.2: 6 | # Added code to select server stencils 7 | # 0.0.3: 8 | # Added code to test type of files 9 | # 0.0.4: 10 | # Added code to load CSV file 11 | # 0.0.5: 12 | # Added code to determine location on page 13 | # 0.0.6: Thu 27 Oct 2016 11:24:09 AEDT 14 | # Numerous fixes 15 | # 0.0.7: Thu 27 Oct 2016 13:27:09 AEDT 16 | # Added code to put in blanking plates if name can't be resolved 17 | # 0.0.8: Thu 27 Oct 2016 13:46:52 AEDT 18 | # Fixed blanking plate placement 19 | # 0.0.9: Thu 27 Oct 2016 17:59:02 AEDT 20 | # Added code to create an output file for each rack within a list 21 | # 0.1.0: Thu 27 Oct 2016 23:10:26 AEDT 22 | # Added support for Dell rackmount servers 23 | # 0.1.1: Sat 29 Oct 2016 12:33:21 AEDT 24 | # Added support for Dell storage 25 | # 0.1.2: Sat 29 Oct 2016 13:33:21 AEDT 26 | # Added support for IBM servers 27 | # 0.1.3: Sat 29 Oct 2016 20:34:03 AEDT 28 | # Added support for NetApp storage 29 | # 0.1.4: Sun 30 Oct 2016 12:11:01 AEDT 30 | # Added code to unzip stencils file 31 | # 0.1.5: Sun 30 Oct 2016 12:46:36 AEDT 32 | # Fixed bugs 33 | # 0.1.6: Sun 30 Oct 2016 22:24:15 AEDT 34 | # Fixed bug with processing racks with one item 35 | # 0.1.7: Mon 31 Oct 2016 10:46:43 AEDT 36 | # More bug fixes 37 | # 0.1.8: Mon 5 Feb 2018 14:28:44 AEDT 38 | # Rewrite to use VisioBot3000 powershell module 39 | # 0.1.9: Mon 5 Feb 2018 19:57:29 AEDT 40 | # Improved outputfile handling 41 | # 0.2.0: Wed 7 Feb 2018 10:36:02 AEDT 42 | # Updated code to support modifying shape data 43 | # 0.2.1: Thu 8 Feb 2018 09:12:35 AEDT 44 | # Updated example and added Pure FlashBlade support 45 | # 0.2.2: Thu 8 Feb 2018 09:26:42 AEDT 46 | # Example and Shape data updates 47 | # 0.2.3: Fri 9 Feb 2018 08:12:32 AEDT 48 | # Fixed shape labels and added additional shape data 49 | # 0.2.4: Fri 9 Feb 2018 10:59:50 AEDT 50 | # Added -longrackname switch option to include hostnames in page name and rack name 51 | # 0.2.5: Fri 9 Feb 2018 17:02:45 AEDT 52 | # Fixed calls to code to unzip stencils 53 | # 0.2.6: Sat 10 Feb 2018 15:01:18 AEDT 54 | # Added code to show labels on stencils 55 | # 0.2.7: Sat 10 Feb 2018 15:14:36 AEDT 56 | # Added code to ensure server stencils are on top of rack stencils 57 | # 0.2.8: Sat 10 Feb 2018 23:41:18 AEDT 58 | # Added additional examples and code to output a file per rack 59 | # 0.2.9: Sun 11 Feb 2018 15:13:56 AEDT 60 | # Added -pagelables switch to put rack label on top of page 61 | # 0.3.0: Sun 11 Feb 2018 17:16:24 AEDT 62 | # Improved page label handling 63 | -------------------------------------------------------------------------------- /devices.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [switch] $help, 3 | [switch] $version, 4 | [switch] $verbose, 5 | [switch] $longracknames, 6 | [switch] $showlabels, 7 | [switch] $pagelabels, 8 | [switch] $rackperfile, 9 | [string] $inputfile, 10 | [string] $outputfile 11 | ) 12 | 13 | # Name: Devices 14 | # Version: 0.3.0 15 | # Release: 1 16 | # License: CC-BA (Creative Commons By Attribution) 17 | # http://creativecommons.org/licenses/by/4.0/legalcode 18 | # Group: System 19 | # Source: N/A 20 | # URL: http://lateralblast.com.au/ 21 | # Distribution: UNIX 22 | # Vendor: Lateral Blast 23 | # Packager: Richard Spindler 24 | # Description: Powershell script to output a Visio diagram from an Excel file 25 | 26 | # Import module 27 | 28 | Import-Module VisioBot3000 -Force 29 | 30 | # Script glabal vars 31 | 32 | $script_name = $MyInvocation.MyCommand.Name 33 | $script_path = $MyInvocation.MyCommand.Path 34 | $script_file = $MyInvocation.MyCommand 35 | $script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent 36 | $script_vers = "" 37 | $data_dir = "$script_dir\data" 38 | $stencil_dir = "$script_dir\stencils" 39 | $output_dir = "$script_dir\output" 40 | 41 | $script_text = Get-Content $script_file 42 | 43 | function unzip_stencil($stencil_file) { 44 | $zip_file = "$stencil_file.zip" 45 | $shell_obj = new-object -com shell.application 46 | $zip_obj = $shell_obj.NameSpace($zip_file) 47 | $destination = Split-Path $stencil_file 48 | if (!(Test-Path $stencil_file)) { 49 | foreach($item in $zip_obj.items()) { 50 | Write-Host "Extracting '$item' from '$zip_file' to '$destination'" 51 | $shell_obj.Namespace($destination).copyhere($item) 52 | } 53 | } 54 | return 55 | } 56 | 57 | function get_file_type($input_file) { 58 | Add-Type -AssemblyName "System.Web" 59 | $mime_type = [System.Web.MimeMapping]::GetMimeMapping($script_file) 60 | return($mime_type) 61 | } 62 | 63 | function print_help($script_name) { 64 | Write-Host "usage: $script_name" 65 | Write-Host "--help" 66 | Write-Host "--version" 67 | Write-Host "--inputfile FILENAME" 68 | Write-Host "--outputfile FILENAME" 69 | Write-Host "--longracknames" 70 | Write-Host "--showlabels" 71 | Write-Host "--rackperfile" 72 | Write-Host "--pagelabels" 73 | return 74 | } 75 | 76 | function print_version($script_vers) { 77 | Write-Host "$script_vers" 78 | } 79 | 80 | function get_script_vers($script_text) { 81 | foreach ($script_line in $script_text) { 82 | if ($script_line -match "# Version") { 83 | $line_items = $script_line -split "\s+" 84 | $script_vers = $line_items[2] 85 | return $script_vers 86 | } 87 | } 88 | } 89 | 90 | $script_vers = get_script_vers($script_text) 91 | 92 | # Print help 93 | 94 | if ($help) { 95 | print_help($script_name) 96 | exit 97 | } 98 | 99 | # Print version 100 | 101 | if ($version) { 102 | print_version($script_vers) 103 | exit 104 | } 105 | 106 | # Handle input switch 107 | 108 | if ($inputfile) { 109 | $input_file = $inputfile 110 | if (!(Test-Path $input_file)) { 111 | Write-Host "File: '$input_file' does not exist" 112 | exit 113 | } 114 | } 115 | else { 116 | Write-Host "Input file not specified" 117 | print_help($script_name) 118 | exit 119 | } 120 | 121 | if ($verbose) { 122 | Write-Host "Input: $input_file" 123 | } 124 | 125 | # Handle output switch 126 | 127 | if ($outputfile) { 128 | $output_file = $outputfile 129 | if (!($output_file -match ":")) { 130 | $output_file = "$script_dir\$output_file" 131 | } 132 | } 133 | else { 134 | if (!($rackperfile)) { 135 | Write-Host "Output file not specified" 136 | print_help($script_name) 137 | exit 138 | } 139 | } 140 | 141 | # Get file type 142 | 143 | $file_type = get_file_type($input_file) 144 | 145 | # Handle opening file 146 | 147 | if ($input_file -match "xls$|xlsx$" -And $file_type -match "octet") { 148 | $excel = New-Object -ComObject Excel.Application 149 | $book = $excel.Workbooks.Open($input_file) 150 | $sheet = $book.Worksheets.Item(1) 151 | $max_row = ($sheet.UsedRange.Rows).count 152 | $max_col = ($sheet.UsedRange.Columns).count 153 | } 154 | else { 155 | if ($input_file -match "csv$") { 156 | $csv_rows = Import-Csv $input_file 157 | } 158 | } 159 | 160 | $csv_racks = $csv_rows.Rack | Select-Object -Unique 161 | 162 | # Set up some global stencil files 163 | 164 | $basic_shapes_stencils_file = "BASIC_U.VSSX" 165 | $oracle_sparc_server_stencils_file = "$stencil_dir\oracle\Oracle-Server-SPARC.vss" 166 | $oracle_intel_server_stencils_file = "$stencil_dir\oracle\Oracle-Server-x86.vss" 167 | $oracle_blade_server_stencils_file = "$stencil_dir\oracle\Oracle-Server-Blade.vss" 168 | $dell_rack_stencils_file = "$stencil_dir\dell\Dell-Racks.vss" 169 | $dell_blade_server_stencils_file = "$stencil_dir\dell\Dell-PowerEdge-BladeServers.vss" 170 | $dell_rack_server_stencils_file = "$stencil_dir\dell\Dell-PowerEdge-RackServers.vss" 171 | $dell_sc_storage_stencils_file = "$stencil_dir\dell\Dell-Storage-Compellent-SC.vss" 172 | $dell_ps_storage_stencils_file = "$stencil_dir\dell\Dell-Storage-EqualLogic-PS.vss" 173 | $dell_md_storage_stencils_file = "$stencil_dir\dell\Dell-Storage-PowerVault-Dx-MD-NX.vss" 174 | $dell_emc_storage_stencils_file = "$stencil_dir\dell\Dell-EMC.vss" 175 | $ibm_power_stencils_file = "$stencil_dir\ibm\IBM-Server-Power.vss" 176 | $ibm_systemi_stencils_file = "$stencil_dir\ibm\IBM-Server-Systemi.vss" 177 | $ibm_systemp_stencils_file = "$stencil_dir\ibm\IBM-Server-Systemp.vss" 178 | $ibm_systemx_stencils_file = "$stencil_dir\ibm\IBM-Server-Systemx.vss" 179 | $ibm_systemz_stencils_file = "$stencil_dir\ibm\IBM-Server-Systemz.vss" 180 | $pure_storage_array_stencils_file = "$stencil_dir\pure\Purestorage.vss" 181 | $netapp_nearstore_stencils_file = "$stencil_dir\netapp\NetApp-NearStore-classic.vss" 182 | $netapp_fas_stencils_file = "$stencil_dir\netapp\NetApp-FAS-Series.vss" 183 | $netapp_old_fas_stencils_file = "$stencil_dir\netapp\NetApp-FAS-Series-classic.vss" 184 | $netapp_e_series_stencils_file = "$stencil_dir\netapp\NetApp-E-Series.vss" 185 | $netapp_s_series_stencils_file = "$stencil_dir\netapp\NetApp-S-Family-classic.vss" 186 | $netapp_v_series_stencils_file = "$stencil_dir\netapp\NetApp-V-Series.vss" 187 | $netapp_old_v_series_stencils_file = "$stencil_dir\netapp\NetApp-V-Series-classic.vss" 188 | $netapp_vtl_stencils_file = "$stencil_dir\netapp\NetApp-VTL-Series-classic.vss" 189 | 190 | # Default Rack 191 | 192 | $default_rack = "4220 Rack Frame" 193 | 194 | # Text defaults 195 | 196 | $default_text_size = "6pt" 197 | $default_text_colour = "RGB(255, 165, 0)" 198 | $default_back_colour = "RGB(255, 255, 255)" 199 | $default_text_y_pos = "Height * 0.5" 200 | $default_text_x_pos = "Width * 0.5" 201 | 202 | # Page label defaults 203 | 204 | $default_page_label_x_pos = 4.25 205 | $default_page_label_y_pos = 11.0 206 | $default_page_label_height = 0.5 207 | $default_page_label_width = 7.5 208 | $default_page_label_box_colour = "RGB(255, 255, 255)" 209 | $default_page_label_text_style = "1" 210 | $default_page_label_text_size = "16pt" 211 | 212 | if ($showlabels) { 213 | $default_text_hidden = "FALSE" 214 | } 215 | else { 216 | $default_text_hidden = "TRUE" 217 | } 218 | 219 | # Rack x,y constants 220 | 221 | $front_rack_x = 1.0 222 | $back_rack_x = 5.0 223 | $front_rack_y = 4.0 224 | $back_rack_y = 4.0 225 | $front_ru_x = $front_rack_x + 1.19 226 | $back_ru_x = $back_rack_x + 1.19 227 | $front_ru_y = 2.13 228 | $back_ru_y = 2.13 229 | $ru_space = 0.175 230 | $cur_rack = "None" 231 | 232 | # Process CSV 233 | 234 | if ($input_file -match "csv$") { 235 | $load_stencil = 1 236 | # Open Visio Document 237 | if (!($rackperfile)) { 238 | $visio = New-VisioApplication 239 | $new_doc = New-VisioDocument $output_file 240 | foreach ($rack in $csv_racks) { 241 | $cur_rows = $csv_rows | Where {$_.Rack -eq "$rack"} 242 | if ($longracknames) { 243 | $list = @() 244 | $items = $cur_rows | Where {$_.Component -match "CH|Chassis"} 245 | $max_items = $items.count 246 | if (!($max_items -match "[0-9]")) { 247 | $max_items = 1 248 | } 249 | for ($num = 0; $num -lt $max_items; $num++) { 250 | $item = $items[$num].hostname 251 | $list += $item 252 | } 253 | $hosts = $list -join "," 254 | $rack_name = "$rack ($hosts)" 255 | } 256 | else { 257 | $rack_name = "$rack" 258 | } 259 | $new_page = New-VisioPage -Name $rack_name 260 | } 261 | } 262 | foreach ($rack in $csv_racks) { 263 | # Reset grid references 264 | $cur_front_ru_x = $front_ru_x 265 | $cur_back_ru_x = $back_ru_x 266 | $cur_front_ru_y = $front_ru_y 267 | $cur_back_ru_y = $back_ru_y 268 | # Process rows in CSV for current rack 269 | $cur_rows = $csv_rows | Where {$_.Rack -eq "$rack"} 270 | $max_rows = $cur_rows.count 271 | if (!($max_rows -match "[0-9]")) { 272 | $max_rows = 1 273 | } 274 | if ($longracknames) { 275 | $list = @() 276 | $items = $cur_rows | Where {$_.Component -match "CH|Chassis"} 277 | $max_items = $items.count 278 | if (!($max_items -match "[0-9]")) { 279 | $max_items = 1 280 | } 281 | for ($num = 0; $num -lt $max_items; $num++) { 282 | $item = $items[$num].hostname 283 | $list += $item 284 | } 285 | $hosts = $list -join "," 286 | $rack_name = "$rack ($hosts)" 287 | } 288 | else { 289 | $rack_name = "$rack" 290 | } 291 | # Select Rack Page 292 | if ($rackperfile) { 293 | $visio = New-VisioApplication 294 | $output_file = "$output_dir\$rack_name.vsd" 295 | $new_doc = New-VisioDocument $output_file 296 | $new_page = New-VisioPage -Name $rack_name 297 | } 298 | $page = Set-VisioPage $rack_name 299 | if ($pagelabels) { 300 | 301 | } 302 | if ($load_stencil -eq 1) { 303 | if ($pagelabels) { 304 | $basic_shapes_stencils = Register-VisioStencil -Name basic_shapes_stencils $basic_shapes_stencils_file 305 | } 306 | # Setup Rack Stencils 307 | # Dell has a good default rack stencil 308 | unzip_stencil($dell_rack_stencils_file) 309 | $dell_rack_stencils = Register-VisioStencil -Name dell_rack_stencils -Path $dell_rack_stencils_file 310 | $rack_stencil = Register-VisioShape -Name rack_stencil -From dell_rack_stencils -MasterName "$default_rack" 311 | # Check for vendors 312 | $pure_rows = $cur_rows | Where {$_.Vendor -match "Pure"} 313 | if ($pure_rows) { 314 | unzip_stencil($pure_storage_array_stencils_file) 315 | $pure_storage_array_stencils = Register-VisioStencil -Name pure_storage_array_stencils -Path $pure_storage_array_stencils_file 316 | } 317 | $dell_rows = $cur_rows | Where {$_.Vendor -match "Dell"} 318 | if ($dell_rows) { 319 | $model_test = $dell_rows | Where {$_.Model -match "^CX4|^NX4|^ES|^DD"} 320 | if ($model_test -match "[A-Z]") { 321 | unzip_stencil($dell_emc_storage_stencils_file) 322 | $dell_emc_storage_stencils = Register-VisioStencil -Name dell_emc_storage_stencils $dell_emc_storage_stencils_file 323 | } 324 | $model_test = $dell_rows | Where {$_.Model -match "^R|^C"} 325 | if ($model_test -match "[A-Z]") { 326 | unzip_stencil($dell_rack_server_stencils_file) 327 | $dell_rack_server_stencils = Register-VisioStencil -Name dell_rack_server_stencils $dell_rack_server_stencils_file 328 | } 329 | $model_test = $dell_rows | Where {$_.Model -match "^M[0-9]"} 330 | if ($model_test -match "[A-Z]") { 331 | unzip_stencil($dell_blade_server_stencils_file) 332 | $dell_blade_server_stencils = Register-VisioStencil -Name dell_blade_server_stencils $dell_blade_server_stencils_file 333 | } 334 | $model_test = $dell_rows | Where {$_.Model -match "^FS8|^SC"} 335 | if ($model_test -match "[A-Z]") { 336 | unzip_stencil($dell_sc_storage_stencils_file) 337 | $dell_sc_storage_stencils = Register-VisioStencil -Name dell_sc_storage_stencils $dell_sc_storage_stencils_file 338 | } 339 | $model_test = $dell_rows | Where {$_.Model -match "^FS7|^PS"} 340 | if ($model_test -match "[A-Z]") { 341 | unzip_stencil($dell_ps_storage_stencils_file) 342 | $dell_ps_storage_stencils = Register-VisioStencil -Name dell_ps_storage_stencils $dell_ps_storage_stencils_file 343 | } 344 | $model_test = $dell_rows | Where {$_.Model -match "^D|^MD|^NX"} 345 | if ($model_test -match "[A-Z]") { 346 | unzip_stencil($dell_md_storage_stencils_file) 347 | $dell_md_storage_stencils = Register-VisioStencil -Name dell_md_storage_stencils $dell_md_storage_stencils_file 348 | } 349 | } 350 | $sun_rows = $cur_rows | Where {$_.Vendor -match "Oracle|Sun"} 351 | if ($sun_rows) { 352 | $model_test = $sun_rows | Where {$_.Model -match "Blade|^B[0-9]"} 353 | if ($model_test -match "[A-Z]") { 354 | unzip_stencil($oracle_blade_server_stencils_file) 355 | $oracle_blade_server_stencils = Register-VisioStencil -Name oracle_blade_server_stencils $oracle_blade_server_stencils_file 356 | } 357 | $model_test = $sun_rows | Where {$_.Model -match "SPARC|sparc|^T[0-9]|^M[0-9]|^E[0-9]"} 358 | if ($model_test -match "[A-Z]") { 359 | unzip_stencil($oracle_sparc_server_stencils_file) 360 | $oracle_sparc_server_stencils = Register-VisioStencil -Name oracle_sparc_server_stencils $oracle_sparc_server_stencils_file 361 | } 362 | $model_test = $sun_rows | Where {$_.Model -match "X64|X86|x64|x86|i386|^X[0-9]"} 363 | if ($model_test -match "[A-Z]") { 364 | unzip_stencil($oracle_intel_server_stencils_file) 365 | $oracle_intel_server_stencils = Register-VisioStencil -Name oracle_intel_server_stencils $oracle_intel_server_stencils_file 366 | } 367 | } 368 | if (!($rackperfile)) { 369 | $load_stencil = 0 370 | } 371 | } 372 | if ($pagelabels) { 373 | # Put a label on the page so it will appear when output to PDF 374 | $rectangle = Register-VisioShape -Name rectangle -From basic_shapes_stencils -MasterName "Rectangle" 375 | $characters = $rack_name | measure-object -character | select -expandproperty characters 376 | $shape_pos = Set-NextShapePosition -x $default_page_label_x_pos -y $default_page_label_y_pos 377 | $shape = rectangle rack_label 378 | $shape_height = $shape.Cells("Height") = $default_page_label_height 379 | $shape_width = $shape.Cells("Width") = $default_page_label_width 380 | $label = $shape.Characters.Text = $rack_name 381 | $shape_colour = $shape.Cells("LineColor").FormulaU = $default_page_label_box_colour 382 | $text_style = $shape.Cells("Char.Style").FormulaU = $default_page_label_text_style 383 | $text_size = $shape.Cells("Char.Size").FormulaU = $default_page_label_text_size 384 | $text_hidden = $shape.Cells("HideText").FormulaU = $default_text_hidden 385 | } 386 | # Place rack front stencil 387 | $shape_pos = Set-NextShapePosition -x $front_rack_x -y $front_rack_y 388 | $shape = rack_stencil rack_front 389 | $label = $shape.Characters.Text = $rack_name 390 | $text_colour = $shape.Cells("Char.Color").FormulaU = $default_text_colour 391 | $text_size = $shape.Cells("Char.Size").FormulaU = $default_text_size 392 | $text_x_pos = $shape.Cells("TxtLocPinX").FormulaU = $default_text_x_pos 393 | $text_y_pos = $shape.Cells("TxtLocPinY").FormulaU = $default_text_y_pos 394 | $text_back = $shape.Cells("TextBkgnd").FormulaU = $default_back_colour 395 | $text_hidden = $shape.Cells("HideText").FormulaU = $default_text_hidden 396 | $shape_data = Set-VisioShapeData -Shape $rack_front -Name ProductNumber "" 397 | $shape_data = Set-VisioShapeData -Shape $rack_front -Name Manufacturer "" 398 | $shape_data = Set-VisioShapeData -Shape $rack_front -Name ProductNumber "" 399 | $shape_data = Set-VisioShapeData -Shape $rack_front -Name PartNumber "" 400 | $shape_data = Set-VisioShapeData -Shape $rack_front -Name ProductDescription "" 401 | # Place rack back stencil 402 | $shape_pos = Set-NextShapePosition -x $back_rack_x -y $back_rack_y 403 | $shape = rack_stencil rack_back 404 | $label = $shape.Characters.Text = $rack_name 405 | $text_colour = $shape.Cells("Char.Color").FormulaU = $default_text_colour 406 | $text_size = $shape.Cells("Char.Size").FormulaU = $default_text_size 407 | $text_x_pos = $shape.Cells("TxtLocPinX").FormulaU = $default_text_x_pos 408 | $text_y_pos = $shape.Cells("TxtLocPinY").FormulaU = $default_text_y_pos 409 | $text_back = $shape.Cells("TextBkgnd").FormulaU = $default_back_colour 410 | $text_hidden = $shape.Cells("HideText").FormulaU = $default_text_hidden 411 | $shape_data = Set-VisioShapeData -Shape $rack_back -Name ProductNumber "" 412 | $shape_data = Set-VisioShapeData -Shape $rack_back -Name Manufacturer "" 413 | $shape_data = Set-VisioShapeData -Shape $rack_back -Name ProductNumber "" 414 | $shape_data = Set-VisioShapeData -Shape $rack_back -Name PartNumber "" 415 | $shape_data = Set-VisioShapeData -Shape $rack_back -Name ProductDescription "" 416 | # Set through rows on current rack 417 | for ($row = 0; $row -lt $max_rows; $row++) { 418 | # Get Values from columns 419 | $hostname = $cur_rows[$row].Hostname 420 | $component = $cur_rows[$row].Component 421 | $vendor = $cur_rows[$row].Vendor 422 | $arch = $cur_rows[$row].Architecture 423 | $model = $cur_rows[$row].Model 424 | $os = $cur_rows[$row]."Operating System" 425 | $rack = $cur_rows[$row].Rack 426 | $rus = $cur_rows[$row]."Rack Units" 427 | $top_ru = $cur_rows[$row]."Top Rack Unit" 428 | $serial = $cur_rows[$row]."Serial Number" 429 | $asset = $cur_rows[$row]."Asset Number" 430 | $installed = $cur_rows[$row]."Installed Date" 431 | $warranty = $cur_rows[$row]."Warranty Exp" 432 | $location = $cur_rows[$row].Location 433 | $country = $cur_rows[$row].Country 434 | $info = "$hostname"+": $component" 435 | # Handle Vendor to help chose shapes 436 | switch -regex ($vendor) { 437 | # Handle Dell Servers, Blades and Storage 438 | "Dell" { 439 | $front_name = "$model Front" 440 | $back_name = "$model Rear" 441 | switch -regex ($model) { 442 | "^CX4|^NX4|^ES|^DD" { 443 | $dell_emc_storage_stencil_front = Register-VisioShape -Name stencil_front -From dell_emc_storage_stencils -MasterName "$front_name" 444 | $dell_emc_storage_stencil_back = Register-VisioShape -Name stencil_back -From dell_emc_storage_stencils -MasterName "$back_name" 445 | } 446 | "^R|^C" { 447 | $dell_rack_server_stencil_front = Register-VisioShape -Name stencil_front -From dell_rack_server_stencils -MasterName "$front_name" 448 | $dell_rack_server_stencil_back = Register-VisioShape -Name stencil_back -From dell_rack_server_stencils -MasterName "$back_name" 449 | } 450 | "^M[0-9]" { 451 | $dell_blade_server_stencil_front = Register-VisioShape -Name stencil_front -From dell_blade_server_stencils -MasterName "$front_name" 452 | $dell_blade_server_stencil_back = Register-VisioShape -Name stencil_back -From dell_blade_server_stencils -MasterName "$back_name" 453 | } 454 | "^FS8|^SC" { 455 | $dell_sc_storage_stencil_front = Register-VisioShape -Name stencil_front -From dell_sc_storage_stencils -MasterName "$front_name" 456 | $dell_sc_storage_stencil_back = Register-VisioShape -Name stencil_back -From dell_sc_storage_stencils -MasterName "$back_name" 457 | } 458 | "^FS7|^PS" { 459 | $dell_ps_storage_stencil_front = Register-VisioShape -Name stencil_front -From dell_ps_storage_stencils -MasterName "$front_name" 460 | $dell_ps_storage_stencil_back = Register-VisioShape -Name stencil_back -From dell_ps_storage_stencils -MasterName "$back_name" 461 | } 462 | "^D|^MD|^NX" { 463 | $dell_md_storage_stencil_front = Register-VisioShape -Name stencil_front -From dell_md_storage_stencils -MasterName "$front_name" 464 | $dell_md_storage_stencil_back = Register-VisioShape -Name stencil_back -From dell_md_storage_stencils -MasterName "$back_name" 465 | } 466 | } 467 | } 468 | # Handle Pure arrays 469 | "Pure" { 470 | switch -regex ($model) { 471 | "FB|FlashBlade" { 472 | $front_name = "FlashBlade Front Full" 473 | $back_name = "FlashBlade back" 474 | } 475 | "FA-|M" { 476 | $front_name = "FA M70 front" 477 | $back_name = "FA M70 back" 478 | } 479 | default { 480 | $front_name = "$model front" 481 | $back_name = "$model back" 482 | } 483 | } 484 | $pure_storage_array_stencil_front = Register-VisioShape -Name stencil_front -From pure_storage_array_stencils -MasterName "$front_name" 485 | $pure_storage_array_stencil_back = Register-VisioShape -Name stencil_back -From pure_storage_array_stencils -MasterName "$back_name" 486 | } 487 | # Handle Oracle servers 488 | "Oracle|Sun" { 489 | $front_name = "$model Front" 490 | $back_name = "$model Rear" 491 | if ($model -match "Blade") { 492 | $oracle_blade_server_stencil_front = Register-VisioShape -Name stencil_front -From oracle_blade_server_stencils -MasterName "$front_name" 493 | $oracle_blade_server_stencil_back = Register-VisioShape -Name stencil_back -From oracle_blade_server_stencils -MasterName "$back_name" 494 | } 495 | else { 496 | if ($arch -match "SPARC|sparc") { 497 | $oracle_sparc_server_stencil_front = Register-VisioShape -Name stencil_front -From oracle_sparc_server_stencils -MasterName "$front_name" 498 | $oracle_sparc_server_stencil_back = Register-VisioShape -Name stencil_back -From oracle_sparc_server_stencils -MasterName "$back_name" 499 | } 500 | else { 501 | $oracle_intel_server_stencil_front = Register-VisioShape -Name stencil_front -From oracle_intel_server_stencils -MasterName "$front_name" 502 | $oracle_intel_server_stencil_back = Register-VisioShape -Name stencil_back -From oracle_intel_server_stencils -MasterName "$back_name" 503 | } 504 | } 505 | } 506 | default { 507 | $front_name = "1U Metal Close Out" 508 | $back_name = "1U Metal Close Out" 509 | $blank_stencil_front = Register-VisioShape -Name stencil_front -From dell_rack_stencils -MasterName "$front_name" 510 | $blank_stencil_back = Register-VisioShape -Name stencil_back -From dell_rack_stencils -MasterName "$back_name" 511 | } 512 | } 513 | # Calculate shape position 514 | $rack_space = [float]$rus * [float]$ru_space 515 | $cur_front_ru_y = [float]$front_ru_y + ([float]$top_ru * [float]$ru_space) - $rack_space 516 | $cur_back_ru_y = [float]$back_ru_y + ([float]$top_ru * [float]$ru_space) - $rack_space 517 | # Place front shape 518 | $shape_pos = Set-NextShapePosition -x $cur_front_ru_x -y $cur_front_ru_y 519 | $shape = stencil_front stencil 520 | $shape_label = $shape.Characters.Text = $info 521 | $text_colour = $shape.Cells("Char.Color").FormulaU = $default_text_colour 522 | $text_size = $shape.Cells("Char.Size").FormulaU = $default_text_size 523 | $text_x_pos = $shape.Cells("TxtLocPinX").FormulaU = $default_text_x_pos 524 | $text_y_pos = $shape.Cells("TxtLocPinY").FormulaU = $default_text_y_pos 525 | $text_back = $shape.Cells("TextBkgnd").FormulaU = $default_back_colour 526 | $text_hidden = $shape.Cells("HideText").FormulaU = $default_text_hidden 527 | $shape_pos = $shape.BringToFront() 528 | $shape_data = Set-VisioShapeData -Shape $stencil -Name SerialNumber $serial 529 | $shape_data = Set-VisioShapeData -Shape $stencil -Name AssetNumber $asset 530 | $shape_data = Set-VisioShapeData -Shape $stencil -Name Location $location 531 | $shape_data = Set-VisioShapeData -Shape $stencil -Name InstalledDate $installed 532 | $shape_data = Set-VisioShapeData -Shape $stencil -Name WarrantyExp $warranty 533 | $shape_data = Set-VisioShapeData -Shape $stencil -Name Room $rack 534 | $shape_data = Set-VisioShapeData -Shape $stencil -Name RackUnits $rus 535 | $shape_data = Set-VisioShapeData -Shape $stencil -Name OperatingSystem $os 536 | $shape_data = Set-VisioShapeData -Shape $stencil -Name SystemName $hostname 537 | # Place back shape 538 | $shape_pos = Set-NextShapePosition -x $cur_back_ru_x -y $cur_back_ru_y 539 | $shape = stencil_back stencil 540 | $shape_label = $shape.Characters.Text = $info 541 | $text_colour = $shape.Cells("Char.Color").FormulaU = $default_text_colour 542 | $text_size = $shape.Cells("Char.Size").FormulaU = $default_text_size 543 | $text_x_pos = $shape.Cells("TxtLocPinX").FormulaU = $default_text_x_pos 544 | $text_y_pos = $shape.Cells("TxtLocPinY").FormulaU = $default_text_y_pos 545 | $text_back = $shape.Cells("TextBkgnd").FormulaU = $default_back_colour 546 | $text_hidden = $shape.Cells("HideText").FormulaU = $default_text_hidden 547 | $shape_pos = $shape.BringToFront() 548 | $shape_data = Set-VisioShapeData -Shape $stencil -Name SerialNumber $serial 549 | $shape_data = Set-VisioShapeData -Shape $stencil -Name AssetNumber $asset 550 | $shape_data = Set-VisioShapeData -Shape $stencil -Name Location $location 551 | $shape_data = Set-VisioShapeData -Shape $stencil -Name InstalledDate $installed 552 | $shape_data = Set-VisioShapeData -Shape $stencil -Name WarrantyExp $warranty 553 | $shape_data = Set-VisioShapeData -Shape $stencil -Name Room $rack 554 | $shape_data = Set-VisioShapeData -Shape $stencil -Name RackUnits $rus 555 | $shape_data = Set-VisioShapeData -Shape $stencil -Name OperatingSystem $os 556 | $shape_data = Set-VisioShapeData -Shape $stencil -Name SystemName $hostname 557 | } 558 | if ($rackperfile) { 559 | $remove_page = Remove-VisioPage -Name "Page-1" 560 | $save_doc = Complete-VisioDocument -Close 561 | } 562 | } 563 | if (!($rackperfile)) { 564 | $remove_page = Remove-VisioPage -Name "Page-1" 565 | $save_doc = Complete-VisioDocument -Close 566 | } 567 | } 568 | -------------------------------------------------------------------------------- /example_full.bat: -------------------------------------------------------------------------------- 1 | powershell -ExecutionPolicy ByPass -File devices.ps1 -longracknames -showlabels -pagelabels -inputfile input\example.csv -outputfile output\example_full.vsd 2 | -------------------------------------------------------------------------------- /example_full_rackperfile.bat: -------------------------------------------------------------------------------- 1 | powershell -ExecutionPolicy ByPass -File devices.ps1 -longracknames -showlablels -rackperfile -inputfile input\example.csv 2 | -------------------------------------------------------------------------------- /example_longracknames.bat: -------------------------------------------------------------------------------- 1 | powershell -ExecutionPolicy ByPass -File devices.ps1 -longracknames -inputfile input\example.csv -outputfile output\examle_longracknames.vsd 2 | -------------------------------------------------------------------------------- /example_showlabels.bat: -------------------------------------------------------------------------------- 1 | powershell -ExecutionPolicy ByPass -File devices.ps1 -showlabels -inputfile input\example.csv -outputfile output\example_showlables.vsd 2 | -------------------------------------------------------------------------------- /input/example.csv: -------------------------------------------------------------------------------- 1 | Hostname,Component,Vendor,Architecture,Model,Operating System,Rack,Rack Units,Top Rack Unit,Serial Number,Asset Number,Installed Date,Warranty Exp,Location,Country 2 | server1,Chassis,Oracle,SPARC,M3000,,A1,2,2,12341,,,,, 3 | server2,Chassis,Oracle,SPARC,M5000,,A1,10,12,12342,,,,, 4 | server3,Chassis,Oracle,x86,X2-4,,A1,3,15,12343,,,,, 5 | array1,SH3,Pure,,Disk shelf,,A1,2,17,12344,,,,, 6 | array1,SH2,Pure,,Disk shelf,,A1,2,19,12345,,,,, 7 | array1,SH1,Pure,,Disk shelf,,A1,2,21,12346,,,,, 8 | array1,SH0,Pure,,Disk shelf,,A1,2,23,12347,,,,, 9 | array1,CH0,Pure,,FA-m70r2,,A1,3,26,12348,,,,, 10 | server5,Chassis,Dell,x86,R820,,A1,2,28,12349,,,,, 11 | flashblade1,CH1,Pure,,FlashBlade,,A1,4,32,123450 12 | server11,Chassis,Oracle,SPARC,M3000,,A2,2,2,12351,,,,, 13 | server12,Chassis,Oracle,SPARC,M5000,,A2,10,12,12352,,,,, 14 | server13,Chassis,Oracle,x86,X2-4,,A2,3,15,12353,,,,, 15 | array2,SH3,Pure,,Disk shelf,,A2,2,17,12354,,,,, 16 | array2,SH2,Pure,,Disk shelf,,A2,2,19,12355,,,,, 17 | array2,SH1,Pure,,Disk shelf,,A2,2,21,12356,,,,, 18 | array2,SH0,Pure,,Disk shelf,,A2,2,23,12357,,,,, 19 | array2,CH0,Pure,,FA-m70r2,,A2,3,26,12358,,,,, 20 | flashblade2,CH1,Pure,,FlashBlade,,A2,4,30,123459,,,,, 21 | -------------------------------------------------------------------------------- /output/example_full.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lateralblast/devices/c238e96f919c1e97df65e47953867170b7953cd1/output/example_full.vsd -------------------------------------------------------------------------------- /rack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lateralblast/devices/c238e96f919c1e97df65e47953867170b7953cd1/rack.jpg --------------------------------------------------------------------------------