ConfigMgr: Powershell Script

Generell baue ich eine Configuration Manager Umgebung so auf, dass ich pro zu verteilender Software eine eigene Collection einrichte. Diese wird unterhalb eines Ordner _Software und darunter in einem Ordner mit dem Namen des Herstellers abgelegt. In diese Device Collection kommen dann die Clients, die die Software erhalten sollen.

So erhält man die maximale Flexibilität, auch wenn man am Anfang wahrscheinlich das meiste an die gleiche Gruppe von Clients verteilt.

Um diesen Ablauf zu vereinfachen, habe ich ein kleines Powershell Script geschrieben, dass die Ordner und die Collection entsprechend anlegt.

Der Aufruf erfolgt mittels:

.\createSWCollection.ps1 -vendor "Adobe" -software "Flash Player 14" -site MBK -siteserver cm01

Loading ConfigMgr Module  D:\Program files\ConfigMgr\bin\ConfigurationManager.psd1
Collection Flash Player 14 successfull created. ID:MBK00011

Das gesamte Script hat einige nützliche Funktionen, die ich auch in anderen Powershellscripte verwende:

[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Vendor,
[Parameter(Mandatory=$true)]
[string]$Software,
[Parameter(Mandatory=$true)]
[string]$Site,
[Parameter(Mandatory=$true)]
[string]$Siteserver,
[Parameter(Mandatory=$false)]
[string]$rootFolder="_Software"
)


 #Load the ConfigurationManager Module

 #from http://www.dexterposh.com/2014/06/powershell-sccm-2012-getting-started.html
try
{
    $ConfigMgrModule = "$($env:SMS_ADMIN_UI_PATH | Split-Path -Parent)\ConfigurationManager.psd1"
    if (!(Test-Path $ConfigMgrModule)) {
        throw 'Configuration Manager module not found in admin console path'
    }
    write-host "Loading ConfigMgr Module " $ConfigMgrModule
    Import-Module $ConfigMgrModule
    $BeforeLocation = (Get-Location).Path
} catch 
{
   Write-Error $_.Exception.Message        
}

cd $site":"

$updateCollectionMin=30
$limitingCollection="All Systems"


$namespace="root\SMS\Site_$site"
$PSDefaultParameterValues =@{
    "get-cimclass:namespace"="Root\SMS\site_$site";
    "get-cimclass:computername"=$siteserver;
    "get-cimInstance:computername"=$siteserver;
    "get-ciminstance:namespace"="Root\SMS\site_$site";
    "get-wmiobject:namespace"="Root\SMS\site_$site";
    "get-WMIObject:computername"=$siteserver}

 $rootDeviceFolder=Get-CimInstance -ClassName SMS_ObjectContainerNode -Filter "ObjectType=5000 and ParentContainerNodeid=0"
 
 function getFolder([String]$name,[int]$parentID,[bool]$deviceFolder=$true) {
   if ($deviceFolder) {
       $objectTyp=5000
    } else {
     $objectTyp=6000
    }
    Get-CimInstance -ClassName SMS_ObjectContainerNode -Filter "ObjectType=$objectTyp and ParentContainerNodeid=$parentID and Name='$name'"
 }
 

 function createFolder([String]$name,[int]$parentID,[bool]$deviceFolder=$true)
 {
    if ($deviceFolder) {
       $objectTyp=5000
    } else {
     $objectTyp=6000
    }
    $rt=getfolder $name $parentID $deviceFolder
    if (-not $rt) {
        $rt=New-CimInstance -ClassName SMS_ObjectContainerNode -Property @{Name=$name;ObjectType=$objectTyp;ParentContainerNodeid=$parentID;SourceSite=$site} -Namespace $namespace -ComputerName $siteserver 
        Write-Host "Folder $name successfull created."
    }
    else
    {
        write-verbose "Folder $name already exists."
    }
    $rt
 }

 function createFolderPath([String]$folderPath,[int]$parentID,[bool]$deviceFolder=$true)
 {
    if ($deviceFolder) {
       $objectTyp=5000
    } else {
     $objectTyp=6000
    }
    $folders=$folderPath.split('\')
    $parentID=0
    $folders | ForEach-Object {
       $folder=$_
       $rt=createFolder $folder $parentID $true
       $parentID=$rt.ContainerNodeID
    }
    $rt
 }
 
 #$rootDeviceFolder


 $folderpath=$rootFolder+"\$vendor"
 $targetFolder=createFolderPath $folderpath 0 $true

 $collection=Get-CMDeviceCollection -name $software
 if (-not $collection) {
    $collection=New-CMDeviceCollection -Name $software -Comment "Software Deployment Target for $software" -LimitingCollectionName $limitingCollection  -RefreshType Periodic -RefreshSchedule (New-CMSchedule -Start (get-date) -RecurInterval Minutes -RecurCount $updateCollectionMin) 
    write-host ("Collection $software successfull created. ID:"+$collection.CollectionID)

 }
else
{
    write-verbose ("Collection $software already exists. ID:"+$collection.CollectionID)
}
Move-CMObject -FolderPath ($site+":\DeviceCollection\"+$folderpath) -InputObject $collection

cd $BeforeLocation
m4s0n501
Posted in Configuration Manager, Deutsch, Powershell, System Center, System Center 2012 | Tagged , | Leave a comment

ConfigMgr: Softwareverteilung

Im Bereich Softwareverteilung gibt es mehrere Möglichkeiten eine Software auszuführen und zu verteilen:

  • Im Deploymenttype im Bereich User Experience steht Installation behavior auf:
    • Install for System
    • Install for User
    • Install for system if resource is device; otherwise install for user
  • Zielcollection ist vom Typ:
    • Device Collection
    • User Collection

Continue reading

Posted in Configuration Manager, Deutsch, System Center, System Center 2012 | Tagged | Leave a comment

OpsMgr: Neue Management Packs seit März 2014

Neue Management Packs im Zeitraum zwischen 09.03.2014 und 12.10.2014

Message Queuing

Active Directory

DHCP

DNS

Microsoft Dynamics

Operating System

Posted in Active Directory Domain Service, Deutsch, Operations Manager, System Center, Windows | Tagged , , , | Leave a comment

ConfigMgr: Cumulative Update 3 für ConfigMgr 2012 R2 verfügbar

Das dritte kumulative Update für den System Center 2012 R2 Configuration Manager (ConfigMgr) ist seit gestern verfügbar.

Wie üblich sind einige Probleme korrigiert worden.  Nennenswert sind aus meiner Sicht folgende Punkte:

  • Unknown x64 UEFI Computer werden fehlerhafter Weise auf x86 Unknown Computer gemappt
  • SMS Agent Host kann während einer Task Sequenz unerwartet abstürzen
  • Änderungen an den Eigenschaften eines Distribution Points können dazu führen, dass im IIS Log kein Datum und Uhrzeit mehr protokolliert wird

Ungewöhnlicher Weise gibt es in diesem CU 3 eine neue Funktionalität:

Bis jetzt habe ich Kunden immer davon abgeraten an Remotestandorten Management Points (MP) einzusetzen, da diese nicht standortbezogen sind. Ein Client bekommt somit eine Liste aller MPs in der Site und geht diese alphabetisch durch, bis er einen erreichbaren gefunden hat. Workarounds mit Firewallsperrungen, um den Client nur auf seinen am Standort vorhandenen MP zu lassen, sehe ich nicht wirklich als elegant an.

Einen ersten Schritt Richtung Site Awareness macht jetzt das CU3, denn es führt auf dem Client  einen Registry Key, mit dem definiert wird, auf welche Management Points der Client zugreifen darf. Es handelt sich dabei um einen eher ungewöhnlichen REG_MULTI_SZ Key, der mittlerweile direkt über regedit erzeigt werden kann:

image

Alternativ ist dies auch über reg.exe möglich:

reg.exe ADD "HKEY_LOCAL_MACHINE\Software\Microsoft\CCM" /v AllowedMPs /t REG_MULTI_SZ /d "MP1\0MP2\0MP3\0"

In seinem Sitesetup sollte man trotzdem bedenken, dass ein MP immer auf die Sitedatenbank zugreifen muss. Alternativ ist hier ein Replikat der Sitedatenbank an dem entfernten Standort möglich.

Posted in Configuration Manager, Deutsch, System Center, System Center 2012 | Tagged , , | Leave a comment

OpsMgr, SCSM: Sortierhilfe für Management Pack Autoren

Erstellt man eigene Management Packs (MP) für den Operations Manager (OpsMgr) oder den Service Manager (SCSM), so kommt es regelmäßig vor, dass er beim Öffnen eine bestimmte Version eines abhängigen MPs haben möchte. Wurde das neue Management Pack in einer Umgebung erstellt, die ein aktuelles Update Rollup eingespielt hat, so wird u.U. genau dieser benötigt.

Daher habe ich mir für meine tägliche Arbeit in einer Ordnerstruktur mit diversen Management Packs aufgebaut. Als Ordnername wird die Versionsnummer verwendet. Möchte das Authoring Studio somit die Version 1.0.1, kann ich in den Ordner wechseln und sehe direkt alle MPs mit dieser Version bzw. aufgrund des Filters im Dialog direkt das benötigte File.

Gerade bei den vielen MPs von Microsoft ist es schwer, diese Struktur manuell zu pflegen. Erschwerend kommt hinzu, dass man an der .mp Datei nicht direkt sieht, welche Version es ist. (Kleiner Tipp am Rande: Dateiendung .dll anfügen und dann ist im Eigenschaftendialog die Versionsnummer sichtbar).

Daher habe ich mir das nachfolgende Powershell geschrieben, dass signierte MP-Files, unsignierte XML-Files und Managementpack Bundles (.mpb) in entsprechende Ordner einsortiert.

Bei mpb Files verwende ich ein Workaround, da ich das erste File (Index 0) extrahiere und auf Basis davon die Einsortierung vornehme.

 


$sourcePath="E:\_Tools\OpsMgr\MP Library"
$targetPath=$sourcePath
$filter=$sourcepath+"\*"
get-childitem $filter -include *.mp | foreach-object {
$name=$_
$version=[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_).FileVersion
new-item -path . -name $version -itemtype Directory
$source=$name
$target=$targetPath+"\"+$version
"Moving from $source to $target"
move-item -path $source -destination $target
}

get-childitem $filter -include *.xml | foreach-object {
$name=$_
$version=(select-xml -path $name -XPath "/ManagementPack/Manifest/Identity/Version").Node.InnerXML
new-item -path . -name $version -itemtype Directory
$source=$name
$target=$targetPath+"\"+$version
"Moving from $source to $target"
move-item -path $source -destination $target
}

get-childitem $filter -include *.mpb | foreach-object {

import-module pscx
$name=$_
$version=""
"Extracting XML from $name"
expand-archive $name -Index 0
$xml=[System.IO.Path]::GetFileNameWithoutExtension($name)+".xml"
"Using $xml"
$version=(select-xml -path $xml -XPath "/ManagementPack/Manifest/Identity/Version").Node.InnerXML
remove-item $xml
new-item -path . -name $version -itemtype Directory
$source=$name
$target=$targetPath+"\"+$version
"Moving from $source to $target"
move-item -path $source -destination $target
}
Posted in Deutsch, Operations Manager, Service Manager, System Center, System Center 2012 | Tagged , , | Leave a comment