SCCM/SMS & PowerShell: Introduction (1/3)

avril 11, 2011
images Scripter autour de SCCM/SMS n’est pas chose facile. On trouve sur internet quelques scripts VBS mais la documentation reste assez pauvre.
Concernant Powershell, c’est encore plus vrai car il n’existe que très peu d’exemples concrèts.

Je vais donc essayer de combler ce manque ne vous proposant un exemple concrèt: automatiser l’export des objects Query en provenance de SMS et les réimporter dans SCCM.

Je vais vous montrer comment utiliser à la fois les objects de type WMI et les objects en provenance des librairies SCCM.

A. Par où commencer?

Dans un premier temps, il faut se procurer le SDK de SCCM: System Center Configuration Manager 2007 Software Development Kit (SDK) v4.0

Cette documentation est votre seul véritable aide. Elle est fournie d’exemples de tout type et le plus intéressant est qu’ils sont écrits en C# et Vb.net.

Comme Powershell est un language pure .Net, il est très facile de porter les exemples.

B. Première étape: Chargement des librairies SCCM dans notre script PowerShell

Pour pouvoir controller SCCM au travers de Powershell, il va falloir utiliser les objects mis à notre disposition dans les librairies adéquates:

  • adminui.wqlqueryengine.dll
  • microsoft.configurationmanagement.managementprovider.dll

Vous les trouverez dans le répertoire d’installation de SCCM: C:\Program Files (x86)\Microsoft Configuration Manager\AdminUI\bin

Pour pouvoir les charger en Powershell, il faut les charger à partir de la méthode LoadFrom du name space System.Reflection.Assembly.

Ce qui nous donne ceci:

[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Microsoft Configuration Manager\AdminUI\bin\adminui.wqlqueryengine.dll")
[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Microsoft Configuration Manager\AdminUI\bin\microsoft.configurationmanagement.managementprovider.dll")

C. Seconde étape: Récupérer les objects Query de notre environement SMS

Pour ce faire, nous allons utiliser une connection et des objects de type WMI, ce qui nous évitera de trop nous compliquer la tâche et de cette manière vous aurez également un exemple de ce type de connection.

Toute la magie de cette connection se situe dans cette ligne de commande:

Get-WmiObject -ComputerName $oSrv -Namespace $smsSiteCode -Query "select * from SMS_Query"

ComputerName: Nom du server SMS

NameSpace: Localisation des objects SMS en WMI (ex: root\SMS\Site_001)

Query: Query de type WQL vous permettant de récupérer les objets dont vous avez besoin.

Voici une fonction vous permettant de récuperer l’ensemble des objects Query et de les exporter dans un fichier CSV.

Function ExportQuery ([string]$oSrv, [string]$oSc, [string]$oFile) {
$smsSiteCode = "root\SMS\Site_" + $oSc
$oQuerySms = Get-WmiObject -ComputerName $oSrv -Namespace $smsSiteCode -Query "select * from SMS_Query"
$oQuerySms | select-object Name, Comments, QueryID, TargetClassName, Expression | Export-Csv $oFile -Delimiter ";"
write-host "Queries exported from SMS: " $oQuerySms.Length "item(s)"
}

D. Troisième étape: Importer notre fichier CSV dans SCCM

Le fait d’avoir précédement charger les librairies SCCM dans notre script PowerShell va nous permettre maintenant de les utiliser.

Nous allons dans un premier temps nous connecter à SCCM:

Function ConnectionSCCM(){
$nameValues = New-Object -TypeName microsoft.configurationmanagement.managementprovider.SmsNamedValuesDictionary
$script:conSCCM = New-Object -TypeName microsoft.configurationmanagement.managementprovider.WqlQueryEngine.WqlConnectionManager -ArgumentList $nameValues
$script:conSCCM.Connect([system.Net.dns]::GetHostName().ToUpper())
}

Nous allons ensuite lire notre fichier CSV et importer chaque query dans SCCM

Function ImportQuery($collData) {
foreach ($elem in $collData){
# Query Creation
$oQuery = $script:conSCCM.CreateInstance("SMS_Query")

# Populate Data
$oQuery["Comments"].StringValue = $elem.Comments.ToString()
$oQuery["Expression"].StringValue = $elem.Expression.ToString()
$oQuery["LimitToCollectionID"].StringValue = $elem.LimitToCollectionID
$oQuery["Name"].StringValue = $elem.Name.ToString()
$oQuery["TargetClassName"].StringValue = $elem.TargetClassName.ToString()
$oQuery.put()
$oQuery.Get()
write-host "SCCM: New query ID: " $oQuery["QueryID"].StringValue
}
Write-Host "Queries imported to SCCM: " $collData.Length "item(s)"
}

E. Exemple complet

Ce script doit être exécuté à partir du server SCCM. Si vous voulez l’utiliser à partir d’une station de management, assurez vous des points suivants:

  • Les librairies se trouvent également sur la station de management
  • Votre compte utilisateur à les droits suffisants pour accéder aux informations de SCCM et SMS.
#=========================================================================
#
#NAME: PS-QueryMigrator
#
#VERSION: 1.0
#AUTHOR: Malfroidt Olivier
#DATE: 05/04/2011
#
#COMMENT:
#
#=========================================================================

#*****************
#Arguments
#*****************
param ([string]$mode, [string]$file, [string]$smsSrv, [string]$siteCode)

#*****************
#Assemblies
#*****************
[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Microsoft Configuration Manager\AdminUI\bin\adminui.wqlqueryengine.dll")
[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Microsoft Configuration Manager\AdminUI\bin\microsoft.configurationmanagement.managementprovider.dll")

#*****************
#Variables
#*****************
$conSCCM = $null
$importedQueries = @()

#*****************
#Functions
#*****************

#*************
#HelpMessage
#*************

Function HelpMsg()
{
$helpText=@"

Name: PS-QueryMigrator - v1.0 Release

Usage:
PS-QueryMigrator -mode [IMPORT | EXPORT] -file [filename] [-smsSrv [server name] -siteCode [SMS site code]]

Options:
Mandatory
-mode [IMPORT | EXPORT]: Specify if you want import data to SCCM or export data from SMS
-file [Filename]: Desination file if you export data and Source file if you import data.
Optionnal
-smsSrv [ServerName]: In case of Export mode, you must specify the SMS Server name.
-siteCode [SMS Site code]: In case of Export mode, you must specify the SMS Site code.

"
@
$helpText
exit
}

Function ConnectionSCCM(){
$nameValues = New-Object -TypeName microsoft.configurationmanagement.managementprovider.SmsNamedValuesDictionary
$script:conSCCM = New-Object -TypeName microsoft.configurationmanagement.managementprovider.WqlQueryEngine.WqlConnectionManager -ArgumentList $nameValues
$script:conSCCM.Connect([system.Net.dns]::GetHostName().ToUpper())
}

Function CloseConnSCCM(){
$script:conSCCM.Close()
}

Function ConnectionSMS(){

}

Function ImportQuery($collData) {
foreach ($elem in $collData){
# Query Creation
$oQuery = $script:conSCCM.CreateInstance("SMS_Query")

# Populate Data
$oQuery["Comments"].StringValue = $elem.Comments.ToString()
$oQuery["Expression"].StringValue = $elem.Expression.ToString()
$oQuery["LimitToCollectionID"].StringValue = $elem.LimitToCollectionID
$oQuery["Name"].StringValue = $elem.Name.ToString()
$oQuery["TargetClassName"].StringValue = $elem.TargetClassName.ToString()
$oQuery.put()
$oQuery.Get()
write-host "SCCM: New query ID: " $oQuery["QueryID"].StringValue
}
Write-Host "Queries imported to SCCM: " $collData.Length "item(s)"
}

Function ExportQuery ([string]$oSrv, [string]$oSc, [string]$oFile) {
$smsSiteCode = "root\SMS\Site_" + $oSc
$oQuerySms = Get-WmiObject -ComputerName $oSrv -Namespace $smsSiteCode -Query "select * from SMS_Query"
$oQuerySms | select-object Name, Comments, QueryID, TargetClassName, Expression | Export-Csv $oFile -Delimiter ";"
write-host "Queries exported from SMS: " $oQuerySms.Length "item(s)"
}

#*****************
#Main
#*****************

try{
if (($mode -ne "") -and ($file -ne "")) {
switch ($mode.ToUpper()){
"IMPORT" {
Write-Host "Queries import to SCCM: Job start"
$importedQueries = import-csv $file -Delimiter ";"
ConnectionSCCM
ImportQuery $importedQueries
CloseConnSCCM
Write-Host "Queries import to SCCM: Job done"
}
"EXPORT" {
if (($smsSrv -ne "") -and ($siteCode -ne "")) {
Write-Host "Queries export from SMS: Job start"
ExportQuery $smsSrv  $siteCode $file
Write-Host "Queries export from SMS: Job done"
} else {
Write-Host "EXPORT ERROR: Incorrect arguments provided" -ForegroundColor Red
HelpMsg
}
}
Default {
HelpMsg
}
}
}else{
Write-Host "GENERAL ERROR: Incorrect arguments provided" -ForegroundColor Red
HelpMsg
}

}catch {
Write-Host -ForegroundColor Red "CRITICAL ERROR: " $Error[0]
}

F. Conclusion

Cet exemple peut facilement être adapté pour travailler avec d’autres objects tel que les collections, advertisments, reports, packages, ….

Le SDK vous sera d’une aide précieuse pour connaitres les objets, méthodes et propriétés nécessaires pour réaliser votre script.

Enjoy !!!

It's only fair to share...Share on Facebook

Leave a Reply