├── DFW2Excel.ps1 ├── DFW2Excel_Workbook_Example.xlsx ├── License.txt └── README.md /DFW2Excel.ps1: -------------------------------------------------------------------------------- 1 | # Author: Tony Sangha 2 | # Blog: tonysangha.com 3 | # Version: 1.0.1 4 | # PowerCLI v6.0 5 | # PowerNSX v3.0 6 | # Purpose: Document NSX for vSphere Distributed Firewall 7 | 8 | param ( 9 | [switch]$EnableIpDetection, 10 | [switch]$GetSecTagMembers, 11 | [switch]$GetSecGrpMembers, 12 | [switch]$StartMinimised, 13 | [string]$DocumentPath 14 | ) 15 | 16 | # Import PowerNSX Module 17 | import-module PowerNSX 18 | 19 | # Import PowerCLI modules, PowerCLI must be installed 20 | if ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { 21 | if (Test-Path -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware, Inc.\VMware vSphere PowerCLI' ) { 22 | $Regkey = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\VMware, Inc.\VMware vSphere PowerCLI' 23 | 24 | } else { 25 | $Regkey = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.\VMware vSphere PowerCLI' 26 | } 27 | . (join-path -path (Get-ItemProperty $Regkey).InstallPath -childpath 'Scripts\Initialize-PowerCLIEnvironment.ps1') 28 | } 29 | if ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { 30 | Write-Host "VMware modules not loaded/unable to load" 31 | Exit 99 32 | } 33 | 34 | # Empty Hash-tables for use with Hyperlinks 35 | $services_ht = @{} 36 | $vmaddressing_ht = @{} 37 | $ipsets_ht = @{} 38 | $secgrp_ht = @{} 39 | ######################################################## 40 | # Cleanup Excel application object 41 | # We Need to call this for EVERY VARIABLE that references 42 | # an excel object. __EVERY VARIABLE__ 43 | ######################################################## 44 | function ReleaseObject { 45 | param ( 46 | $Obj 47 | ) 48 | 49 | Try { 50 | $intRel = 0 51 | Do { 52 | $intRel = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Obj) 53 | } While ($intRel -gt 0) 54 | } 55 | Catch { 56 | throw "Error releasing object: $_" 57 | } 58 | Finally { 59 | [System.GC]::Collect() 60 | 61 | } 62 | } 63 | 64 | ######################################################## 65 | # Cleanup Excel application object 66 | # We Need to call this for EVERY VARIABLE that references 67 | # an excel object. __EVERY VARIABLE__ 68 | ######################################################## 69 | function ReleaseObject { 70 | param ( 71 | $Obj 72 | ) 73 | 74 | Try { 75 | $intRel = 0 76 | Do { 77 | $intRel = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($Obj) 78 | } While ($intRel -gt 0) 79 | } 80 | Catch { 81 | throw "Error releasing object: $_" 82 | } 83 | Finally { 84 | [System.GC]::Collect() 85 | 86 | } 87 | } 88 | 89 | ######################################################## 90 | # Formatting/Functions Options for Excel Spreadsheet 91 | ######################################################## 92 | 93 | $titleFontSize = 18 94 | $titleFontBold = $True 95 | $titleFontColorIndex = 2 96 | $titleFontName = "Calibri (Body)" 97 | $titleInteriorColor = 10 98 | 99 | $subTitleFontSize = 10.5 100 | $subTitleFontBold = $True 101 | $subTitleFontName = "Calibri (Body)" 102 | $subTitleInteriorColor = 43 103 | 104 | $valueFontName = "Calibri (Body)" 105 | $valueFontSize = 10.5 106 | $valueMissingColorIndex = 107 | $valueMissingText = "" 108 | $valueMissingHighlight = 6 109 | $valueNotApplicable = "" 110 | $valueNotDefined = "" 111 | 112 | ######################################################## 113 | # Global Parameters 114 | ######################################################## 115 | 116 | New-VIProperty -Name VMIPAddress -ObjectType VirtualMachine ` 117 | -ValueFromExtensionProperty 'Summary.Guest.IPAddress' ` 118 | -Force 119 | 120 | ######################################################## 121 | # Define Excel Workbook and calls to different WS 122 | ######################################################## 123 | function startExcel(){ 124 | 125 | $Excel = New-Object -Com Excel.Application 126 | if ( -not $StartMinimised ) { 127 | $Excel.visible = $True 128 | } 129 | $Excel.DisplayAlerts = $false 130 | $wb = $Excel.Workbooks.Add() 131 | 132 | if ($args[0] -eq "y"){ 133 | 134 | Write-Host "`nRetrieving IP Addresses for ALL Virtual Machines in vCenter environment." -foregroundcolor "magenta" 135 | Write-Host "*** This may take a while ***." -foregroundcolor "Yellow" 136 | $ws0 = $wb.WorkSheets.Add() 137 | $ws0.Name = "VM_Info" 138 | vm_ip_addresses_ws($ws0) 139 | $usedRange = $ws0.UsedRange 140 | $usedRange.EntireColumn.Autofit() 141 | } 142 | 143 | Write-Host "`nRetrieving Services configured in NSX-v." -foregroundcolor "magenta" 144 | $ws1 = $wb.WorkSheets.Add() 145 | $ws1.Name = "Services" 146 | services_ws($ws1) 147 | $usedRange = $ws1.UsedRange 148 | $usedRange.EntireColumn.Autofit() 149 | 150 | Write-Host "`nRetrieving Service Groups configured in NSX-v." -foregroundcolor "magenta" 151 | $ws2 = $wb.WorkSheets.Add() 152 | $ws2.Name = "Service_Groups" 153 | service_groups_ws($ws2) 154 | $usedRange = $ws2.UsedRange 155 | $usedRange.EntireColumn.Autofit() 156 | 157 | Write-Host "`nRetrieving MACSETS configured in NSX-v." -foregroundcolor "magenta" 158 | $ws3 = $wb.WorkSheets.Add() 159 | $ws3.Name = "MACSETS" 160 | macset_ws($ws3) 161 | $usedRange = $ws3.UsedRange 162 | $usedRange.EntireColumn.Autofit() 163 | 164 | Write-Host "`nRetrieving IPSETS configured in NSX-v." -foregroundcolor "magenta" 165 | $ws4 = $wb.WorkSheets.Add() 166 | $ws4.Name = "IPSETS" 167 | ipset_ws($ws4) 168 | $usedRange = $ws4.UsedRange 169 | $usedRange.EntireColumn.Autofit() 170 | 171 | Write-Host "`nRetrieving Security Groups configured in NSX-v." -foregroundcolor "magenta" 172 | $ws5 = $wb.WorkSheets.Add() 173 | $ws5.Name = "Security_Groups" 174 | sg_ws($ws5) 175 | $usedRange = $ws5.UsedRange 176 | $usedRange.EntireColumn.Autofit() 177 | 178 | Write-Host "`nRetrieving Security Tags configured in NSX-v." -foregroundcolor "magenta" 179 | $ws6 = $wb.Worksheets.Add() 180 | $ws6.Name = "Security_Tags" 181 | sec_tags_ws($ws6) 182 | $usedRange = $ws6.UsedRange 183 | $usedRange.EntireColumn.Autofit() 184 | 185 | Write-Host "`nRetrieving VMs in DFW Exclusion List" -foregroundcolor "magenta" 186 | $ws7 = $wb.Worksheets.Add() 187 | $ws7.Name = "DFW Exclusion list" 188 | ex_list_ws($ws7) 189 | $usedRange = $ws7.UsedRange 190 | $usedRange.EntireColumn.Autofit() 191 | 192 | Write-Host "`nRetrieving Environment Summary" -foregroundcolor "magenta" 193 | $ws8 = $wb.Worksheets.Add() 194 | $ws8.Name = "Environment Summary" 195 | env_ws($ws8) 196 | $usedRange = $ws8.UsedRange 197 | $usedRange.EntireColumn.Autofit() 198 | 199 | Write-Host "`nRetrieving DFW Layer 3 FW Rules" -foregroundcolor "magenta" 200 | $ws9 = $wb.Worksheets.Add() 201 | $ws9.Name = "Layer 3 Firewall" 202 | dfw_ws($ws9) 203 | $usedRange = $ws9.UsedRange 204 | $usedRange.EntireColumn.Autofit() 205 | 206 | # Must cleanup manually or excel process wont quit. 207 | ReleaseObject -Obj $ws1 208 | ReleaseObject -Obj $ws2 209 | ReleaseObject -Obj $ws3 210 | ReleaseObject -Obj $ws4 211 | ReleaseObject -Obj $ws5 212 | ReleaseObject -Obj $ws6 213 | ReleaseObject -Obj $ws7 214 | ReleaseObject -Obj $ws8 215 | ReleaseObject -Obj $ws9 216 | ReleaseObject -Obj $usedRange 217 | 218 | if ( $DocumentPath -and (test-path (split-path -parent $DocumentPath))) { 219 | $wb.SaveAs($DocumentPath) 220 | $wb.close(0) 221 | $Excel.Quit() 222 | ReleaseObject -Obj $Excel 223 | ReleaseObject -Obj $wb 224 | 225 | } 226 | } 227 | 228 | ######################################################## 229 | # Firewall Worksheet (Only Layer 3) 230 | ######################################################## 231 | 232 | function dfw_ws($sheet){ 233 | 234 | $sheet.Cells.Item(1,1) = "Firewall Configuration" 235 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 236 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 237 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 238 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 239 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 240 | $range1 = $sheet.Range("a1", "s1") 241 | $range1.merge() | Out-Null 242 | 243 | l3_rules($sheet) 244 | } 245 | 246 | function l3_rules($sheet){ 247 | 248 | $sheet.Cells.Item(2,1) = "Layer 3 Rules" 249 | $sheet.Cells.Item(2,1).Font.Bold = $titleFontBold 250 | $sheet.Cells.Item(2,1).Font.ColorIndex = $titleFontColorIndex 251 | $sheet.Cells.Item(2,1).Font.Name = $titleFontName 252 | $sheet.Cells.Item(2,1).Interior.ColorIndex = $titleInteriorColor 253 | $range1 = $sheet.Range("a2", "s2") 254 | 255 | $sheet.Cells.Item(3,1) = "Section Name" 256 | $sheet.Cells.Item(3,2) = "Section ID" 257 | 258 | $sheet.Cells.Item(3,3) = "Rule Status" 259 | $sheet.Cells.Item(3,4) = "Rule Name" 260 | $sheet.Cells.Item(3,5) = "Rule ID" 261 | 262 | $sheet.Cells.Item(3,6) = "Source Excluded (Negated)" 263 | $sheet.Cells.Item(3,7) = "Source Type" 264 | $sheet.Cells.Item(3,8) = "Source Name" 265 | $sheet.Cells.Item(3,9) = "Source Object ID" 266 | 267 | $sheet.Cells.Item(3,10) = "Destination Excluded (Negated)" 268 | $sheet.Cells.Item(3,11) = "Destination Type" 269 | $sheet.Cells.Item(3,12) = "Destination Name" 270 | $sheet.Cells.Item(3,13) = "Destination Object ID" 271 | 272 | $sheet.Cells.Item(3,14) = "Service Name" 273 | $sheet.Cells.Item(3,15) = "Action" 274 | $sheet.Cells.Item(3,16) = "Direction" 275 | $sheet.Cells.Item(3,17) = "Packet Type" 276 | $sheet.Cells.Item(3,18) = "Applied To" 277 | $sheet.Cells.Item(3,19) = "Log" 278 | 279 | $range2 = $sheet.Range("a3", "s3") 280 | $range2.Font.Bold = $subTitleFontBold 281 | $range2.Interior.ColorIndex = $subTitleInteriorColor 282 | $range2.Font.Name = $subTitleFontName 283 | 284 | $fw_sections = Get-NSXFirewallSection 285 | 286 | $row = 4 287 | 288 | foreach($section in $fw_sections){ 289 | $sheet.Cells.Item($row,1) = $section.name 290 | $sheet.Cells.Item($row,1).Font.Bold = $true 291 | $sheet.Cells.Item($row,2) = $section.id 292 | $sheet.Cells.Item($row,2).Font.Bold = $true 293 | 294 | foreach($rule in $section.rule){ 295 | 296 | if($rule.disabled -eq "false"){ 297 | $sheet.Cells.Item($row,3) = "Enabled" 298 | } else { 299 | $sheet.Cells.Item($row,3) = "Disabled" 300 | } 301 | if ($rule.name -eq "rule"){ 302 | $sheet.Cells.Item($row,4) = $valueNotDefined 303 | } else { 304 | $sheet.Cells.Item($row,4) = $rule.name 305 | $sheet.Cells.Item($row,4).Font.Bold = $true 306 | } 307 | $sheet.Cells.Item($row,5) = $rule.id 308 | $sheet.Cells.Item($row,5).Font.Bold = $true 309 | 310 | # Highlight Allow/Deny statements 311 | if($rule.action -eq "deny"){ 312 | $sheet.Cells.Item($row,15) = $rule.action 313 | $sheet.Cells.Item($row,15).Font.ColorIndex = 3 314 | } elseif($rule.action -eq "allow"){ 315 | $sheet.Cells.Item($row,15) = $rule.action 316 | $sheet.Cells.Item($row,15).Font.ColorIndex = 4 317 | } 318 | 319 | $sheet.Cells.Item($row,16) = $rule.direction 320 | $sheet.Cells.Item($row,17) = $rule.packetType 321 | $sheet.Cells.Item($row,19) = $rule.logged 322 | 323 | ###### Sources Section ###### 324 | $srcRow = $row 325 | 326 | # If Source does not exist, it must be set to ANY 327 | if (!$rule.sources){ 328 | $sheet.Cells.Item($srcRow,8) = "ANY" 329 | $sheet.Cells.Item($srcRow,8).Font.ColorIndex = 45 330 | } else { 331 | #If Negated field exists, document 332 | if ($rule.sources.excluded -eq "True" ){ 333 | $sheet.Cells.Item($srcRow,6) = "NEGATE" 334 | $sheet.Cells.Item($row,6).Font.ColorIndex = 3 335 | } 336 | 337 | foreach($source in $rule.sources.source){ 338 | $sheet.Cells.Item($srcRow,7) = $source.type 339 | 340 | if($source.type -eq "Ipv4Address"){ 341 | $sheet.Cells.Item($srcRow,8) = $source.value 342 | } 343 | elseif($source.type -eq "Ipv6Address") { 344 | $sheet.Cells.Item($srcRow,8) = $source.value 345 | } 346 | elseif ($source.type -eq "IPSet") { 347 | $result = $ipsets_ht[$source.value] 348 | if([string]::IsNullOrWhiteSpace($result)) 349 | { 350 | $sheet.Cells.Item($srcRow,8) = $source.name 351 | $sheet.Cells.Item($srcRow,9) = $source.value 352 | } 353 | else 354 | { 355 | $link = $sheet.Hyperlinks.Add( 356 | $sheet.Cells.Item($srcRow,8), 357 | "", 358 | $result, 359 | $source.value, 360 | $source.name) 361 | $sheet.Cells.Item($srcRow,9) = $source.value 362 | } 363 | } 364 | elseif ($source.type -eq "SecurityGroup") { 365 | $result = $secgrp_ht[$source.value] 366 | if([string]::IsNullOrWhiteSpace($result)) 367 | { 368 | $sheet.Cells.Item($srcRow,8) = $source.name 369 | $sheet.Cells.Item($srcRow,9) = $source.value 370 | } 371 | else 372 | { 373 | $link = $sheet.Hyperlinks.Add( 374 | $sheet.Cells.Item($srcRow,8), 375 | "", 376 | $result, 377 | $source.value, 378 | $source.name) 379 | $sheet.Cells.Item($srcRow,9) = $source.value 380 | } 381 | } 382 | elseif ($source.type -eq "VirtualMachine") { 383 | $result = $vmaddressing_ht[$source.value] 384 | if([string]::IsNullOrWhiteSpace($result)) 385 | { 386 | $sheet.Cells.Item($srcRow,8) = $source.name 387 | $sheet.Cells.Item($srcRow,9) = $source.value 388 | } 389 | else 390 | { 391 | $link = $sheet.Hyperlinks.Add( 392 | $sheet.Cells.Item($srcRow,8), 393 | "", 394 | $result, 395 | $source.value, 396 | $source.name) 397 | $sheet.Cells.Item($srcRow,9) = $source.value 398 | } 399 | } 400 | else { 401 | $sheet.Cells.Item($srcRow,8) = $source.name 402 | $sheet.Cells.Item($srcRow,9) = $source.value 403 | } 404 | $srcRow++ 405 | } 406 | } 407 | 408 | ###### Destination Section ###### 409 | $dstRow = $row 410 | 411 | # If Destination does not exist, it must be set to ANY 412 | if (!$rule.destinations){ 413 | $sheet.Cells.Item($dstRow,13) = "ANY" 414 | $sheet.Cells.Item($dstRow,13).Font.ColorIndex = 45 415 | } else { 416 | 417 | #If Negated field exists, document 418 | if ($rule.destinations.excluded -eq "True" ){ 419 | $sheet.Cells.Item($srcRow,10) = "NEGATE" 420 | $sheet.Cells.Item($row,10).Font.ColorIndex = 3 421 | } 422 | 423 | foreach($destination in $rule.destinations.destination){ 424 | $sheet.Cells.Item($dstRow,11) = $destination.type 425 | if($destination.type -eq "Ipv4Address"){ 426 | $sheet.Cells.Item($dstRow,12) = $destination.value 427 | } 428 | elseif($destination.type -eq "Ipv6Address") { 429 | $sheet.Cells.Item($dstRow,12) = $destination.value 430 | } 431 | elseif ($destination.type -eq "IPSet") { 432 | $result = $ipsets_ht[$destination.value] 433 | if([string]::IsNullOrWhiteSpace($result)) 434 | { 435 | $sheet.Cells.Item($dstRow,12) = $destination.name 436 | $sheet.Cells.Item($dstRow,13) = $destination.value 437 | } 438 | else 439 | { 440 | $link = $sheet.Hyperlinks.Add( 441 | $sheet.Cells.Item($dstRow,12), 442 | "", 443 | $result, 444 | $destination.value, 445 | $destination.name) 446 | $sheet.Cells.Item($dstRow,13) = $destination.value 447 | } 448 | } 449 | elseif ($destination.type -eq "VirtualMachine") { 450 | $result = $vmaddressing_ht[$destination.value] 451 | if([string]::IsNullOrWhiteSpace($result)) 452 | { 453 | $sheet.Cells.Item($dstRow,12) = $destination.name 454 | $sheet.Cells.Item($dstRow,13) = $destination.value 455 | } 456 | else 457 | { 458 | $link = $sheet.Hyperlinks.Add( 459 | $sheet.Cells.Item($dstRow,12), 460 | "", 461 | $result, 462 | $destination.value, 463 | $destination.name) 464 | $sheet.Cells.Item($dstRow,13) = $destination.value 465 | } 466 | } 467 | elseif ($destination.type -eq "SecurityGroup") { 468 | $result = $secgrp_ht[$destination.value] 469 | if([string]::IsNullOrWhiteSpace($result)) 470 | { 471 | $sheet.Cells.Item($dstRow,12) = $destination.name 472 | $sheet.Cells.Item($dstRow,13) = $destination.value 473 | } 474 | else 475 | { 476 | $link = $sheet.Hyperlinks.Add( 477 | $sheet.Cells.Item($dstRow,12), 478 | "", 479 | $result, 480 | $destination.value, 481 | $destination.name) 482 | $sheet.Cells.Item($dstRow,13) = $destination.value 483 | } 484 | } 485 | else { 486 | $sheet.Cells.Item($dstRow,12) = $destination.name 487 | $sheet.Cells.Item($dstRow,13) = $destination.value 488 | } 489 | $dstRow++ 490 | } 491 | } 492 | 493 | ###### Services Section ###### 494 | $svcRow = $row 495 | 496 | # If Service does not exist, it must be set to ANY 497 | if(!$rule.services){ 498 | $sheet.Cells.Item($svcRow,14) = "ANY" 499 | $sheet.Cells.Item($svcRow,14).Font.ColorIndex = 45 500 | } else { 501 | foreach($service in $rule.services.service){ 502 | if($service.protocolName) 503 | { 504 | $sheet.Cells.Item($svcRow,14) = $service.protocolName + "/" + $service.destinationPort 505 | } 506 | else { 507 | # $sheet.Cells.Item($svcRow,14) = $service.name 508 | $result = $services_ht[$service.value] 509 | if([string]::IsNullOrWhiteSpace($result)) 510 | { 511 | $sheet.Cells.Item($svcRow,14) = $service.name 512 | # $svcRow++ # Increment Rows 513 | } 514 | else 515 | { 516 | $link = $sheet.Hyperlinks.Add( 517 | $sheet.Cells.Item($svcRow,14), 518 | "", 519 | $result, 520 | $service.value, 521 | $service.name) 522 | # $svcRow++ # Increment Rows 523 | } 524 | } 525 | $svcRow++ 526 | } 527 | } 528 | 529 | ###### AppliedTo ###### 530 | $appRow = $row 531 | 532 | foreach($appliedTo in $rule.appliedToList.appliedTo){ 533 | $sheet.Cells.Item($appRow,18) = $appliedTo.name 534 | $appRow++ 535 | } 536 | $row = ($srcRow,$dstRow,$svcRow,$appRow | Measure-Object -Maximum).Maximum 537 | } 538 | $row++ 539 | $sheet.Cells.Item($row,1).Interior.ColorIndex = $titleInteriorColor 540 | $range1 = $sheet.Range("a"+$row, "s"+$row) 541 | $range1.merge() | Out-Null 542 | $row++ 543 | 544 | } 545 | } 546 | 547 | ######################################################## 548 | # Security Groups 549 | ######################################################## 550 | 551 | function sg_ws($sheet){ 552 | 553 | $sheet.Cells.Item(1,1) = "Security Group Configuration" 554 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 555 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 556 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 557 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 558 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 559 | $range1 = $sheet.Range("a1", "j1") 560 | $range1.merge() | Out-Null 561 | 562 | $sheet.Cells.Item(2,1) = "Name" 563 | $sheet.Cells.Item(2,2) = "Scope" 564 | $sheet.Cells.Item(2,3) = "Universal" 565 | $sheet.Cells.Item(2,4) = "Inheritance Allowed" 566 | $sheet.Cells.Item(2,5) = "Group Type (Dynamic/Static)" 567 | $sheet.Cells.Item(2,6) = "Dynamic Query Key Value" 568 | $sheet.Cells.Item(2,7) = "Dynamic Query Operator" 569 | $sheet.Cells.Item(2,8) = "Dynamic Query Criteria" 570 | $sheet.Cells.Item(2,9) = "Dynamic Query Value" 571 | $sheet.Cells.Item(2,10) = "Object-ID" 572 | $range2 = $sheet.Range("a2", "j2") 573 | $range2.Font.Bold = $subTitleFontBold 574 | $range2.Interior.ColorIndex = $subTitleInteriorColor 575 | $range2.Font.Name = $subTitleFontName 576 | pop_sg_ws($sheet) 577 | } 578 | 579 | function pop_sg_ws($sheet){ 580 | 581 | $row = 3 582 | $sg = Get-NSXSecurityGroup -scopeID 'globalroot-0' 583 | foreach ($member in $sg){ 584 | try 585 | { 586 | $link_ref = "Security_Groups!" + ($sheet.Cells.Item($row,1)).address($false,$false) 587 | if($secgrp_ht.ContainsKey($member.objectID) -eq $false) 588 | { 589 | $secgrp_ht.Add($member.objectID, $link_ref) 590 | } 591 | } 592 | catch [Exception]{ 593 | Write-Warning $member.objectID + "already exists, manually create hyperlink reference" 594 | } 595 | 596 | if($member.dynamicMemberDefinition){ 597 | 598 | $sheet.Cells.Item($row,1) = $member.name 599 | $sheet.Cells.Item($row,2) = $member.scope.name 600 | $sheet.Cells.Item($row,3) = $member.isUniversal 601 | $sheet.Cells.Item($row,4) = $member.inhertianceAllowed 602 | $sheet.Cells.Item($row,10) = $member.objectId 603 | $sheet.Cells.Item($row,5) = "Dynamic" 604 | 605 | foreach ($entity in $member.dynamicMemberDefinition.dynamicSet.dynamicCriteria){ 606 | $sheet.Cells.Item($row,6) = $entity.key 607 | $sheet.Cells.Item($row,7) = $entity.operator 608 | $sheet.Cells.Item($row,8) = $entity.criteria 609 | $sheet.Cells.Item($row,9) = $entity.value 610 | $row++ 611 | } 612 | } 613 | else{ 614 | $sheet.Cells.Item($row,1) = $member.name 615 | $sheet.Cells.Item($row,2) = $member.scope.name 616 | $sheet.Cells.Item($row,3) = $member.isUniversal 617 | $sheet.Cells.Item($row,4) = $member.inhertianceAllowed 618 | $sheet.Cells.Item($row,10) = $member.objectId 619 | $sheet.Cells.Item($row,5) = "Static" 620 | $row++ 621 | } 622 | } 623 | $sgu = Get-NSXSecurityGroup -scopeID 'universalroot-0' 624 | foreach ($member in $sgu){ 625 | try 626 | { 627 | $link_ref = "Security_Groups!" + ($sheet.Cells.Item($row,1)).address($false,$false) 628 | if($secgrp_ht.ContainsKey($member.objectID) -eq $false) 629 | { 630 | $secgrp_ht.Add($member.objectID, $link_ref) 631 | } 632 | } 633 | catch [Exception]{ 634 | Write-Warning $member.objectID + "already exists, manually create hyperlink reference" 635 | } 636 | if($member.dynamicMemberDefinition){ 637 | 638 | $sheet.Cells.Item($row,1) = $member.name 639 | $sheet.Cells.Item($row,2) = $member.scope.name 640 | $sheet.Cells.Item($row,3) = $member.isUniversal 641 | $sheet.Cells.Item($row,4) = $member.inhertianceAllowed 642 | $sheet.Cells.Item($row,10) = $member.objectId 643 | $sheet.Cells.Item($row,5) = "Dynamic" 644 | 645 | foreach ($entity in $member.dynamicMemberDefinition.dynamicSet.dynamicCriteria){ 646 | $sheet.Cells.Item($row,6) = $entity.key 647 | $sheet.Cells.Item($row,7) = $entity.operator 648 | $sheet.Cells.Item($row,8) = $entity.criteria 649 | $sheet.Cells.Item($row,9) = $entity.value 650 | $row++ 651 | } 652 | } 653 | else{ 654 | $sheet.Cells.Item($row,1) = $member.name 655 | $sheet.Cells.Item($row,2) = $member.scope.name 656 | $sheet.Cells.Item($row,3) = $member.isUniversal 657 | $sheet.Cells.Item($row,4) = $member.inhertianceAllowed 658 | $sheet.Cells.Item($row,10) = $member.objectId 659 | $sheet.Cells.Item($row,5) = "Static" 660 | $row++ 661 | } 662 | } 663 | 664 | $sheet.Cells.Item($row,1) = "Security Group Membership" 665 | $sheet.Cells.Item($row,1).Font.Size = $titleFontSize 666 | $sheet.Cells.Item($row,1).Font.Bold = $titleFontBold 667 | $sheet.Cells.Item($row,1).Font.ColorIndex = $titleFontColorIndex 668 | $sheet.Cells.Item($row,1).Font.Name = $titleFontName 669 | $sheet.Cells.Item($row,1).Interior.ColorIndex = $titleInteriorColor 670 | $range2 = $sheet.Range("a"+$row, "j"+$row) 671 | $range2.merge() | Out-Null 672 | 673 | $row++ 674 | 675 | $sheet.Cells.Item($row,1) = "SG Name" 676 | $sheet.Cells.Item($row,2) = "VM ID" 677 | $sheet.Cells.Item($row,3) = "VM Name" 678 | $range3 = $sheet.Range("a"+$row, "c"+$row) 679 | $range3.Font.Bold = $subTitleFontBold 680 | $range3.Interior.ColorIndex = $subTitleInteriorColor 681 | $range3.Font.Name = $subTitleFontName 682 | 683 | $row++ 684 | 685 | if ($collect_vm_members -eq "y") { 686 | Write-Host "Collection of VM Sec Membership Enabled" 687 | 688 | foreach ($member in $sg){ 689 | 690 | $members = $member | Get-NSXSecurityGroupEffectiveMember 691 | 692 | $sheet.Cells.Item($row,1) = $member.name 693 | 694 | foreach ($vm in $members.virtualmachine.vmnode) 695 | { 696 | $sheet.Cells.Item($row,2) = $vm.vmID 697 | $sheet.Cells.Item($row,3) = $vm.vmName 698 | 699 | $result = $vmaddressing_ht[$vm.vmID] 700 | if([string]::IsNullOrWhiteSpace($result)) 701 | { 702 | $sheet.Cells.Item($row,3) = $vm.vmName 703 | } 704 | else 705 | { 706 | $link = $sheet.Hyperlinks.Add( 707 | $sheet.Cells.Item($row,3), 708 | "", 709 | $result, 710 | "Virtual Machine Information", 711 | $vm.vmName) 712 | } 713 | $row++ 714 | } 715 | } 716 | } 717 | else { 718 | Write-Host "Collection of VM Sec Membership Disabled" 719 | $sheet.Cells.Item($row,2) = "" 720 | $sheet.Cells.Item($row,2).Font.ColorIndex = 3 721 | $sheet.Cells.Item($row,3) = "" 722 | $sheet.Cells.Item($row,3).Font.ColorIndex = 3 723 | } 724 | } 725 | 726 | ######################################################## 727 | # Environment Summary 728 | ######################################################## 729 | 730 | function env_ws($sheet){ 731 | 732 | $sheet.Cells.Item(1,1) = "NSX Environment Summary" 733 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 734 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 735 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 736 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 737 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 738 | $range1 = $sheet.Range("a1", "j1") 739 | $range1.merge() | Out-Null 740 | 741 | $sys_sum = Get-NsxManagerSystemSummary 742 | $ssoconfig = Get-NsxManagerSsoConfig 743 | $vcconfig = Get-NsxManagerVcenterConfig 744 | $ver = Get-PowerNSXVersion 745 | 746 | $sheet.Cells.Item(2,1) = "PowerNSX version" 747 | $sheet.Cells.Item(2,2) = $ver.version.toString() 748 | 749 | $sheet.Cells.Item(3,1) = "NSX Manager Name" 750 | $sheet.Cells.Item(3,2) = $sys_sum.hostName 751 | 752 | $sheet.Cells.Item(4,1) = "IPv4 Address" 753 | $sheet.Cells.Item(4,2) = $sys_sum.Ipv4Address 754 | 755 | $sheet.Cells.Item(5,1) = "SSO Lookup URL" 756 | $sheet.Cells.Item(5,2) = $ssoconfig.ssoLookupServiceUrl 757 | 758 | $sheet.Cells.Item(6,1) = "SSO User Account" 759 | $sheet.Cells.Item(6,2) = $ssoconfig.ssoAdminUsername 760 | 761 | $sheet.Cells.Item(7,1) = "vCenter Mapping" 762 | $sheet.Cells.Item(7,2) = $vcconfig.ipAddress 763 | 764 | $sheet.Cells.Item(8,1) = "NSX Manager Version" 765 | $sheet.Cells.Item(8,2) = ($sys_sum.versionInfo.majorVersion + "." ` 766 | + $sys_sum.versionInfo.minorVersion + "." ` 767 | + $sys_sum.versionInfo.patchVersion + "." ` 768 | + $sys_sum.versionInfo.buildNumber) 769 | 770 | $sheet.Cells.Item(9,1) = "Security Group Membership Statistics" 771 | $sheet.Cells.Item(9,1).Font.Size = $titleFontSize 772 | $sheet.Cells.Item(9,1).Font.Bold = $titleFontBold 773 | $sheet.Cells.Item(9,1).Font.ColorIndex = $titleFontColorIndex 774 | $sheet.Cells.Item(9,1).Font.Name = $titleFontName 775 | $sheet.Cells.Item(9,1).Interior.ColorIndex = $titleInteriorColor 776 | $range1 = $sheet.Range("a9", "j9") 777 | $range1.merge() | Out-Null 778 | 779 | $sheet.Cells.Item(10,1) = "Security Group Name" 780 | $sheet.Cells.Item(10,2) = "Translated VMs" 781 | $sheet.Cells.Item(10,3) = "Translated IPs" 782 | $range2 = $sheet.Range("a10", "c10") 783 | $range2.Font.Bold = $subTitleFontBold 784 | $range2.Interior.ColorIndex = $subTitleInteriorColor 785 | $range2.Font.Name = $subTitleFontName 786 | pop_env_ws($sheet) 787 | } 788 | 789 | function pop_env_ws($sheet){ 790 | 791 | $row = 11 792 | 793 | ### Security Group Membership statistics 794 | 795 | $sg = Get-NSXSecurityGroup 796 | 797 | foreach($item in $sg){ 798 | 799 | $sheet.Cells.Item($row,1) = $item.name 800 | 801 | $url_vms = "/api/2.0/services/securitygroup/" + $item.objectid + ` 802 | "/translation/virtualmachines" 803 | $url_ips = "/api/2.0/services/securitygroup/" + $item.objectid + ` 804 | "/translation/ipaddresses" 805 | 806 | $sec_vm_stats = Invoke-NsxRestMethod -method get -uri $url_vms 807 | $sheet.Cells.Item($row,2) = $sec_vm_stats.vmnodes.vmnode.Length 808 | 809 | $sec_ip_stats = Invoke-NsxRestMethod -method get -uri $url_ips 810 | $sheet.Cells.Item($row,3) = $sec_ip_stats.ipNodes.ipNode.ipAddresses.Length 811 | 812 | $row ++ 813 | } 814 | } 815 | 816 | ######################################################## 817 | # IPSETS Worksheet 818 | ######################################################## 819 | 820 | function ipset_ws($sheet){ 821 | 822 | $sheet.Cells.Item(1,1) = "IPSET Configuration" 823 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 824 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 825 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 826 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 827 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 828 | $range1 = $sheet.Range("a1", "d1") 829 | $range1.merge() | Out-Null 830 | 831 | $sheet.Cells.Item(2,1) = "Name" 832 | $sheet.Cells.Item(2,2) = "Value" 833 | $sheet.Cells.Item(2,3) = "Universal" 834 | $sheet.Cells.Item(2,4) = "Object-ID" 835 | $sheet.Cells.Item(2,5) = "Description" 836 | $range2 = $sheet.Range("a2", "e2") 837 | $range2.Font.Bold = $subTitleFontBold 838 | $range2.Interior.ColorIndex = $subTitleInteriorColor 839 | $range2.Font.Name = $subTitleFontName 840 | pop_ipset_ws($sheet) 841 | } 842 | 843 | function pop_ipset_ws($sheet){ 844 | 845 | $row=3 846 | $ipset = get-nsxipset -scopeID 'globalroot-0' 847 | 848 | foreach ($ip in $ipset) { 849 | 850 | $sheet.Cells.Item($row,1) = $ip.name 851 | $sheet.Cells.Item($row,2) = $ip.value 852 | $sheet.Cells.Item($row,3) = $ip.isUniversal 853 | $sheet.Cells.Item($row,4) = $ip.objectId 854 | try 855 | { 856 | $link_ref = "IPSETS!" + ($sheet.Cells.Item($row,1)).address($false,$false) 857 | if($ipsets_ht.ContainsKey($ip.objectID) -eq $false) 858 | { 859 | $ipsets_ht.Add($ip.objectID, $link_ref) 860 | } 861 | } 862 | catch [Exception]{ 863 | Write-Warning $ip.objectID + "already exists, manually create hyperlink reference" 864 | } 865 | if(!$ip.description){ 866 | $sheet.Cells.Item($row,5) = $valueNotDefined 867 | } 868 | else {$sheet.Cells.Item($row,5) = $ip.description} 869 | 870 | $row++ # Increment Rows 871 | } 872 | 873 | $ipset_unv = get-nsxipset -scopeID 'universalroot-0' 874 | 875 | foreach ($ip in $ipset_unv) { 876 | 877 | $sheet.Cells.Item($row,1) = $ip.name 878 | $sheet.Cells.Item($row,2) = $ip.value 879 | $sheet.Cells.Item($row,3) = $ip.isUniversal 880 | $sheet.Cells.Item($row,4) = $ip.objectId 881 | try 882 | { 883 | $link_ref = "IPSETS!" + ($sheet.Cells.Item($row,1)).address($false,$false) 884 | if($ipsets_ht.ContainsKey($ip.objectID) -eq $false) 885 | { 886 | $ipsets_ht.Add($ip.objectID, $link_ref) 887 | } 888 | } 889 | catch [Exception]{ 890 | Write-Warning $ip.objectID + "already exists, manually create hyperlink reference" 891 | } 892 | 893 | if(!$ip.description){ 894 | $sheet.Cells.Item($row,5) = $valueNotDefined 895 | } 896 | else {$sheet.Cells.Item($row,5) = $ip.description} 897 | $row++ # Increment Rows 898 | } 899 | } 900 | 901 | ######################################################## 902 | # MACSETS Worksheet 903 | ######################################################## 904 | 905 | function macset_ws($sheet){ 906 | 907 | $sheet.Cells.Item(1,1) = "MACSET Configuration" 908 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 909 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 910 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 911 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 912 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 913 | $range1 = $sheet.Range("a1", "e1") 914 | $range1.merge() | Out-Null 915 | 916 | $sheet.Cells.Item(2,1) = "Name" 917 | $sheet.Cells.Item(2,2) = "Value" 918 | $sheet.Cells.Item(2,3) = "Description" 919 | $range2 = $sheet.Range("a2", "c2") 920 | $range2.Font.Bold = $subTitleFontBold 921 | $range2.Interior.ColorIndex = $subTitleInteriorColor 922 | $range2.Font.Name = $subTitleFontName 923 | pop_macset_ws($sheet) 924 | } 925 | 926 | function pop_macset_ws($sheet){ 927 | 928 | # Grab MACSets and populate 929 | $row=3 930 | $macset = get-nsxmacset 931 | foreach ($mac in $macset) { 932 | 933 | $sheet.Cells.Item($row,1) = $mac.name 934 | $sheet.Cells.Item($row,2) = $mac.value 935 | if(!$mac.description){ 936 | $sheet.Cells.Item($row,3) = $valueNotDefined 937 | } 938 | else {$sheet.Cells.Item($row,3) = $mac.description} 939 | 940 | $row++ # Increment Rows 941 | } 942 | } 943 | 944 | ######################################################## 945 | # Services Worksheet 946 | ######################################################## 947 | 948 | function services_ws($sheet){ 949 | 950 | $sheet.Cells.Item(1,1) = "DFW Services Configuration" 951 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 952 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 953 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 954 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 955 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 956 | $range1 = $sheet.Range("a1", "f1") 957 | $range1.merge() | Out-Null 958 | 959 | $sheet.Cells.Item(2,1) = "Name" 960 | $sheet.Cells.Item(2,2) = "Type" 961 | $sheet.Cells.Item(2,3) = "Application Protocol" 962 | $sheet.Cells.Item(2,4) = "Value" 963 | $sheet.Cells.Item(2,5) = "Universal" 964 | $sheet.Cells.Item(2,6) = "Object-ID" 965 | $range2 = $sheet.Range("a2", "f2") 966 | $range2.Font.Bold = $subTitleFontBold 967 | $range2.Interior.ColorIndex = $subTitleInteriorColor 968 | $range2.Font.Name = $subTitleFontName 969 | pop_services_ws($sheet) 970 | } 971 | 972 | function pop_services_ws($sheet){ 973 | 974 | # Grab Services and populate 975 | $row=3 976 | $services = get-nsxservice -scopeID 'globalroot-0' 977 | foreach ($svc in $services) { 978 | 979 | $sheet.Cells.Item($row,1) = $svc.name 980 | $sheet.Cells.Item($row,2) = $svc.type.typeName 981 | $sheet.Cells.Item($row,3) = $svc.element.applicationProtocol 982 | $sheet.Cells.Item($row,4).NumberFormat = "@" 983 | $sheet.Cells.Item($row,4) = $svc.element.value 984 | $sheet.Cells.Item($row,5) = $svc.isUniversal 985 | $sheet.Cells.Item($row,6) = $svc.objectID 986 | try 987 | { 988 | $link_ref = "Services!" + ($sheet.Cells.Item($row,1)).address($false,$false) 989 | if($services_ht.ContainsKey($svc.objectID) -eq $false) 990 | { 991 | $services_ht.Add($svc.objectID, $link_ref) 992 | } 993 | } 994 | catch [Exception]{ 995 | Write-Warning $svc.objectID + "already exists, manually create hyperlink reference" 996 | } 997 | 998 | $row++ # Increment Rows 999 | } 1000 | 1001 | $services_unv = get-nsxservice -scopeID 'universalroot-0' 1002 | foreach ($svc in $services_unv) { 1003 | 1004 | $sheet.Cells.Item($row,1) = $svc.name 1005 | $sheet.Cells.Item($row,2) = $svc.type.typeName 1006 | $sheet.Cells.Item($row,3) = $svc.element.applicationProtocol 1007 | $sheet.Cells.Item($row,4).NumberFormat = "@" 1008 | $sheet.Cells.Item($row,4) = $svc.element.value 1009 | $sheet.Cells.Item($row,5) = $svc.isUniversal 1010 | $sheet.Cells.Item($row,6) = $svc.objectID 1011 | try 1012 | { 1013 | $link_ref = "Services!" + ($sheet.Cells.Item($row,1)).address($false,$false) 1014 | if($services_ht.ContainsKey($svc.objectID) -eq $false) 1015 | { 1016 | $services_ht.Add($svc.objectID, $link_ref) 1017 | } 1018 | } 1019 | catch [Exception]{ 1020 | Write-Warning $svc.objectID + "already exists, manually create hyperlink reference" 1021 | } 1022 | 1023 | $row++ # Increment Rows 1024 | } 1025 | } 1026 | 1027 | ######################################################## 1028 | # Service Groups Worksheet 1029 | ######################################################## 1030 | 1031 | function service_groups_ws($sheet){ 1032 | 1033 | $sheet.Cells.Item(1,1) = "Service Group Configuration" 1034 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 1035 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 1036 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 1037 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 1038 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 1039 | $range1 = $sheet.Range("a1", "f1") 1040 | $range1.merge() | Out-Null 1041 | 1042 | $sheet.Cells.Item(2,1) = "Service Group Name" 1043 | $sheet.Cells.Item(2,2) = "Universal" 1044 | $sheet.Cells.Item(2,3) = "Scope" 1045 | $sheet.Cells.Item(2,4) = "Service Members" 1046 | $sheet.Cells.Item(2,5) = "Object-ID" 1047 | $range2 = $sheet.Range("a2", "e2") 1048 | $range2.Font.Bold = $subTitleFontBold 1049 | $range2.Interior.ColorIndex = $subTitleInteriorColor 1050 | $range2.Font.Name = $subTitleFontName 1051 | pop_service_groups_ws($sheet) 1052 | } 1053 | 1054 | function pop_service_groups_ws($sheet){ 1055 | 1056 | $row=3 1057 | $SG = Get-NSXServiceGroup -scopeID 'globalroot-0' 1058 | 1059 | foreach ($svc_mem in $SG) 1060 | { 1061 | $sheet.Cells.Item($row,1) = $svc_mem.name 1062 | $sheet.Cells.Item($row,1).Font.Bold = $true 1063 | $sheet.Cells.Item($row,2) = $svc_mem.isUniversal 1064 | $sheet.Cells.Item($row,3) = $svc_mem.scope.name 1065 | $sheet.Cells.Item($row,5) = $svc_mem.objectId 1066 | 1067 | try 1068 | { 1069 | $link_ref = "Service_Groups!" + ($sheet.Cells.Item($row,1)).address($false,$false) 1070 | if($services_ht.ContainsKey($svc_mem.objectID) -eq $false) 1071 | { 1072 | $services_ht.Add($svc_mem.objectID, $link_ref) 1073 | } 1074 | } 1075 | catch [Exception]{ 1076 | Write-Warning $svc_mem.objectID + "already exists, manually create hyperlink reference" 1077 | } 1078 | 1079 | if (!$svc_mem.member) 1080 | { 1081 | $row++ # Increment Rows 1082 | } 1083 | else 1084 | { 1085 | foreach ($member in $svc_mem.member) 1086 | { 1087 | $result = $services_ht[$member.objectid] 1088 | if([string]::IsNullOrWhiteSpace($result)) 1089 | { 1090 | $sheet.Cells.Item($row,4) = $member.name 1091 | $row++ # Increment Rows 1092 | } 1093 | else 1094 | { 1095 | $link = $sheet.Hyperlinks.Add( 1096 | $sheet.Cells.Item($row,4), 1097 | "", 1098 | $result, 1099 | $member.objectid, 1100 | $member.name) 1101 | $row++ # Increment Rows 1102 | } 1103 | } 1104 | } 1105 | } 1106 | 1107 | $SGU = Get-NSXServiceGroup -scopeID 'universalroot-0' 1108 | 1109 | foreach ($svc_mem in $SGU) 1110 | { 1111 | $sheet.Cells.Item($row,1) = $svc_mem.name 1112 | $sheet.Cells.Item($row,1).Font.Bold = $true 1113 | $sheet.Cells.Item($row,2) = $svc_mem.isUniversal 1114 | $sheet.Cells.Item($row,3) = $svc_mem.scope.name 1115 | $sheet.Cells.Item($row,5) = $svc_mem.objectId 1116 | 1117 | try 1118 | { 1119 | $link_ref = "Service_Groups!" + ($sheet.Cells.Item($row,1)).address($false,$false) 1120 | if($services_ht.ContainsKey($svc_mem.objectID) -eq $false) 1121 | { 1122 | $services_ht.Add($svc_mem.objectID, $link_ref) 1123 | } 1124 | } 1125 | catch [Exception]{ 1126 | Write-Warning $svc_mem.objectID + "already exists, manually create hyper link reference" 1127 | } 1128 | 1129 | if (!$svc_mem.member) 1130 | { 1131 | $row++ # Increment Rows 1132 | } 1133 | else 1134 | { 1135 | foreach ($member in $svc_mem.member) 1136 | { 1137 | $result = $services_ht[$member.objectid] 1138 | if([string]::IsNullOrWhiteSpace($result)) 1139 | { 1140 | $sheet.Cells.Item($row,4) = $member.name 1141 | $row++ # Increment Rows 1142 | } 1143 | else 1144 | { 1145 | $link = $sheet.Hyperlinks.Add( 1146 | $sheet.Cells.Item($row,4), 1147 | "", 1148 | $result, 1149 | $member.objectid, 1150 | $member.name) 1151 | $row++ # Increment Rows 1152 | } 1153 | } 1154 | } 1155 | } 1156 | } 1157 | 1158 | ######################################################## 1159 | # Security Tag Worksheet 1160 | ######################################################## 1161 | 1162 | function sec_tags_ws($sheet){ 1163 | 1164 | $sheet.Cells.Item(1,1) = "Security Tag Configuration" 1165 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 1166 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 1167 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 1168 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 1169 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 1170 | $range1 = $sheet.Range("a1", "f1") 1171 | $range1.merge() | Out-Null 1172 | 1173 | $sheet.Cells.Item(2,1) = "Security Tag Name" 1174 | $sheet.Cells.Item(2,2) = "Built-In" 1175 | $sheet.Cells.Item(2,3) = "VM Members" 1176 | $sheet.Cells.Item(2,4) = "Is Universal" 1177 | $range2 = $sheet.Range("a2", "d2") 1178 | $range2.Font.Bold = $subTitleFontBold 1179 | $range2.Interior.ColorIndex = $subTitleInteriorColor 1180 | $range2.Font.Name = $subTitleFontName 1181 | pop_sec_tags_ws($sheet) 1182 | } 1183 | 1184 | function pop_sec_tags_ws($sheet){ 1185 | 1186 | $row=3 1187 | $ST = get-nsxsecuritytag -includesystem 1188 | 1189 | foreach ($tag in $ST) { 1190 | $sheet.Cells.Item($row,1) = $tag.name 1191 | $sheet.Cells.Item($row,2) = $tag.systemResource 1192 | $sheet.Cells.Item($row,3) = $tag.vmCount 1193 | $sheet.Cells.Item($row,4) = $tag.isUniversal 1194 | $row++ # Increment Rows 1195 | } 1196 | 1197 | $sheet.Cells.Item($row,1) = "Security Tag Name" 1198 | $sheet.Cells.Item($row,2) = "VM Name" 1199 | $range3 = $sheet.Range("a"+$row, "b"+$row) 1200 | $range3.Font.Bold = $subTitleFontBold 1201 | $range3.Interior.ColorIndex = $subTitleInteriorColor 1202 | $range3.Font.Name = $subTitleFontName 1203 | 1204 | $row ++ 1205 | 1206 | # Traverse VM membership and populate spreadsheet 1207 | if ($collect_vm_stag_members -eq "y") { 1208 | 1209 | # Retrieve a list of all Tag Assignments 1210 | $tag_assign = $ST | Get-NsxSecurityTagAssignment 1211 | 1212 | foreach ($mem in $tag_assign){ 1213 | 1214 | $sheet.Cells.Item($row,1) = $mem.SecurityTag.name 1215 | $sheet.Cells.Item($row,2) = $mem.VirtualMachine.name 1216 | $row++ 1217 | } 1218 | } 1219 | else { 1220 | $sheet.Cells.Item($row,1) = "" 1221 | $sheet.Cells.Item($row,1).Font.ColorIndex = 3 1222 | $sheet.Cells.Item($row,2) = "" 1223 | $sheet.Cells.Item($row,2).Font.ColorIndex = 3 1224 | } 1225 | } 1226 | 1227 | ######################################################## 1228 | # Exclusion list Worksheet 1229 | ######################################################## 1230 | 1231 | function ex_list_ws($sheet){ 1232 | 1233 | $sheet.Cells.Item(1,1) = "Exclusion List" 1234 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 1235 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 1236 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 1237 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 1238 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 1239 | $range1 = $sheet.Range("a1", "f1") 1240 | $range1.merge() | Out-Null 1241 | 1242 | $sheet.Cells.Item(2,1) = "VM Name" 1243 | $sheet.Cells.Item(2,2) = "VM ID" 1244 | $range2 = $sheet.Range("a2", "b2") 1245 | $range2.Font.Bold = $subTitleFontBold 1246 | $range2.Interior.ColorIndex = $subTitleInteriorColor 1247 | $range2.Font.Name = $subTitleFontName 1248 | pop_ex_list_ws($sheet) 1249 | } 1250 | 1251 | function pop_ex_list_ws($sheet){ 1252 | 1253 | $row=3 1254 | $guests = Get-NsxFirewallExclusionListMember 1255 | 1256 | foreach ($vm in $guests) { 1257 | # $sheet.Cells.Item($row,1) = $vm.name 1258 | $result = $vmaddressing_ht[$vm.id.TrimStart("VirtualMachine-")] 1259 | if([string]::IsNullOrWhiteSpace($result)) 1260 | { 1261 | $sheet.Cells.Item($row,1) = $vm.name 1262 | $sheet.Cells.Item($row,2) = $vm.id.TrimStart("VirtualMachine-") 1263 | } 1264 | else 1265 | { 1266 | $link = $sheet.Hyperlinks.Add( 1267 | $sheet.Cells.Item($row,1), 1268 | "", 1269 | $result, 1270 | "Virtual Machine Information", 1271 | $vm.name) 1272 | $sheet.Cells.Item($row,2) = $vm.id.TrimStart("VirtualMachine-") 1273 | } 1274 | $row++ # Increment Rows 1275 | } 1276 | } 1277 | 1278 | ######################################################## 1279 | # VM Addressing - First NIC IP Address 1280 | ######################################################## 1281 | 1282 | function vm_ip_addresses_ws($sheet){ 1283 | 1284 | $sheet.Cells.Item(1,1) = "Virtual Machine Addressing" 1285 | $sheet.Cells.Item(1,1).Font.Size = $titleFontSize 1286 | $sheet.Cells.Item(1,1).Font.Bold = $titleFontBold 1287 | $sheet.Cells.Item(1,1).Font.ColorIndex = $titleFontColorIndex 1288 | $sheet.Cells.Item(1,1).Font.Name = $titleFontName 1289 | $sheet.Cells.Item(1,1).Interior.ColorIndex = $titleInteriorColor 1290 | $range1 = $sheet.Range("a1", "f1") 1291 | $range1.merge() | Out-Null 1292 | 1293 | $sheet.Cells.Item(2,1) = "VM Name" 1294 | $sheet.Cells.Item(2,2) = "Guest IP Address" 1295 | $sheet.Cells.Item(2,3) = "VM ID" 1296 | $range2 = $sheet.Range("a2", "c2") 1297 | $range2.Font.Bold = $subTitleFontBold 1298 | $range2.Interior.ColorIndex = $subTitleInteriorColor 1299 | $range2.Font.Name = $subTitleFontName 1300 | pop_ip_address_ws($sheet) 1301 | } 1302 | 1303 | function pop_ip_address_ws($sheet){ 1304 | 1305 | $row=3 1306 | $guests = Get-VM | Select Name, VMIPAddress, id 1307 | 1308 | foreach ($vm in $guests) { 1309 | $sheet.Cells.Item($row,1) = $vm.name 1310 | $sheet.Cells.Item($row,2) = $vm.VMIPAddress 1311 | $vm_id = $vm.id.TrimStart("VirtualMachine-") 1312 | $sheet.Cells.Item($row,3) = $vm_id 1313 | try 1314 | { 1315 | $link_ref = "VM_Info!" + ($sheet.Cells.Item($row,1)).address($false,$false) 1316 | if($vmaddressing_ht.ContainsKey($vm_id) -eq $false) 1317 | { 1318 | $vmaddressing_ht.Add($vm_id, $link_ref) 1319 | } 1320 | } 1321 | catch [Exception]{ 1322 | Write-Warning "already exists, manually create hyperlink reference" 1323 | } 1324 | 1325 | $row++ # Increment Rows 1326 | } 1327 | } 1328 | 1329 | ######################################################## 1330 | # Global Functions 1331 | ######################################################## 1332 | 1333 | If (-not $DefaultNSXConnection) 1334 | { 1335 | Write-Warning "`nConnect to NSX Manager and vCenter Server needs to be established" 1336 | $nsx_mgr = Read-Host "`nIP or FQDN of NSX Manager? " 1337 | Connect-NSXServer -NSXServer $nsx_mgr 1338 | } 1339 | 1340 | $version = Get-NsxManagerSystemSummary 1341 | $major_version = $version.versionInfo.majorVersion 1342 | 1343 | # Only tested to run on NSX 6.2.x & 6.3.x installations 1344 | 1345 | if($major_version -eq 6){ 1346 | 1347 | if ( $EnableIpDetection ) { 1348 | $collect_vm_ips = "y" 1349 | Write-Host "Collection of IP Addresses Enabled" 1350 | } 1351 | elseif (-not $PSBoundParameters.ContainsKey("EnableIpDetection")) { 1352 | $collect_vm_ips = "n" 1353 | Write-Warning "Collection of IP Addresses Disabled" 1354 | } 1355 | 1356 | if ( $GetSecTagMembers ) { 1357 | $collect_vm_stag_members= "y" 1358 | Write-Host "Collection of Security Tag VM Membership Enabled" 1359 | } 1360 | elseif (-not $PSBoundParameters.ContainsKey("GetSecTagMembers")) { 1361 | $collect_vm_stag_members = "n" 1362 | Write-Warning "Collection of Security Tag VM Membership Disabled" 1363 | } 1364 | 1365 | if ( $GetSecGrpMembers ) { 1366 | $collect_vm_members = "y" 1367 | Write-Host "Collection of Security Group VM Membership Enabled" 1368 | } 1369 | elseif (-not $PSBoundParameters.ContainsKey("GetSecGrpMembers")) { 1370 | $collect_vm_members = "n" 1371 | Write-Warning "Collection of Security Group VM Membership Disabled" 1372 | } 1373 | 1374 | if ($collect_vm_ips -eq "y") { 1375 | # Write-Host "Collection of IP Addresses Enabled" 1376 | startExcel("y") 1377 | } 1378 | else{ 1379 | # Write-Warning "Collection of IP Addresses Disabled" 1380 | startExcel("n") 1381 | } 1382 | } 1383 | else{ 1384 | Write-Warning "`nNSX Manager version is not in the NSX 6.x release train" 1385 | } 1386 | -------------------------------------------------------------------------------- /DFW2Excel_Workbook_Example.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonysangha/PowerNSX-DFW2Excel/27a5767fa94d3b3d0c9749308d718615a3fe7725/DFW2Excel_Workbook_Example.xlsx -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) [2016] [Tony Sangha] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Document NSX-v DFW with PowerNSX 2 | 3 | ### Note: Script is now part of the [NSX-PowerOps](https://github.com/vmware/nsx-powerops) toolset! NSX-PowerOps will now be the main repository for issues and new features for this tool. Current as of 21st November 2017 4 | 5 | Script connects to NSX Manager and vCenter using the Powershell/Powercli 6 | to download and create an MS Excel spreadsheet with your firewall configurations. 7 | 8 | ** Only works for Layer 3 DFW Policy 9 | 10 | Pre-requisites to run the script are: 11 | 12 | * [VMware PowerCLI](https://www.vmware.com/support/developer/PowerCLI/) 13 | * [VMware PowerNSX](https://github.com/vmware/powernsx) 14 | * [Microsoft Excel](https://products.office.com/en-au/excel) installed on the local system 15 | * Access to NSX Manager API with privileges 16 | * Access to vSphere Web Client and Privileges (Read) 17 | 18 | To run the script, make sure your Powershell Execution is set to *remotesigned* 19 | 20 | ``` Powershell 21 | Set-ExecutionPolicy remotesigned 22 | ``` 23 | 24 | PowerNSX is essential, therefore please ensure you have the latest supported version of PowerNSX installed, 25 | which can be installed in an administrative PowerShell terminal from the [PowerShell Gallery](https://www.powershellgallery.com/packages/PowerNSX/3.0.1047) 26 | 27 | ```Powershell 28 | Install-Module -Name PowerNSX 29 | ``` 30 | The script has been tested against version **3.0.1047**, support for other PowerNSX versions is not tested. 31 | 32 | To verify what PowerNSX version you have running execute the command: 33 | 34 | ```Powershell 35 | Get-PowerNsxVersion 36 | 37 | Version Path Author CompanyName 38 | ------- ---- ------ ----------- 39 | 3.0.1047 C:\Users\Tony\Documents\WindowsPowerShell\Modules\powernsx\PowerNSX.psm1 Nick Bradford VMware 40 | ``` 41 | 42 | To execute the script, download it to your scripts folder and change into the folder from the PowerShell CLI 43 | terminal and execute the command: 44 | 45 | ``` Powershell 46 | .\DFW2Excel.ps1 47 | ``` 48 | 49 | By default the script will look for an active connection to NSX Manager, if none is present, the user will be prompted to connect to NSX Manager and vCenter Server. In addition, several parameters can be used to collect additional information, which are: 50 | 51 | * `-EnableIPDetection` Collect IP Addresses for Virtual Machines 52 | * `-GetSecTagMembers` Collect Security Tag VM Membership 53 | * `-GetSecGrpMembers` Collect Security Group VM Membership 54 | * `-StartMinimised` Microsoft Excel will not be visible to user 55 | * `-DocumentPath` Local path to save excel file 56 | 57 | If any of the parameters are **omitted** during execution, the script will default to false and no collection will be conducted! 58 | 59 | Below an example of using all these parameters together: 60 | 61 | ```Powershell 62 | .\DFW2Excel.ps1 -StartMinimised -EnableIPDetection -GetSecTagMembers -GetSecGrpMembers -DocumentPath c:\dfwconfig.xlsx 63 | ``` 64 | 65 | You are prompted to connect to an NSX Manager instance and enter your credentials, and PowerNSX also initiates a connection to vCenter. Please ensure you select yes and enter in the correct credentials. 66 | Once a connection to NSX Manager and vCenter has been established, the script starts an Excel Workbook and populates the worksheets with the data as required. 67 | 68 | Once the script has finished running, remember to save your Excel Workbook to a location of your choosing. 69 | 70 | ### Release Notes 71 | 72 | Version 1.0.1 73 | 74 | Release Date: **21/11/2017** 75 | 76 | * Added prompt to check if user wants to get VM Security Group & Tag Membership 77 | * Rudimentary validation check of yes/no prompt added 78 | * Added new worksheet titled _Environment Summary_ 79 | * Security Group Statistics included to resolve issue: #19 80 | * Used PowerOps Excel COM object clean-up code for script 81 | * Switch parameters included to start script: `-EnableIpDetection` `-GetSecTagMembers` `-GetSecGrpMembers` -`StartMinimised` `-DocumentPath` 82 | 83 | Version 1.0.0 84 | 85 | Release Date: **08/10/2017** 86 | 87 | * Hyperlink Support in FW Rule sheet to: VMs, IPSets, Services, Security Groups 88 | * Sample output file updated 89 | 90 | Version 0.9.2 91 | 92 | Release Date: **06/10/2017** 93 | 94 | * If Service Field is not a NSX Object, output raw `Protocol/Port` into Cell 95 | * Collasped hash table for local/universal services into a single table - as it's now using objectID for unique field 96 | 97 | Version 0.9.1 98 | 99 | Release Date: **06/10/2017** 100 | 101 | * New Column - object-ids added to service and service group tabs. 102 | * Instead of using service names, using object-id's instead for hashtable to build hyperlink 103 | * For Service Group Hyperlinks, provide tooltip which is object-id 104 | * Hyperlink from Exclusion List VMs & Sec Grp VMs to VM_Info sheet 105 | 106 | Version 0.9 107 | 108 | Release Date: **06/10/2017** 109 | 110 | * If `$NSXDefaultConnection` exists, do not prompt for a new NSX Manager connection 111 | * When retrieving objects, specify scope - do not rely on defaults 112 | * [New Feature] - Hyperlinks from Service Groups to Services 113 | 114 | Version 0.8 115 | 116 | Release Date: **06/05/2017** 117 | 118 | * Resolved Issue 12 - _Error with $svc.name DFW2Excel.ps1:540 char:9_ 119 | * PowerNSX enhancements to universal object handling incorporated into script 120 | * Changed VM IP Address lookup to use Extension Data from `get-vm` cmdlet 121 | 122 | Version 0.6/0.7 123 | 124 | Release Date: **1/04/2017** 125 | 126 | * Remove Minor version check of NSX Manager 127 | * remove hard-coded string `admin` from credentials request 128 | 129 | Version 0.5 130 | 131 | Release Date: **09/02/2017** 132 | 133 | * Fixed issue #7 - Needed to format value as text of cell 134 | 135 | Version 0.4 136 | 137 | Release Date: **24/11/2016** 138 | 139 | * Document VM IP Addresses into worksheet 140 | * Document static membership of VMs in Security Groups 141 | * Add warning text and simple error checks to start script 142 | 143 | Version 0.3 144 | 145 | Release Date: **28/10/2016** 146 | 147 | * Object-ID for destination and source fields added to Layer 3 Firewall worksheet 148 | 149 | Version 0.2 150 | 151 | Release Date: **21/10/2016** 152 | 153 | * Fixed Casting errors that were displayed on console 154 | * Implemented version check 155 | * New worksheet to document Security Tags and VM Membership 156 | * Negated Field in L3 Policy is now documented 157 | * DFW Exclusion List 158 | 159 | # MIT License 160 | 161 | Copyright (c) [2016] [Tony Sangha] 162 | 163 | Permission is hereby granted, free of charge, to any person obtaining a copy 164 | of this software and associated documentation files (the "Software"), to deal 165 | in the Software without restriction, including without limitation the rights 166 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 167 | copies of the Software, and to permit persons to whom the Software is 168 | furnished to do so, subject to the following conditions: 169 | 170 | The above copyright notice and this permission notice shall be included in all 171 | copies or substantial portions of the Software. 172 | 173 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 174 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 175 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 176 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 177 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 178 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 179 | SOFTWARE. 180 | --------------------------------------------------------------------------------