Feeds
Artikel
Kommentare

Möchte man die Zuordnung eines Primary Users automatisieren (statt die Zuordnung in der Admin Konsole vorzunehmen (“Edit Primary Users”)), so kann dafür entweder das Powershell-cmdlet Add-CMUserAffinityToDevice oder folgende vbs-Variante verwendet werden:

 Set objSMS = GetObject("winmgmts://./root/sms/site_XYZ") ' Replace XYZ with the site code
 Set objUDA = objSMS.Get("SMS_UserMachineRelationShip")
 Set objRelShip = objUDA.Methods_("CreateRelationShip").inParameters.SpawnInstance_()
 objRelShip.MachineResourceID = "16777235" ' ResourceID
 objRelShip.SourceID = "2" ' AffinityType (2 = admin defined)
 objRelShip.TypeID = "1"
 objRelShip.UserAccountName = "your-domain\your-account" ' user account
 objSMS.ExecMethod "SMS_UserMachineRelationShip", "CreateRelationship", objRelShip
 

Folgende SQL-Abfrage listet alle Applications und deren Deployment Types:

select
 LLAC.DisplayName as [Application],
 LDTC.DisplayName as [Deployment Type],
 LDTC.Technology
 from
 fn_ListLatestApplicationCIs(1033) LLAC
 left join fn_ListDeploymentTypeCIs(1033) LDTC
 on LLAC.ModelName = LDTC.AppModelName and LDTC.IsLatest = 1
 order by 1,2

Seit dem Service Pack 1 für ConfigMgr gibt es ja Powershell CmdLets zur einfacheren Automatiserung vieler Vorgänge. Vor dieser Zeit blieb einem nur der Weg über WMI (vbs, Powershell usw).
Doch nicht alles, was einfach ist (und funktioniert), ist auch performant. In kleinen Umgebungen, oder Umgebungen, bei denen der Automatisierungsgrad nicht sehr hoch ist, fällt dies unter Umständen nicht einmal auf.
Schon kleine Tricks können dabei einen massiven Performance-Gewinn bringen. Hier ein Powershell-Beispiel zum Thema Performance. Gegeben ist der Name einer Collection (“Name_to_Search“). Diese soll in SCCM 2012 gefunden werden, um damit dann weiterarbeiten zu können.
Im Folgenden betrachte ich 4 unterschiedliche Möglichkeiten:

  1. Get-CMDeviceCollection | where {$_.Name -eq “Name_to_Search“}
  2. gwmi -Namespace root\sms\site_xyz -Class SMS_Collection | where {$_.Name -eq “Name_to_Search“}
  3. Get-CMDeviceCollection -Name “Name_to_Search
  4. gwmi -Namespace root\sms\site_xyz -Query “SELECT * FROM SMS_Collection where Name = ‘Name_to_Search

Hier jeweils die Dauer (gemessen mit measure-command) in Sekunden:

  1. 472
  2. 13
  3. 0,2
  4. 0,2

Man sieht, dass zwischen der kürzesten und längsten Laufzeit ein Faktor von ca. 2000 (!) liegt. Woran liegt das? Dazu sollte man sich betrachten, welche Abfragen (Queries) der SMS Provider jeweils ausführt:

  1. SELECT * FROM SMS_Collection WHERE CollectionType=2
    plus: GetObjectAsync : SMS_Collection.CollectionID=”XYZ00xxx” für alle CollectionIDs
  2. select * from SMS_Collection
  3. SELECT * FROM SMS_Collection WHERE Name=’Name_To-Search‘  AND CollectionType=2
  4. SELECT * FROM SMS_Collection where Name = ‘Name_to_Search

An den Beispielen 1) und 2) sieht man, dass erst alle Collection-Objekte verarbeitet werden müssen und man sich erst danach (mittels Pipe (|)) die wirklich benötigte herausfiltert.
Eine Analogie aus der Praxis dazu: man bestellt in einem Restaurant erst einmal alles von der Speisekarte, lässt alles von der Bedienung bringen, der Tisch wird richtig voll gestapelt und man sucht sich erst dann sein Gericht aus. Funktioniert. Aber eben nicht wirklich optimal, denn (a) wird dies teuer (man zahlt alle Gerichte, obwohl man nur eines isst) und (b) dauert dies lange (da die Bedienung zig mal hin- und herlaufen muß, um alles auszuliefern). Der Rest wird weggeworfen.
Die Methoden 3) und 4) sind deutlich schneller. Wieso? Weil man sich von Anfang an nur das aussucht, was man auch wirklich braucht. Am Beispiel des Restaurant-Besuches: man sucht sich das Gericht von der Speisekarte aus, welches man auch wirklich essen möchte. Entsprechend läuft die Bedienung nur einmal und man zahlt auch nur einmal.

Entsprechend gilt dies natürlich nicht nur für Collection, sondern auch alle anderen ConfigMgr-Objekte, die in großer Anzahl vorhanden sein können. Denkt also bei der Erstellung des nächsten Skripts kurz an das Beispiel von oben. Die Bedienung Der ConfigMgr-Provider und die Performance werden es euch danken!

Unter http://www.microsoft.com/en-us/download/details.aspx?id=36212 kann man die Clients für non-Windows Betriebssysteme (MAC, RedHat, Solaris und Suse Linux Enterprise) herunterladen.

Das CU1 (Cumulative Update) für SP1 ist verfügbar: http://support.microsoft.com/kb/2817245. Infos zu CUs und ConfigMgr 2012 hatte ich bereits in diesem Artikel zu Verfügung gestellt.

In System Center 2012 Configuration Manager (RTM und SP1) gibt es einen Bug, der verantwortlich dafür ist, daß im Software Center Applications nicht angezeigt werden, obwohl diese auf den Client zugewiesen sind.

Die Chance, von diesem Bug betroffen zu sein, ist meiner Meinung nach sehr gering. Ich selbst habe dies bisher nur in einer Umgebung gesehen, auf der über 1000 Applications auf einen Client zugewiesen sind. Laut Aussage eines Support Engineers von Microsoft gibt es aber einen weiteren Fall, bei dem dies “schon” bei 200 Applications aufgetreten ist. Ob die Anzahl der Deployments pro Client aber überhaupt eine Rolle spielt ist mir nicht bekannt. Außerdem ergaben Analysen von Microsoft, daß nur “high performance Clients” betroffen sind.

Wie erkannt man den Bug?
Direkt erst einmal gar nicht, d.h. man sieht client- und serverseitig erst einmal keine Fehlermeldung oder ähnliches. Ein Symptom ist, daß eine zugewiesene Applikation einfach nicht im Software Center angezeigt wird.

Für ein weiteres Troubleshooting kann das Deployment Monitoring Tool aus dem “System Center 2012 Configuration Manager Service Pack 1 Component Add-ons and Extensions” verwendet werden. Dieses listet zwar alle Applications, bei einem Klick auf eine betroffene Application bekommt man aber die Fehlermeldung “DT cannot be empty” und das Tool stürzt ab:

DMT

Entsprechend war es naheliegend, einen Automatismus zu verwenden, der die betroffenen Clients ermitteln kann.
Ich habe mich für eine Configuration Baseline mit einem Configuration Item (ehemals “DCM” / Desired Configuration Management) entschieden.
Das CI verwendet dazu ein Powershell-Skript (Powershell Version 3.0 erforderlich!) um die fehlenden DTs (Deployment Types) zu ermitteln:

CI-01

$ErrorActionPreference = "Stop"

$PSvers = $host.Version
if($PSvers.Major -lt 3)
{
Write-Host "Please install WMF 3.0 (kb2506143)."
write-host "Quit (255)"
exit 255
}

[int]$countMissingDTs = 0

try
{
$Applications = gwmi -namespace root\ccm\clientsdk -query "select * from ccm_application"
}
catch
{
exit 1
}

$AppsTotal = $Applications.Length

foreach($App in $Applications)
{
$AppDT = [wmi] $App.__Path

if($AppDT.AppDTs.Name.Length -eq 0)
{
$countMissingDTs = $countMissingDTs + 1
}
}

$countMissingDTs

Ich bin kein Powershell-Profi und konnte das Skript auch nur begrenzt testen, entsprechend ist es nur als Anregung für weitere Verbesserungen zu sehen ;-)
Die Idee ist aber, die fehlenden DeploymentTypes (DT) zu ermitteln, diese zu summieren und am Ende des Skripts auszugeben.
Wenn kein DT fehlt, dann ist die Ausgabe 0 ($countMissingDTs) und der Rechner als “compliant” anzusehen. Ist die Ausgabe größer 0, so wird der Rechner als “non-compliant” angesehen:

CI-02

Als Ergebnis erhält man dann entsprechend alle Clients, die von dem Problem betroffen bzw nicht betroffen sind:

CI-Monitoring-01

Bei den betroffenen Clients entsprechend dann sogar mit Ausgabe der Anzahl der fehlenden Applications (in diesem Beispiel 5):

CI-Monitoring-02

Als “Lösung” für das Problem gibt es ein vbs-Skript (Quelle: Microsoft Support), welches auf den betroffenen Clients auszuführen ist.
Hier ist ebenfalls ein Automatismus denkbar. Die betroffenen Clients wurden per DCM/Compliance identifiziert, können entsprechend in einer Collection gruppiert und das Skript als Package/Program advertised werden.

'Trigger DCM Schedules for Applications
 Dim objWMI_MachinePolicy
 Dim query, AppCIAssignments
 'Connect to WMI
 Set objWMI_MachinePolicy = GetObject("wInmgmts:\\.\root\ccm\Policy\Machine")
 query=("select * from CCM_ApplicationCIAssignment")
 Set AppCIAssignments=objWMI_MachinePolicy.ExecQuery(query)
 For Each AppCIAssignment in AppCIAssignments
 'MsgBox "Starting schedule for " & AppCIAssignment.AssignmentID
 RunSchedule(AppCIAssignment.AssignmentId)
 WScript.Sleep 500
 Next
 Set objWMI_MachinePolicy=Nothing
 '--------------------
 'Function RunSchedule
 '
 'Purpose: Connects to WMI and triggers the supplied schedule.
 '
 '--------------------
 Function RunSchedule (ScheduleMessageId)
 Dim objWMI_RunSchedule
 'Connect to WMI
 Set objWMIService = GetObject("winmgmts:\\.\root\ccm:SMS_Client")
 objWMIService.TriggerSchedule(ScheduleMessageId)
 Set objWMIService=Nothing
 End Function

(Hinweis: dieser Blog-Artikel stellt keine fertige End-to-End-Lösung dar. Es soll nur prinzipiell gezeigt werden, wie ein ConfigMgr-Problem identifiziert und gelöst werden kann. Skript-Anpassungen können pro Umgebung ggfs. nötig sein.)

Möchte man sich zu einer Windows Internal Database (WID) verbinden (wie sie z.B. von WSUS verwendet wird, wenn keine “echte” SQL-Datenbank verwendet wird), so ist das mit dem SQL Management Studio möglich. Man muß sich nur mit dem SQL Management Studio auf die entsprechende WID-Instanz verbinden:

TSQL WID

 

Mit ConfigMgr 2012 kann es bei der Hardware Inventur auf Windows Server 2003 (x86) Clients dazu kommen, daß die WMI abstürzt (“Faulting application wmiprvse.exe”). Ein Bug bei der Inventarisierung der Klasse CCM_RecentlyUsedApps ist dafür verantwortlich.
Workaround: Deaktivierung dieser HINV-Klasse auf den betroffenen Clients.
Das Problem ist bei Microsoft bekannt und wird in CU1 für SP1 einfließen. (Erscheinungsdatum noch nicht bekannt)

In letzter Zeit fällt mir in Blogs, Foren, etc. auf, daß in vielen ConfigMgr 2012-Infrastrukturen eine CAS (Central Administration Site) zum Einsatz kommt. In vielen Fällen wäre dies aber gar nicht nötig gewesen. Eine der ConfigMgr 2012 Features – Vereinfachung der Hierarchie und entsprechend eine Reduktion der Anzahl der Site Systeme – ist damit leider nicht berücksichtigt worden.
Oftmals wird / wurde eine CAS installiert, weil man ja bei SCCM 2007 schon eine Central Site hatte. Diese Schlußfolgerung ist in den meisten Fällen aber falsch. Central Adminsitration Site (CM12) != Central Site (CM07).

Insgesamt gibt es nur wenige Gründe, wirklich eine CAS einzusetzen. Der wichtigste ist die Gesamtanzahl zu verwaltender Clients:
Eine standalone Primary Site kann bis zu 100.000 Clients verwalten. Eine CAS wird erst dann zwingend nötig, wenn man diese Anzahl überschreitet.
Oftmals wurde auch eine CAS nur “für den Fall der Fälle” installiert, falls man doch irgendwann, vielleicht einmal eine CAS brauchen sollte (Expansion der Firma, Zukauf einer weiteren, etc). Spätestens mit Service Pack (SP) 1 ist auch dieses Argument entkräftet. Bei RTM war es nicht möglich, eine bestehende Primary zu einer CAS hinzuzufügen. Mit SP1 hingegen kann eine bestehende Primary zu einer neuen CAS hinzugefügt werden.
Ansonsten sollte man sich gut überlegen, ob man nicht auch mit einer Standalone Primary Site auskommt. Neue Funktionen wie Secondary Sites (die bis zu 5.000 Clients unterstützen), sender-enabled Distribution Points, Pull-DPs (SP1) oder Branch Cache bieten viele interessante Möglichkeiten, die bei der Versorgung von entfernten Standorten unterstützen. Man spart sich dadurch Hardware, Kosten und Komplexität (SQL-Replikation / DRS (Data Replication Service).

Bei der Planung einer Hierarchie spielen sehr viele Faktoren eine Rolle, die natürlich alle untersucht werden müssen und den Rahmen eines einzigen Blog-Artikels sprengen. Dieser Artikel soll einfach als Anstoß dienen, den Einsatz einer CAS kritisch zu hinterfragen. Keep it simple!

Mit dem Service Pack 1 (SP1) für System Center 2012 Microsoft Configuration (SCCM / ConfigMgr) kommen endlich auch Powershell-cmdlets zur einfacheren Automatisierung.
Doch wo sind diese cmdlets zu finden? Wo fängt man an?

Möglichkeit 1: starten von Powershell durch die ConfigMgr AdminConsole (“Connect via Windows PowerShell”):

SP1-PoSh-01

Danach öffnet sich PowerShell und man kann sofort cmdlets ausführen:

SP1-PoSh-02
Möglickkeit 2:
Starten der PowerShell ISE (x86!)
Importieren des ConfigMgr-Moduls (ConfigurationManager.psd1 im \bin-Verzeichnis der AdminConsole) und
Verbinden zur Site (cd “<Sitecode>:”):

SP1-PoSh-03

Eine Liste aller verfügbaren cmdlets findet man online unter http://technet.microsoft.com/en-us/library/jj821831.aspx oder per Get-Command -Module ConfigurationManager.

Ältere Artikel »