SCSM 2012 R2 With Powershell – HTML Base Chart Report – Part 8

By | 14 January 2016

Şu ana kadar powershell ile scsm mimarisinde yapabileceklerinizi adım adım anlatmıştım. Ama henüz yapabileceklerinizi bitirmiş değilim J Söz konusu powershell olduğu zaman sınırlarınızı en yüksek seviyeye kadar zorlayabilirsiniz.

mk.3

Günümüzde elde edilen verilerin sağlıklı biçimde sunulması ve bu sunumun grafikler ile desteklenmesi iş ortamlarında oldukça talep görmektedir. Bu işler için BI araçları, reporting service’ler üzerilerine düşen görevi oldukça iyi şekilde yerine getirebilmektedir. Fakat bunları powershell ile yapmak isterseniz onunda çözümü mevcutJ

Fazla uzatmadan anlatmak istediğimi açıklayarak devam edeyim. Powershell ile zaten veriyi CMDB’den çekip HTML tablo üzerinde sunabiliyorduk. Ancak verinin grafik olarak sayısal değerler ile gösterilmesi için biraz daha işlenmesi gerekiyor. Sayısal veri elde edildikten sonra MSchart kütüphanesi kullanılarak elde edilen veriye ilişkin grafiksek tablolar kolaylıkla oluşturulabilir. Burada önemli olan kısım sayısal veriyi oluşturmaktır.

İşlemlere başlamadan önce aşağıdaki link üzerinden MSChart kütüphanesini indirip işlem yapacağınız makineye yüklemeniz gerekiyor.

https://www.microsoft.com/en-US/download/details.aspx?id=14422

Kurulum öncesinde makine üzerinde .Net framework 3.5 bileşeninin kurulu olması gerekmektedir. Zaten .net 3.5 kurulu değilse kurulum wizard’ı buna ilişkin uyarıyı verecektir.

Kurulumun ardından işlemlere başlayabiliriz.

Öncelikle yapmak istediğim şey aşağıdaki örnekte görüleceği gibi belli bir tarihten sonra oluşturulmuş olay kayıtlarını elde edip bu olay kayıtları içerisinden ne kadarı çözümlenmiş, çözümlenenlerden ne kadarı SLA’e uymuş , ne kadarı SLA’e uymamış grafik halinde ve HTML tablo olarak göstermek.

Scripti düzgün şekilde yapılandırıldığı taktirde aşağıdaki gibi bir sonucu elde edeceğiz.

mk1.pics

Resmi Prod ortamından örnek aldığım için support group isimleri gibi belli kısımlarını karaladım.

Şimdi scriptimizi yapılandırmaya başlayabiliriz. Yukardaki resmi incelediğinizde işin içinde hem Chart hem de HTML tablo olduğun görebilirsiniz. HTML tabloyu oluştururken daha önce technet gallery’de yayınlanmış fonksiyonları script’imin içerisinde kullandım. Gayet güzel fonksiyonar, sizlerin de kendi script’lerinizde bu fonsiyonlardan faydalanmanızı şiddetle öneririm. Aşağıdaki linkten bu fonksiyonlara ulaşabilirsiniz.

https://gallery.technet.microsoft.com/scriptcenter/PowerShell-HTML-Notificatio-e1c5759d

Bu fonksiyonlara ek olarak MS chart ile ilgili bazı kaynaklardan da faydalandım. Onları da incelemenizi öneririm. İncelemeniz sonrasında kendi chart fonksiyonlarınızı oluşturabilirsiniz. Onun için de aşağıdaki linklerden faydalanabilirsiniz.

https://bytecookie.wordpress.com/2012/04/13/tutorial-powershell-and-microsoft-chart-controls-or-how-to-spice-up-your-reports/

Şimdi yavaş yavaş scriptimizi anlatalım. Öncesince scripti C:\Temp klasöründe çalıştırmanız gerektğini hatırlatayım.İsterseniz script içersinde dizini editleyebilirsiniz.

İlk olarak scriptimizin en üstüne HTML fonksiyonlarını ekleyelim.

mk.2

Bunları ayrıntılı anlatmama gerek yok. Resimde yanlarına açıklamalarını yaptım. Ek olarak yukarıdaki link üzerinden fonksiyonları yazan kişinin ayrıntılı açıklamasına da ulaşabilirsiniz.

Öncelikle değişkenlerimizi tanımlayalım. Diğer makalelerimde ayrıntılı anlatmıştım bu kısımları. Burada farklı olarak SLA relationship class’ını $SLARelClass değişkenine atıyoruz. SLA olay objesi olay objesi ile relationship kurduğu için tıpkı atanan ve ya etklenen kullanıcıyı elde ederken kullandığımız gibi relationship class’lardan faydalanıyoruz.

Hangi günden sonra oluşturulmuş olay kayıtlarını baz almak istiyorsanız $WorkItemCreatedBefore değişkenine uygun değeri dakika olarak atamanız gerekiyor.

#=======================DEĞİŞKENLER===================================

  • import-module smlets -force
  • $WorkItemCreatedBefore = 5040
  • $GetBeforeDate = (get-date).AddMinutes($WorkItemCreatedBefore).ToString(“MM/dd/yyy HH:mm:ss”)
  • $Closed = Get-SCSMEnumeration IncidentStatusEnum.Closed$
  • $Resolved = Get-SCSMEnumeration IncidentStatusEnum.Resolved$
  • $IncidentClass = Get-SCSMClass -Name System.WorkItem.Incident$
  • $GetIncidents = @(Get-SCSMObject -Class $IncidentClass | where {(($_.CreatedDate) -gt $GetBeforeDate)})
  • $smtphost=”mail.frt.com”
  • $TierQueueEnums = Get-SCSMEnumeration IncidentTierQueuesEnum | Get-SCSMChildEnumeration
  • $IncidentsObjs = @()
  • $SLARelClass = Get-SCSMRelationshipClass System.WorkItemHasSLAInstanceInformation
Değişkenlere ek olarak boş bir $HTML değişkeni oluşturmamız gerekiyor. Bunun içinde boş bir değişken oluşturalım. Script’in belli aşamalarında bu değişkene data girişi yapıp en son aşamada değişkeni HTML’e dönüştüreceğiz.
  • $HTML2 = New-HTMLHead -title “Incident details” #HTML Sayfanın
  • Başlığı (Explorer kullanılıyor ise gerekli)$HTML2 += “<h4>Haftalık SLA Raporu</h4>”  #HTML Body kısmındaki ilk başlık.
Daha önceki makalelerimde send email fonkisyonunu kullanmıştım. Burada ona bir kaç ekleme yapmam gerekti. Chart fonksiyonum çıktısını png olarak kayıt ediyor. Bu amaçla maili gönderirken bu png dosyasını attachment olarak eklemem gerekiyor. O amaçla attachment’a ilişkin ilgili satırlarıda send email fonkiyonuma ekledim.
function Send-Mail 
    
        param($From,$To,$Subject,$Body) 
        $smtp = new-object system.net.mail.smtpClient($smtphost) 
        $mail = new-object System.Net.Mail.MailMessage
        #Chart png olarak kayıt edilecek. Kayıt edilen png dosyasını email'e eklemek için dosya ismini ve lokasyonunu belirlemek gerekiyor.
        $attachment = New-Object System.Net.Mail.Attachment –ArgumentList "C:\TEMP\FRTColumnChart.png"
        $attachment.ContentDisposition.Inline = $True
        $attachment.ContentDisposition.DispositionType = "Inline"
        #Attachment Type'ını belirliyoruz.
        $attachment.ContentType.MediaType = "image/png"
        #Attechment content id'sini belirliyoruz.
        $attachment.ContentId = 'FRTColumnChart.png'
        $mail.from = $From 
        $mail.to.add($To) 
        $mail.subject= $Subject 
        $mail.body= $Body
        $mail.isbodyhtml=$true 
        $mail.CC.Add("firat.yasar@bdh.com.tr")
        #Attachment'ı email'e ekliyoruz.
        $mail.Attachments.Add($attachment)
        $smtp.send($mail)
    }
Chart’la ilgili paylaştığım linkte sütun grafiği oluşturma ile ilgili paylaşımlar mevcut. Ancak burada bir grafik içerisinde farklı data serileri oluşturmamız gerekiyor. Yani aynı grafik içerisinde farklı datalara ilişkin sütunların yan yana gözükmesi işleminden bahsediyorum. İnceleyen kişi baktığında belli bir destek grubuna ait toplam, çözümlenmiş, SLA’i karşılanmış ve karşılanmamış olay sayılarını yan yana görebilmeli. Bu amaçla chart oluşturma işlemi için bir fonksiyon oluşturdum. Oluşturduğum bu fonksiyon birden fazla data serisini parametre olarak alıp her biri için ayrı data serileri oluşturabiliyor.
function New-ColumnChart{
   
   param ([PSObject[]]$ChartObjects,$XElement,[String[]]$YElement,$ChartTitle)
   
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
 
# chart Objesi
   $chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart
   $chart1.Width = 850
   $chart1.Height = 500
   $chart1.BackColor = [System.Drawing.Color]::White
   $chart1.BorderWidth = 3
   $chart1.BorderDashStyle = "solid"
   $chart1.BorderColor = "#000000"
 
# Chart Başlığı
   [void]$chart1.Titles.Add($ChartTitle)
   $chart1.Titles[0].Font = "Arial,13pt"
   $chart1.Titles[0].Alignment = "topCenter"
 
# Chart Area'sına ilişkin Konfigürasyonlar
   $chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
   $chartarea.Name = "ChartArea1"
   $chartarea.AxisY.Title = "Incident Count"
   $chartarea.AxisX.Title = "Support Group"
   $chartarea.AxisY.Interval = 20
   $chartarea.AxisX.Interval = 1
   $chart1.ChartAreas.Add($chartarea)
   $chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth=0
   $chart1.ChartAreas[0].AxisY.MajorGrid.LineWidth=0
   
 
# Legend Konfigürasyonu
   $legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend
   $legend.name = "Legend1"
   $chart1.Legends.Add($legend)
 
# Veri Kaynağı
   $datasource = $ChartObjects | sort SLAMetCount -Descending 
  
  foreach ($Y in $YElement)
# Data Serilerinin oluşturulması
{
   $Name = $Y.Split("-")[0]
   [void]$chart1.Series.Add($Name)
   $chart1.Series[$Name].ChartType = "Column"
   $chart1.Series[$Name].BorderWidth  = 6
   $chart1.Series[$Name].IsVisibleInLegend = $true
   $chart1.Series[$Name].chartarea = "ChartArea1"
   $chart1.Series[$Name].Legend = "Legend1"
   $chart1.Series[$Name].color = $Y.Split("-")[1]
   $chart1.Series[$Name].SmartLabelStyle.Enabled = $true
   $chart1.Series[$Name].IsValueShownAsLabel= $true
  
   $chart1.Series[$Name].LabelForeColor = $Y.Split("-")[1]
   
   $datasource | ForEach-Object {$chart1.Series[$Name].Points.addxy($_.$XElement , $_.$Name) }
   
}
# Oluşturulan Chart'ın Kaydedilmesi
   $chart1.SaveImage("c:\TEMP\FRTColumnChart.png","png")
}

Giriş kısmının ardından scriptin işlem aşaması aşağıdaki if değişkeni ile başlıyor.

if($GetIncidents.Count -gt 0)

Bu if değişkeni değişken kısmında belirtilen kiretde olay kayıtlarının elde edilip edilmediğini sorguluyor. Sayı sıfırdan büyükse işleme başlıyor.

#Elde edilen her bir incident'ı işlemek için foreach'i kullanıyoruz. 
    foreach ($RSincident in $GetIncidents)
    {
                    
      #SLA relationship class'ını kullanıp SLA objesini elde edelim. Burada SLA DisplayName'ini kendinize uygun yazmanız gerekiyor.
      $sla = Get-SCSMRelatedObject -SMObject $RSIncident -Relationship $SLARelClass | where{$_.DisplayName -eq "Mudahale SLA"}
      #Bir değişkene direk MET değeri atıyorum. Bu SLA Karşılandı anlamına geliyor.
      $blnFound = "MET"
      if($sla -ne $null)
       {
         #Eğer SLA durumu breached'e eşitse MET olarak tanımladığım değişkeni BREACHED olarak değiştiriyorum.
         if($sla.Status.Name -eq "SLAInstance.Status.Breached")
         {
          $blnFound = "BREACHED"
                        
         }
       }
      #Her bir olay kaydı için kendi ps objelerimi oluşturuyorum.Böylece relation class attribute'larını da tek bir objeye attribure olarak
      #atayabiliyorum. SLA.Status bilgisi gibi.
      $Incidentobject = New-Object  PSObject -Property @{ID=$RSIncident.Id;Status=$RSincident.Status.DisplayName;StatusName=$RSincident.Status.Name;Impact=$RSincident.Impact.DisplayName;
                        Title=$RSincident.Title;SupportGroup=$RSincident.TierQueue.DisplayName;CreatedDate=$RSincident.CreatedDate;SLA=$blnFound}
      #Oluşturduğum psobjelerini $IncidentsObjs array'ine ekliyorum.         
      $IncidentsObjs += $Incidentobject
              
     }
    #Arrau sayısı sıfırdan büyükse  işleme devam ediyoruz.   
    if($IncidentsObjs.Count -ne 0)
     {
      #SupportGrouplar için array oluşturalım. $TierQueueEnums'dan elde ettiğim support group bilgilerini bu array'e atacağım.
      $SupportGroupArray = @()
      #Support Group ve sayısal değerleri içeren ps objeleri için bir array oluşturalım.
      $SupportGroupBaseGroupedIncidents=@()
      #Support group bilgilerini array'e atayalım. Sonra bu array'i kullanıp her bir support group için işlem yapacağız.
       foreach ($enum in $TierQueueEnums)
       
        $SupportGroupArray += $enum
       }
    #Her bir support group için sayısal veri içeren ps objelerini oluşturup $SupportGroupBaseGroupedIncidents arrayine atayalım.
    for ($i=0; $i -lt $SupportGroupArray.Count;$i++)
    {
         #ilgili support group için toplam olaylar
         $TOTAL=@($IncidentsObjs | where {$_.SupportGroup -eq $SupportGroupArray[$i].DisplayName})
         #ilgili support group için çözümlenmiş ve apatılmış olaylar
         $Resolved = @($IncidentsObjs | where {$_.SupportGroup -eq $SupportGroupArray[$i].DisplayName -and ($_.StatusName -eq "IncidentStatusEnum.Resolved" -or $_.StatusName -eq "IncidentStatusEnum.Closed")})
         #ilgili support group için çözümlenmiş,kapatılmış ve sla'yi karşılanmış olaylar
         $MET=@($IncidentsObjs | where {$_.SupportGroup -eq $SupportGroupArray[$i].DisplayName -and $_.SLA -eq "MET" -and (($_.StatusName) -eq "IncidentStatusEnum.Resolved" -or ($_.StatusName) -eq "IncidentStatusEnum.Closed") })
         #Eğer ilgili support grubun olay sayısı sıfırdan büyük ise işleme devam ediyoruz.
         if($TOTAL.Count -gt 0)
         {
          #Çözümlenen olay sayısı büyük ise;
          if($Resolved.Count -ne 0)
          {
            #Çözümlenen olaylardan kaçı SLA'yi karşılanmış olanların yüzdesini hesaplıyoruz.
            $SLAPercentage= ("{0:P0}" -f ($MET.Count / $Resolved.Count))
          }
          else
          {
            #çözümlenen olay yok ise oranı sıfır'a eşitliyoruz.
            $SLAPercentage= ("{0:P0}" -f 0)
          }
          #supportgroup ve o support group'a ait sayısal verileri içeren  psobjesini oluşturuyoruz.
         $GroupBaseIncidentObject = New-Object  PSObject -Property @{SupportGroup=$SupportGroupArray[$i].DisplayName;TotalIncidents=$TOTAL.Count;ActiveIncidents=$TOTAL.Count-$Resolved.Count;
         IncidentsSLAMet=$MET.Count;IncidentsSLABreached=$Resolved.Count-$Met.Count;SLAPercentage=$SLAPercentage;ResolvedIncidents=$Resolved.Count}
          #oluşturulan objeyi $SupportGroupBaseGroupedIncidents array'ine ekliyoruz.
         $SupportGroupBaseGroupedIncidents += $GroupBaseIncidentObject
         #Total ve Met değerlerini bir sonraki işlem için sıfırlıyoruz.
         $TOTAL=@()
         $MET=@()
         }
    }

İşlemlerin ardından elde edilen sayısal değerler ile Chart’ın oluşturulması aşamasına geçiyoruz. Bu aşamada bu işlem için yaptığım fonksiyona veriyor göndermemiz yeterli olacak. Fonksiyonun çalışması için birkaç değişkene ihtiyaç var. Önce onları tanımlayalım.

Oluşturduğumuz sayısal değerlerden hangilerini sütun olarak görmek istiyorsan onları ve sütunun rengini “-“ kullanarak aşağıdaki gibi bir array içerisine yerleştirelim. Burada sütun rengi için renk kodu kullanmamız gerekiyor. İstediğimiz kadar sayısal değeri bu şekilde array içerisine atayabiliriz.

$YElements = @(“TotalIncidents-#FF7F00”,“ResolvedIncidents-#728FCE”,“IncidentsSLAMet-#4CC417”,“IncidentsSLABreached-#FF5050”)

Ardından bu değişkeni kullanıp fonksiyonumuzu çağıralım.

New-ColumnChart -ChartObjects $SupportGroupBaseGroupedIncidents -XElement “SupportGroup” -YElement $YElements -ChartTitle “Weekly Incident SLA Chart”

Xelement’e direk support grup yazmamızın sebebi, $SupportGroupBaseGroupedIncidents içerisinde böyle bir attribute olması ve x aksiste bunu kullanacak olmamız. Yani sabit bir değer olması.

İşlemlerin ardından  chart fonksiyonu c:\TEMP içersine dataları kullanıp grafiği png olarak aşağıdaki gibi çizecektir.

mk.3Grafiğimiz verdiğimiz dataları gayet şık olarak gösteriyor. Şimdi bu datalara ait HTML tabloyu da oluşturalım ve mail olarak gönderelim.

#Resmin mail body'sinde gözükmesi için aşağıdaki HTML eklentisini HTML değişkenine ekliyoruz.
   $HTML2 += @'
           <html
            <body
               <imgsrc="cid:FRTColumnChart.png">  
            </body
           </html
'@ 
   #HTML tablo için başlık ekliyoruz.
   $HTML2 +=   "<h3>Support Group Base SLA Calculation</h3>"
   #Tabloyu Göstermesini isteiğimiz field'ları ile oluşturuyoruz. SLA yüzdesine göre de SLAPercentage hücresini değişik renklere boyayalım.
   $HTML2 += New-HTMLTable -inputObject $($SupportGroupBaseGroupedIncidents | sort { [INT]($_.SLAPercentage -replace '%')  } -Descending| select SupportGroup,TotalIncidents,ActiveIncidents,ResolvedIncidents,IncidentsSLAMet,IncidentsSLABreached,SLAPercentage)|
          Add-HTMLTableColor -Argument "%100" -Column "SLAPercentage" -AttrValue "background-color:#4CC417;"|
          Add-HTMLTableColor -Argument "%97" -Column "SLAPercentage" -AttrValue "background-color:#52D017;"|
          Add-HTMLTableColor -Argument "%96" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%95" -Column "SLAPercentage" -AttrValue "background-color:#54C571;"|
          Add-HTMLTableColor -Argument "%94" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%93" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%92" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%91" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%90" -Column "SLAPercentage" -AttrValue "background-color:#4CC552;"|
          Add-HTMLTableColor -Argument "%0" -Column "SLAPercentage" -AttrValue "background-color:#FF5050;"|Close-HTML
         
       
   #Ardından Html'imizi mail olarak yollayalım
   $subject = “Support Group Base SLA Calculation Report"   
   $body = $HTML2
   $to=”firat.yasar@bdh.com.tr” 
   $from=”helpdesk@marsconcept.com”
   Send-Mail $from $to $subject $body
   }

mk.4Hepsi bu kadar :) Dataları elde ettikten sonra daha farklı chart’lar kullanıp farklı görselleri rahatlıkla oluşturabilirsiniz.

Powershell ile her şey mümkün :)

Bir sonraki makale de görüşmek üzere.

Scripti Aşağıdaki linkten indirebilirsiniz

Technet Gallery

FIRAT

Leave a Reply