Application won’t download Content

In my previous post I had a script that creates the application. Everything looked fine but when trying to install SCCM could not find the source so it was thinking it was locally availble. Although I added content to the application it was missing content. Reason was that the object did not create a reference to the application. So the following lines should also be added to add content to the deployment type.

$newContentref  =  New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ContentRef
$newContentref.ID  = $newApplicationContent.Id
$newDeploymentType.Installer.InstallContent =  $newContentref

Creating an SCCM 2012 Application with PowerShell

With SCCM 2007 it was easy to import a package with PowerShell. For now it is a little bit tricky to accomplish it. In this post I will try to explain how you can create an application in SCCM 2012. This has been tested with the Release Candidate 2.

To create an application with powershell first you have to install the Admin Console. And load assemblies in your powershell script.

function Import-SCCMAssemblies($SCCMAdminConsolePath){
$path = "$SCCMAdminConsolePath\Microsoft.ConfigurationManagement.ApplicationManagement.dll"
if (Test-Path $path) { $t = [System.Reflection.Assembly]::LoadFrom($path)}

$path = "$SCCMAdminConsolePath\Microsoft.ConfigurationManagement.ApplicationManagement.Extender.dll"
if (Test-Path $path) { $t = [System.Reflection.Assembly]::LoadFrom($path)}

$path = "$SCCMAdminConsolePath\Microsoft.ConfigurationManagement.ApplicationManagement..MsiInstallerdll"
if (Test-Path $path) { $t = [System.Reflection.Assembly]::LoadFrom($path)}

Next step is to get the ScopeID of you SCCM Site server. How to do this can be found in my previous blog

Now you can create an application XML file with the use of the assemblies we have loaded

    #Loading Assemblies to create an SCCM 2012 application
    Import-SCCMAssemblies "D:\Program Files\Microsoft Configuration Manager\AdminConsole\bin\"
    #Get Authoring ScopeID 
    $scopeid = Get-AuthoringScopeID $con
    #Create an unique id for the application and the deployment type
    $newApplicationID = "Application_" + [guid]::NewGuid().ToString() 
    $newDeploymentTypeID = "DeploymentType_" + [guid]::NewGuid().ToString()     
    #Create SCCM 2012 object id for application and deploymenttyo 
    $newApplicationID = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ObjectID($scopeid,$newApplicationID)   
    $newDeploymentTypeID = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ObjectID($scopeid , $newDeploymentTypeID) 
    #Create all the objects neccessary for the creation of the application
    $newApplication =  New-Object Microsoft.ConfigurationManagement.ApplicationManagement.Application($newApplicationID)    
    $newDeploymentType = New-Object  Microsoft.ConfigurationManagement.ApplicationManagement.DeploymentType($newDeploymentTypeID,"MSI")
    $newDisplayInfo  =  New-Object Microsoft.ConfigurationManagement.ApplicationManagement.AppDisplayInfo 
    $newApplicationContent = New-Object  Microsoft.ConfigurationManagement.ApplicationManagement.Content
    $newContentFile = New-Object  Microsoft.ConfigurationManagement.ApplicationManagement.ContentFile
    #Setting Display Info
    $newDisplayInfo.Title = $Application.DisplayName
    $newDisplayInfo.Language = $newApplication.DisplayInfo.DefaultLanguage
    $newDisplayInfo.Description = $Application.DisplayName
    $newDisplayInfo.Version = $Application.PRVersion 

    #Setting default Language must be set and displayinfo must exists
    $newApplication.DisplayInfo.DefaultLanguage = "en-US"

    $newApplication.Title = $APP.Title
    $newApplication.Version = 1
    #Deployment Type msi installer will be used
    $newDeploymentType.Title = "Deploy $($APP.DisplayName)"
    $newDeploymentType.Version = 1 
    $newDeploymentType.Installer.ProductCode = $APP.ProductCode 
    $newDeploymentType.Installer.InstallCommandLine = "Msiexec /i $($APP.MSIName) /qb-! Reboot=ReallySuppress"
    $newDeploymentType.Installer.InstallFolder  ="\"  
    $newDeploymentType.Installer.UninstallCommandLine = "Msiexec /x $($APP.ProductCode) /qb-! Reboot=ReallySuppress" 

    #Add the msi as content to the application

    #UPDATE: Add all content to the application
    $newApplicationContent = [Microsoft.ConfigurationManagement.ApplicationManagement.ContentImporter]::CreateContentFromFolder($APPUNCPath)

        #DELETE: $newContentFile.Name = $APP.MSIName
        #DELETE: $newApplicationContent.Files.Add($newContentFile)
        #DELETE: $newApplicationContent.Location = $APP.UNCPath
        $newApplicationContent.OnSlowNetwork = "Download"

    $newDeploymentType.Installer.Contents.Add($newApplicationContent )
    #Serialize the object to an xml file
    $newApplicationXML = [Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::SerializeToSTring($newApplication,$true)

So now we have an XML file with the data of the application. In this example we use an msi file. It is also possible to use a script or executable. then you have to set the deployment type to Script. Next step is to import the xml file.

        $applicationClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Application"
        $newApplication = $applicationClass.createInstance() 
        $newApplication.SDMPackageXML = $newApplicationXML 
        $tmp = $newApplication.Put()
        #Reload the application to get the daat 

Now we have created an application in SCCM 2012 with the use of PowerShell. The next step is to distribute and deploy the application to a collection.

The Unique Application ID

If you ask me the biggest change in SCCM 2012 is the backend. The DP and MP can be combined and it will use SQL replication (execpt for content). Another interresting change is the use of application. It’s an evolution of SCCM 2007 packages (still supporting in 2012).

First thing you have to take in mind is that application installation will run in 64-bit mode. Although you can also force to use 32-bit. the current packages still run in 32-bit mode and cannot run in 64-bit. So you can say that packages are obsolete.

If you look at the backend a package difference a lot from a package. Especially the unique id. Where you have a package id in package a applications has multiple unique keys.

  • First you have the CI_ID which is just a number. My guess is that this is site specific.
  •  The second key is what looks like a packageid. This key will be used for the content.
  •  The Third key is long descriptor that starts with scope_[guid]\application_[guid].
    First part is the unique identification of the site server and the second part is the unique id for the application. This key I guess will be used at the entire environment. But that has to be checked when RTM arrived.
$identificationClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Identification"
$cls = Get-WmiObject SMS_Identification -namespace $SccmServer.Namespace -ComputerName $SccmServer.Machine -list
$tmp = $identificationClass.GetSiteID().SiteID
return "ScopeId_$($tmp.Substring(1,$tmp.Length -2))"

I will update this post when more information and documentation is availble