param( [string[]]$ClassNames, [switch]$Help ) if (-not $ClassNames -and -not $help){ Write-Error "Необходимо указать параметр $ClassNames" $Help = $true } if ($help){ Write-Host "SCOM MP Class Visualizer script, version 0.2" Write-Host "http://gexeg.blogspot.com" Write-Host "Параметры: " Write-Host " -Help : вывод справочной информации " Write-Host " -ClassNames <[string[]]> : необходимо указать массив классов," Write-Host " по которым будет строиться дерево классов`n" Write-Host "Примеры использования:" Write-Host "1) .\SCOMDrawClassTree.ps1 -ClassNames ""Microsoft.Windows.Server.2008.AD.DomainControllerRole"", ""Microsoft.Windows.Server.2008.AD.DC.KDC""" Write-Host "`n2) .\SCOMDrawClassTree.ps1 -ClassNames ""Microsoft.Windows.Server.2008.AD.DomainControllerRole""" Write-Host "`n3) `$classNames = Get-SCOMClass -ManagementPack (Get-ScomManagementPack -Name ""Microsoft.Windows.Server.AD.Library"") | foreach {`$_.Name}" Write-Host " .\SCOMDrawClassTree.ps1 -ClassNames `$classNames" exit } if (-not (Get-Module OperationsManager)){ Import-Module OperationsManager } [hashtable]$classes = @{} [hashtable]$shapes = @{} #Const VisSectionIndices $visSectionObject = 1 $visSectionParagraph = 4 $visSectionProp = 243 #Const VisRowIndices $visRowXFormOut = 1 $visRowTextXForm = 12 $visRowPageLayout = 24 $visRowLast = -2 $visRowFill = 3 #Const $visXFormPinX = 0 $visXFormPinY = 1 $visXFormWidth = 2 $visPLOPlaceStyle = 8 $visPLORouteStyle = 9 $visPLOLineRouteExt = 29 $visCustPropsLabel = 2 $visCustPropsType = 5 $visCustPropsValue = 0 $visFillForegnd = 0 $visFillBkgnd = 1 $visTagDefault = 0 $visLayoutIncrSpace = 2 $visLayoutHorzAlignNone = 0 $visLayoutVertAlignNone = 0 $visMillimeters = 70 function VisioResizeShape($shape){ $shape.CellsSRC($visSectionObject, $visRowXFormOut, 2).FormulaU = "10 mm" $shape.CellsSRC($visSectionObject, $visRowXFormOut, 3).FormulaU = "10 mm" } function VisioSetConStyle($con){ $con.CellsSRC($visSectionObject,2,0).FormulaU = "0.25 pt" $con.CellsSRC($visSectionObject,23,19).FormulaU = "0" } function VisioSetText($shape, $text){ $chars = $shape.Characters $chars.Begin = 0 $chars.Begin = 0 $chars.Text = $text $shape.CellsSRC($visSectionObject,11,4).FormulaU = "0" $shape.CellsSRC($visSectionParagraph,0,6).FormulaU = "0" $shape.CellsSRC($visSectionObject,$visRowTextXForm,$visXFormWidth).FormulaU = "5" $shape.CellsSRC($visSectionObject,$visRowTextXForm,$visXFormPinX).FormulaU = "3" #$shape.CellsSRC($visSectionObject,$visRowTextXForm,$visXFormPinY).FormulaU = "Height*0.5" #$shape.CellsSRC($visSectionObject,$visRowTextXForm, 4).FormulaU = "-1" #$shape.CellsSRC($visSectionObject,$visRowTextXForm, 5).FormulaU = "TxtHeight*2" } function VisioAddDataRow($shape, $Name, $Value){ $row = $shape.AddRow($visSectionProp, $visRowLast, $visTagDefault) $shape.CellsSRC($visSectionProp, $row, $visCustPropsLabel).FormulaU = """$Name""" $shape.CellsSRC($visSectionProp, $row, $visCustPropsType).FormulaU = "0" $shape.CellsSRC($visSectionProp, $row, $visCustPropsValue).FormulaU = """$Value""" } function VisioRearIcons(){ $page.PageSheet.CellsSRC($visSectionObject, $visRowPageLayout, $visPLOPlaceStyle).FormulaForceU = "7" $page.PageSheet.CellsSRC($visSectionObject, $visRowPageLayout, $visPLORouteStyle).FormulaForceU = "3" $page.Layout() $visio.ActiveWindow.SelectAll() $visio.ActiveWindow.Selection.LayoutIncremental($visLayoutIncrSpace, $visLayoutHorzAlignNone, $visLayoutVertAlignNone, 70, 8, $visMillimeters) $page.Shapes.ItemFromID(0).CellsSRC($visSectionObject, $visRowPageLayout, $visPLOLineRouteExt).FormulaU = "2" } function PopulateClassTree($ClassID){ while ($ClassID){ $obj = Get-SCOMClass -Id $ClassID if ($obj){ $ClassID = $obj.Base.Id $obj | add-member -Name ParentID -MemberType NoteProperty -Value $ClassID $classes[$obj.Id] = $obj if (-not $ClassID){ break } } } } function PopulateAttr($Shape, $ClassObj){ VisioAddDataRow -shape $Shape -Name "::::::::Class Properties::::" -Value ":::::::::::::::" VisioAddDataRow -shape $Shape -Name "Abstract" -Value $classObj.Abstract VisioAddDataRow -shape $Shape -Name "Accessibility" -Value $classObj.Accessibility VisioAddDataRow -shape $Shape -Name "Extension" -Value $classObj.Extension VisioAddDataRow -shape $Shape -Name "Hosted" -Value $classObj.Hosted VisioAddDataRow -shape $Shape -Name "Singleton" -Value $classObj.Singleton VisioAddDataRow -shape $Shape -Name "Description" -Value $classObj.Description if ($ClassObj.PropertyCollection.Count -gt 0){ VisioAddDataRow -shape $Shape -Name "::::::::Attributes::::" -Value ":::::::::::::::" $ClassObj.PropertyCollection | sort Name | foreach { if ($_.Key -eq $true) { $isKey = "Key" } else { $isKey=$null } if ($_.Required -eq $true) { $Required = "Mandatory" } else { $Required = "Optional"} $propVal = [string]::Join(",", @($_.SystemType, "Min: $($_.MinLength)", "Max: $($_.MaxLength)", $Required, $isKey)) VisioAddDataRow -shape $Shape -Name $_.Name -Value $propVal } } } function PopulateBaseAttr($shape, $classObj){ if ($classObj.ParentID){ $attribs = @() while($classObj.ParentID){ $classObj = $classes[$classObj.ParentID] if ($ClassObj.PropertyCollection.Count -gt 0){ VisioAddDataRow -shape $Shape -Name ":::$($ClassObj.Name)::" -Value ":Attributes::::" $ClassObj.PropertyCollection | sort Name | foreach { if ($_.Key -eq $true) { $isKey = "Key" } else { $isKey=$null } if ($_.Required -eq $true) { $Required = "Mandatory" } else { $Required = "Optional"} $propVal = [string]::Join(",", @($_.SystemType, "Min: $($_.MinLength)", "Max: $($_.MaxLength)", $Required, $isKey)) VisioAddDataRow -shape $Shape -Name $_.Name -Value $propVal } } } } } $initVisio = { Write-Host "Создание приложения Visio" $visio = New-Object -ComObject Visio.Application $visio.Visible = $false $visio.Documents.Add("BASICD_M.VST") | Out-Null $doc = $visio.Documents.Item(1) $page = $doc.Pages.Item(1) $Stensils = $visio.Documents.Item("BASIC_M.VSS") $pentagon = $Stensils.Masters.ItemU("Pentagon") $dyncon = $Stensils.Masters.ItemU("Dynamic connector") } $unInitVisio = { $visio.Visible = $true Write-Host "Переключитесь в Visio и сохраните сформированный документ." $visio.quit() $page = $null $doc = $null $visio = $null } . $initVisio foreach ($className in $ClassNames){ Write-Host "Обрабатываем класс $className" $classObj = Get-SCOMClass -Name $className Write-Host "Заполняем дерево классов" PopulateClassTree -ClassID $classObj.ID } Write-Host "Отрисовка объектов" $classes.Keys | foreach { $shape = $page.Drop($pentagon, 1,1) $shape.Name = $classes[$_].Name if ($classes[$_].Singleton -eq $true){ $shape.CellsSRC($visSectionObject, $visRowFill, $visFillBkgnd).FormulaU = "THEMEGUARD(MSOTINT(THEME(""LineColor""),80))" } elseif ($classes[$_].Abstract -eq $false){ $shape.CellsSRC($visSectionObject, $visRowFill, $visFillBkgnd).FormulaU = "THEMEGUARD(MSOTINT(THEME(""AccentColor4""),40))" } VisioResizeShape -shape $shape VisioSetText -shape $shape -text ("$($classes[$_].Name)`n$($classes[$_].DisplayName)`n$($classes[$_].ManagementPackName)") PopulateAttr -shape $shape -ClassObj $classes[$_] PopulateBaseAttr -shape $shape -ClassObj $classes[$_] $shapes[$_] = $shape } foreach ($class in $classes.Keys){ if (-not $classes[$class].ParentID){ continue } $con = $page.Drop($dyncon, 1,1) $shapeTo = $shapes[$class] $shapeFrom = $shapes[$classes[$class].ParentID] $con.CellsU("BeginX").GlueTo($shapeFrom.CellsSRC(7,0,0)) $con.CellsU("EndX").GlueTo($shapeTo.CellsSRC(7,5,0)) VisioSetConStyle -con $con } VisioRearIcons Write-Host "Отрисовка объектов закончена" . $unInitVisio