fbpx
Anasayfa » System Center Configuration Manager SCCM Üzerinde Queryler ile Çalışmak Bölüm 2

Makaleyi Paylaş

Microsoft System Center Yönetim Ailesi

System Center Configuration Manager SCCM Üzerinde Queryler ile Çalışmak Bölüm 2

Bir önceki makalede sizlerle SCCM query’ leri ile çalılma konusunda bir takım bilgiler vermeye çalışmıştım. Önceki makalede ağırlıklı olarak collectionlar üzerinde durmuştuk. Yine querylerle çalışmaya devam edeceğim ancak bu sefer DCM ve Reporting kısımlarında da bir takım işler yapacağız ve bir parça troubleshooting yapacağız.

 

Bu makalede anlatacağım konular aslında bir ihtiyaçtan dolayı yapılmış çalışmaların özetidir. Muhtemelen böyle bir ihtiyaç birçok sistem yöneticisi için söz konusu olmuştur. İhtiyacımız şu idi; yine bir denetim döneminde tüm serverların lokal gruplarının üyeliklerini listelememiz gerekti. Bu liste üzerinden yapılacak kontrol ile gereksiz ve yetkisiz olarak yetkilendirilmiş tüm user ve grupları görebilecek ve gerekli düzenlemeyi yapabilecektik. Ve bunu bilgiyi/raporu SCCM üzerinden almak istedik.

 

SCCM’ in kurulum ile beraber gelen raporlarına göz attık ve işimizi görecek hazır bir rapor bulamadık.

 

 

image001

 

 

Hatta yeni bir rapor oluşturup query ile istediğimiz veriye ulaşmaya da çalıştık, ancak durum beklediğimizden de farklı idi. SCCM’in agent’lardan topladığı veri içerisinde bizim istediğimiz veriler bulunmamakta idi. Bildiğiniz gibi SCCM ağırlıklı olarak hardware ve software bilgilerini toplamaktadır.

Sponsor

 

 

image002

 

 

Biraz araştırma yaptık, bir arkadaşımızın tecrübesinden yararlandık ve aşağıdaki link üzerinden yola çıktık;

 

http://myitforum.com/cs2/blogs/skissinger/archive/2010/04/25/report-on-all-members-of-all-local-groups.aspx

 

(Hakan UZUNER’ e teşekkürler)

 

Aslında bundan sonra anlatacaklarım link’ te bulunan bilgilerdir. Adım adım devam edersek ilk olarak Desired Configuration Management bölümünde bir tane configuration item oluşturacağız;

 

 

image003

 

 

image004

 

 

İlk ekranda bir isim belirliyoruz ve devam ediyoruz,

 

 

image005

 

 

Herhangi bir object eklemeden devam ediyoruz,

 

 

image006

 

Settings bölümünde bir script ekleyeceğiz,

 

 

image007

 

 

Açılan pencerede script için bir isim giriyoruz, aşağıda linkini ve açık halde kodunu verdiğim script kodunuda script kısmına kopyalıyoruz.

 

http://myitforum.com/cs2/blogs/skissinger/LocalGroupMembersScriptDCMCITest.txt

 

on error resume next

Steps

enumerate from win32_group where localaccount=1

‘Read in the members of each local group returned

‘Add the returned information to a custom WMI namespace

sms-def.mof to pull that back.

Set fso = CreateObject(“Scripting.FileSystemObject“)

Set nwo = CreateObject(“Wscript.Network“)

Set sho = CreateObject(“Wscript.Shell“)

TempFolder = sho.ExpandEnvironmentStrings(“%temp%”)

strWindir = sho.ExpandEnvironmentStrings(“%windir%”)

strComputer = nwo.ComputerName

Dim wbemCimtypeSint16

Dim wbemCimtypeSint32

Dim wbemCimtypeReal32

Dim wbemCimtypeReal64

Dim wbemCimtypeString

Dim wbemCimtypeBoolean

Dim wbemCimtypeObject

Dim wbemCimtypeSint8

Dim wbemCimtypeUint8

Dim wbemCimtypeUint16

Dim wbemCimtypeUint32

Dim wbemCimtypeSint64

Dim wbemCimtypeUint64

Dim wbemCimtypeDateTime

Dim wbemCimtypeReference

Dim wbemCimtypeChar16

 

wbemCimtypeSint16 = 2

wbemCimtypeSint32 = 3

wbemCimtypeReal32 = 4

wbemCimtypeReal64 = 5

wbemCimtypeString = 8

wbemCimtypeBoolean = 11

wbemCimtypeObject = 13

wbemCimtypeSint8 = 16

wbemCimtypeUint8 = 17

wbemCimtypeUint16 = 18

wbemCimtypeUint32 = 19

wbemCimtypeSint64 = 20

wbemCimtypeUint64 = 21

wbemCimtypeDateTime = 101

wbemCimtypeReference = 102

wbemCimtypeChar16 = 103

Remove classes

Set oLocation = CreateObject(“WbemScripting.SWbemLocator“)

‘===================

If this is a Domain Controller, bail!

‘===================

Set oWMI = GetObject(winmgmts:” _

& “{impersonationLevel=impersonate}!\\.\root\cimv2″)

Set colComputer = oWMI.ExecQuery _

(“Select DomainRole from Win32_ComputerSystem”)

For Each oComputer in colComputer

 if (oComputer.DomainRole = 4 or oComputer.DomainRole = 5) then

   wscript.echoDomainController, So I’m quitting!”

   ‘wscript.quit

Else

‘==================

If it is NOT a domain controller, then continue gathering info

‘and stuff it into WMI for later easy retrieval

‘==================

 

Set oServices = oLocation.ConnectServer(,”root\cimv2″)

set oNewObject = oServices.Get(“CM_LocalGroupMembers“)

oNewObject.Delete_

‘==================

Get the local Group Names

‘==================

Dim iGroups(300)

i=0

Set objWMIService = GetObject(winmgmts:” _

        & “{impersonationLevel=impersonate}!\\.\root\cimv2″)

Set colGroup = objWMIService.ExecQuery(“select * from win32_group where localaccount=1″)

for each obj in colGroup

  igroups(i)=obj.Name

  i=i+1

next

‘===============

Get all of the names within each group

dim strLocal(300)

k=0

Set oLocation = CreateObject(“WbemScripting.SWbemLocator“)

Set oServices = oLocation.ConnectServer(, “root\cimv2” )

 

‘group name, domain name, user or group

for j = 0 to i-1

 

squery = “select partcomponent from win32_groupuser where groupcomponent = “”\\\\” &_

 strComputer & “\\root\\cimv2:Win32_Group.Domain=\””” & strComputer &_

“\””,Name=\””” &igroups(j) & “\”””””

 

Set oInstances = oServices.ExecQuery(sQuery)

FOR EACH oObject in oInstances

  strLocal(k)=igroups(j) & “!” & oObject.PartComponent

 

  k=k+1

 

Next

next

‘==================

Drop that into a custom wmi Namespace

‘==================

 

‘ Create data class structure

Set oDataObject = oServices.Get

oDataObject.Path_.Class = “CM_LocalGroupMembers

oDataObject.Properties_.add “Account” , wbemCimtypeString

oDataObject.Properties_(“Account”).Qualifiers_.addkey” , True

oDataObject.Properties_.add “Domain” , wbemCimtypeString

oDataObject.Properties_.addCategory” , wbemCimtypeString

oDataObject.Properties_.addType” , wbemCimtypeString

oDataObject.Properties_.add “Name” , wbemCimtypeString

oDataObject.Properties_(“Name”).Qualifiers_.addkey” , True

oDataObject.Put_

 

for m = 0 to k-1

Set oNewObject = oServices.Get(“CM_LocalGroupMembers” ).SpawnInstance_

str0 = Split(strLocal(m), “!”, -1, 1)

str1 = Split(str0(1), “,” , -1, 1)

str2 = Split(str1(0), “\” , -1, 1)

str4 = Split(str2(4), Chr(34), -1, 1)

 

‘ The Account name or Group Name is inside the quotes after the comma

str3 = Split(str1(1), Chr(34), -1, 1)

if the wmi source name is the same as the domain name inside the quotes, it’ s a local account

‘ str2(2) is the wmi source name, str4(1) is the domain name inside the quotes.

If lcase(str2(2)) = lcase(str4(1)) Then

oNewObject.Type = “Local”

Else

oNewObject.Type = “Domain”

End If

oNewObject.Domain = str4(1)

oNewObject.Account = str3(1)

oNewObject.Name = str0(0)

Select Case lcase(str4(0))

  case “cimv2:win32_useraccount.domain=”

   oNewObject.Category = “UserAccount

  Case “cimv2:win32_group.domain=”

   oNewObject.Category = “Group”

  Case “cimv2:win32_systemaccount.domain=”

   oNewObject.Category = “SystemAccount

  case else

   oNewObject.Category = “unknown

end select

oNewObject.Put_

Next

wscript.echo “ok”

 

 end if

Next

 

wscript.quit

 

 

 

image008

 

 

Aynı pencerenin validation tabındaki ayarlarda resimdeki gibi olmalı,

 

 

image009

 

 

Sonraki pencerede All Windows platforms olarak bıraktık, diğer pencereleri next ile geçerek bitiriyoruz. Configuration item yaratılmış oldu. Sonraki adım olarak bir DCM Baseline yaratmamız gerekli, eğer halihazırda kullandığınız bir Baseline var ise yapacağımız işlemlei onun üzerinde de yapabilirsiniz. Ben olmadığını farederek devam ediyorum;

 

 

image010

 

 

image011

 

 

Yine bir isim vererek devam ediyoruz, ben CI ile aynı ismi vermeyi tercih ettim,

 

 

image012

 

 

These applications and general configuration items are required and must be properly configured” kısmını tıklayarak oluşturduğumuz CI’ I seçiyoruz,

 

 

image013

 

 

Sonraki ekranları next ile geçip işlemi tamamlıyoruz.

 

 

image014

 

 

Baselineıda oluşturduktan sonra sms_def.mof file’ ı notepad ile açıp dosyanın en sonuna aşağıda görülen mof pasajını eklememiz gerekiyor. Ancak bu işlemi yapmadan evvel mof dosyasının bir yedeğini almanız tavsiye edilir, çünkü mof dosyası tüm envanter bilgilerinin alındığı dosyadır.

//=====================Local Group Members, Includes Administrators
//Pre-requisite: recurring Advertisement, or Recurring DCM Baseline/CI
//====================================================================
#pragma deleteclass (“LocalGroupMembers“,NOFAIL)
[ SMS_Report     (TRUE),
  SMS_Group_Name (“LocalGroupMembers“),
  SMS_Class_ID   (“CUSTOM|LocalGroupMembers|1.0”) ]
class cm_LocalGroupMembers : SMS_Class_Template
{
    [SMS_Report (TRUE), key ] string Account;
    [SMS_Report (TRUE)      ] string Category;
    [SMS_Report (TRUE)      ] string Domain;
    [SMS_Report (TRUE), key ] string Name;
    [SMS_Report (TRUE)      ] string Type;
};

 

 

image015

 

 

Sonrasında bu dosyayı command promt’ fa compile etmemiz gerekiyor, bunun için ilgili klasöre gidip (dosyanın bulunduğu klasör) ve mofcomp komutu ile compile edilir.

 

 

image016

 

 

image017

 

 

Burada belirtmek istediğim bir kısım var, oluşturduğumuz baselineın hangi collection için uygulanacağı ve schedule ayarı. Benim amacım sunucuların lokal gruplarındaki üyelikleri öğrenmek idi, bu yüzden tüm windows sunuculara uyguladım.

 

 

image018

 

 

Oluşturduğumuz baslineın serverlarda uygulanıp uygulanmadığını Comtrol Panel içerisinde Configuration Manager içerisinde resimde gösterdiğim alandan kontrol edebilirsiniz. Bizim baselineımız sunucuya ulaşmış ve compliant durumda.

Şu ana kadar yaptığımız işlemler ile sunucuların lokal grupları ile ilgili bir takım bilgileri SCCM database’ i içerisine almış olduk. Bundan sonra yapacağımız işlem Reporting altında custom report oluşturmak olacak. Böylece hedeflediğimiz veriyi tek bir rapor altında toplamış olacağız.

 

 

image019

 

 

Bu işlem için Reporting>Reports altında yeni rapor oluşturmaya başlarız,

 

 

image020

 

 

Rapora anlamlı bir isim verdikten sonra bir kategori seçeriz, yine anlamlı olmasında fayda var, bu rapor kullanıcılar ile alakalı bir sonuç döndüreceğinden ben Users kategorisini seçtim. Sonrasında Edit SQL statement kısmına tıklıyoruz,

 

 

image021

 

 

Açılan pencerede aşağıda açık halini verdiğim query’ yi SQL Statement kısmına kopyalıyoruz.

declare @olddcm datetime

declare @oldhinv datetime

set @oldDCM=DATEADD(DAY,-3, getdate())

set @oldHinv=DATEADD(DAY,-3, getdate())

select sys1.netbios_name0

,lgm.name0 [Name of the local Group]

,lgm.account0 as [Account Contained within the Group]

, lgm.category0 [Account Type]

, lgm.domain0 [Domain for Account]

, lgm.type0 [Type of Account]

, case when ws.lasthwscan < @oldhinv thenLast Hinv might be out of date

 when cs.lastcompliancemessagetime < @olddcm then ‘CI evaluation might be out of date

 when ws.lasthwscan < cs.lastcompliancemessagetime then ‘CI evaluated since hinv, not necessarily unreliable

  elseRecent CI Eval, Hinv since CI Eval = Fairly Reliable

end as [Reliability of Information]

from

v_GS_localgroupmembers0 lgm

join v_GS_WORKSTATION_STATUS ws on ws.ResourceID=lgm.ResourceID

join v_R_System_Valid sys1 on sys1.ResourceID=lgm.ResourceID

left join v_CICurrentComplianceStatus cs on cs.ResourceID=lgm.ResourceID

left join v_LocalizedCIProperties_SiteLoc loc on loc.CI_ID=cs.CI_ID

where loc.DisplayName = ‘Local Group Members

order by sys1.netbios_name0, lgm.name0, lgm.account0

Yukarıdaki query kısmında bazı yerleri yeşil ile işaretledim, bu kısımlar ben daha evvel raporu oluştururken karşılaştığım problemlerden biri idi, case sensitive problemi, raporu çalıştırdığınız zaman aşağıda gördüğünüz hata geri dönmekteydi. Ben sıra ile yukarıdaki pencerede gördüğünüz views ve columns kısımlarını kontrol ederek database üzerindeki ile birebir aynı yaptım. Bir de yukarıda gördüğünüz gibi sarı ile işaretli bir alan daha var, buradaki kısım sizin baseline’ a verdiğiniz isim olmalı, boşluk dahil herhangi bir karakter farklı olur ise rapor hiçbirşey döndürmeyecektir.

 

 

image022

 

 

Artık raporumuzu çalıştırıp dönen sonuca bakalım,

 

 

image023

 

 

image024

 

 

Evet sunuculardaki lokal gruplara üye tüm lokal kullanıcı, domain kullanıcısı, lokal grup veya domain grubu bilgilerini elde ettik. Bu raporu export butonuna basarak csv file olarak export edebiliriz. Csv file’ ıda excel ile birlikte açıp text to file işlemine tabi tutup, virgüllerle ayrılmış veriyi kolonlara dağıtarak üzerinde filter çalışması yapabiliriz. Buradanda yetkili olmaması gereken kullanıcıları kolaylıkla tespit edebiliriz.

 

 

image025

 

 

Yukarıda rapor oluşturmak için kullandığımız query;

declare @olddcm datetime

declare @oldhinv datetime

set @oldDCM=DATEADD(DAY,-3, getdate())

set @oldHinv=DATEADD(DAY,-3, getdate())

select sys1.netbios_name0

,lgm.name0 [Name of the local Group]

,lgm.account0 as [Account Contained within the Group]

, lgm.category0 [Account Type]

, lgm.domain0 [Domain for Account]

, lgm.type0 [Type of Account]

, case when ws.lasthwscan < @oldhinv thenLast Hinv might be out of date

 when cs.lastcompliancemessagetime < @olddcm then ‘CI evaluation might be out of date

 when ws.lasthwscan < cs.lastcompliancemessagetime then ‘CI evaluated since hinv, not necessarily unreliable

  elseRecent CI Eval, Hinv since CI Eval = Fairly Reliable

end as [Reliability of Information]

from

v_gs_localgroupmembers0 lgm

join v_GS_WORKSTATION_STATUS ws on ws.ResourceID=lgm.ResourceID

join v_R_System_Valid sys1 on sys1.ResourceID=lgm.ResourceID

left join v_CICurrentComplianceStatus cs on cs.ResourceID=lgm.ResourceID

left join v_LocalizedCIProperties_SiteLoc loc on loc.CI_ID=cs.CI_ID

where loc.displayname = ‘Local Group Members

and lgm.type0 = ‘local

and lgm.category0 = ‘userAccount

and lgm.account0 not in (‘Administrator’,’Guest‘)

order by sys1.netbios_name0, lgm.name0, lgm.account0

 

 

image026

 

 

Bu query kullanılarak oluşturulan rapor ise yukarıdaki çıktıyı vermektedir. Diğeri ile arasındaki fark bu raporda domain kullanıcıları ve grupları listede bulunmuyor. Genellikle ilk rapor daha kapsamlı veri içerdiği için tercih edilecektir. Ancak sisteminizde yüzlerce sunucu varsa, bunların içerisindeki tüm lokal gruplara üye tüm objeler için liste uzadıkça uzuyor ve 10000 satırın üzerinde veri geri dönecektir. Bu durumda da benim yaşadığım gibi raporun çalışması ile ilgili sorun yaşayacaksınızdır. Rapor bazen çalışacak ve görüntülenecek bazende görüntülenemeyecektir. Bu sorunun 2 nedeni olabiliyor, birincisi satır sayısı ikincisi ise sunucuda o andaki utilization. SCCM’ de görüntülenebilecek maximum satır ayarı yok ancak aşağıda verdiğim link uygulanırsa satır problemi yaşamayacaksınızdır;

 

http://scug.be/blogs/sccm/archive/2009/09/30/sccm-2007-reporting-how-to-change-the-maximum-rows-returned-in-the-values-list-that-is-default-set-to-1000-rows.aspx

 

Yapmanız gereken çok basit bir işlemdir. Registry açılır ve ilgili alan altında bir DWORD yaratılıp değerini istediğiniz gibi atamak.

 

Ve son bir troubleshooting bilgisi daha verelim. Sistem yöneticisi sizsiniz ve tabiki sisteminizdeki sunucuları biliyorsunuz. Ama fark ettiniz ki rapor içerisinde bazı sunucularınız yok, listede bulamadınız.

 

Derdini anlatan sistemler her zaman işimizi kolaylaştırmıştır. Yine SCCM içerisinde system status bölümündeki status message queries kısmında geliyoruz,

 

 

image027

 

 

Tüm durum mesajlarını görüntüleyelim,

 

 

image028

 

 

image029

 

 

Ben 1 haftalık veriyi getirmesini istedim,

 

 

image030

 

 

Gelen birçok veri içerisinden bizimle alakalı olanı çıkarmak için veriyi filtreliyoruz ve Desired Configuration Management ile ilgili veriyi süzüyoruz.

 

 

image031

 

 

Listede göremediğimiz bir takım makineler ile ilgili hata alanlar olduğunu görüyoruz, bir tanesinin detayına baktığımız zaman sunucu üzerinde .Net Framework’ un kurulu olmadığını söylüyor bize. Bu bağımlılıktan dolayı DCM işini düzgün yapamıyor.

 

Toplamda kaç makinede .Net kurulumu olmadığını yine SCCM query’ leri ile çalışarak tespit edebilirsiniz. İlk makalemizde sizinle paylaştığım bilgileri kullanarak custom bir collection oluşturabilirsiniz. Query statement kısmına da aşağıdaki query’ yi yazabilirsiniz.

 

select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId where SMS_G_System_COMPUTER_SYSTEM.Name not in (select distinct SMS_G_System_COMPUTER_SYSTEM.Name from SMS_R_System inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like “%NET Framework%”)

Saygılar.

 

 

 

Makaleyi Paylaş

Cevap bırakın