Sunday, March 30, 2014

PowerShell + SCCM 2012 R2 : Create an Application (from MSI) & Deploy it

This is one of the many posts to follow on my experiments with the new Application Model introduced in Configuration Manager 2012.

In this post will use PowerShell to create a new application, deployment type (from a MSI) and then finally deploy it to a machine. So without further delay.....

Let's get to it 

Create the Application using New-CMApplication cmdlet:


New-CMApplication -Name "Quest Active Roles Managment Shell for AD" -Description "Quest Snapin for AD Admins (64-bit only)" -SoftwareVersion "1.51" -AutoInstall $true

The above will create a Application Object in ConfigMgr which can be used in Task Sequences as well (-AutoInstall $true ). Now let's open the Console and have a peek at the properties of the Application created.




The Set-CMApplication Cmdlet can also be used to set property on the Application Object later. 


Let's create a new App Category and then add the above application to it.


New-CMCategory -CategoryType AppCategories -Name "ADAdministration" -Verbose


Set-CMApplication -Name "Quest Active Roles Managment Shell for AD"  -LocalizedApplicationName "Quest AD Snapin"  -LocalizedApplicationDescription "PowerShell Snapin to be used by AD Admins" -AppCategories "ADAdmins" -SendToProtectedDistributionPoint $true -Verbose

Note the Localized Display Name & Description appears in the Software Center/ Catalog.
Wait ! When you try to run the second cmdlet you would encounter an error
if on the console you have properties opened :




This is by design as Application is one of the globally replicated Objects and before someone tries to edit it they need to request lock on the Object.
Read more about SEDO here and want to know how to request SEDO Locks using PowerShell then go to MVP Kaido's post here

Close the open properties of the Application if any and then try again and the second cmdlet will work.

As a mental note will try to look more into SEDO Locks later.


Create the DeploymentType (Auto from MSI File)

Once the application is created we need to create the Deployment type for it . Note in CM 2012 there can be multiple deployment types targeting various devices but here we will take a look at the default one that gets created when we specify a MSI file.

Now the cmdlet is Add-CMDeploymentType :


Add-CMDeploymentType -ApplicationName "Quest Active Roles Managment Shell for AD" -InstallationFileLocation "\\dexsccm\Packages\QuestADSnapin\Quest_ActiveRolesManagementShellforActiveDirectoryx64_151.msi" -MsiInstaller -AutoIdentifyFromInstallationFile -ForceForUnknownPublisher $true -InstallationBehaviorType InstallForSystem



Note the use of parameter -AutoIdentifyFromInstallationFile and -ForceForUnkownPublisher $True here. These parameters corresponds to what one would normally do when using GUI to create the Application (default way of creating Apps).

This will create the Deployment type with appropriate configuration and if you want to change something later take a look at the Set-CMDeploymentType cmdlet.


Distribute the Content 

Before we start deploying the Application to the Devices, we need to distribute the package to the DP or DP Group. The cmdlet here is Start-CMContentDistribution

Start-CMContentDistribution -ApplicationName "Quest Active Roles Managment Shell for AD" -DistributionPointGroupName "Dex LAB DP group" -Verbose

Now once the Content is Distributed then we can go ahead and deploy the Application.

Create a Collection for the Application and Deploy the Application to it

As a standard practice, I will create a Device Collection by the name of the Application and add members to it where the Application ultimately gets deployed to.

Create the Device Collection to refresh every day at the moment when it is created (that is what New-CMSchedule cmdlet does)

New-CMDeviceCollection -Name "Quest Active Roles Managment Shell for AD" -Comment "All the Machines where Quest AD Snapin is sent to" -LimitingCollectionName "All Systems"  -RefreshType Periodic -RefreshSchedule (New-CMSchedule -Start (get-date) -RecurInterval Days -RecurCount 7) -Verbose



Now Add the machine name to the Collection in a Query MemberShip Rule or Direct MemberShip Rule. For this just using Direct membership rule for now. In the upcoming post will go with Query Membership Rule.


Add-CMDeviceCollectionDirectMembershipRule -CollectionName "Quest Active Roles Managment Shell for AD"  -Resource (Get-CMDevice -Name "DexterDC") -Verbose



Now the collection is created let's deploy the Application to this Collection's member.


Start-CMApplicationDeployment -CollectionName "Quest Active Roles Managment Shell for AD" -Name "Quest Active Roles Managment Shell for AD" -DeployAction Install -DeployPurpose Available -UserNotification DisplayAll -AvaliableDate (get-date) -AvaliableTime (get-date) -TimeBaseOn LocalTime  -Verbose

Done.

Now we can refresh the Machine Policy on the Members of the Collection by using the old WMI way of connecting to the Client machine through WMI and calling the triggerSchedule method or use Client Notification (which is a great new feature) which will ensure that the Application reaches end machine quickly.


Invoke-CMClientNotification -DeviceCollectionName "Quest Active Roles Managment Shell for AD" -NotificationType RequestMachinePolicyNow -Verbose

After all done let's run the Summary of the Deployment:


Invoke-CMDeploymentSummarization -CollectionName "Quest Active Roles Managment Shell for AD" -Verbose

After this we can see the results in the summary of the Deployment:



And the Application does shows up on the end Machine:




Creating various types of Applications & Packages (Classic ones) are the next in my post list.

Below is the consolidated Gist:

27 comments:

  1. Replies
    1. Thanks Sathya :) for the kind words.

      Delete
  2. Great Script. I have modified my copy slightly to add variables at the top to make it more modular. Have you made any progress on the non-MSI install script? I am adding a section to mine for this function but wondered if you had made any headway on yours.

    ReplyDelete
    Replies
    1. Hey Joshua,

      Play with the code and wrap it into a more generic advanced function.
      It has been long since I have done anything with ConfigMgr.

      Drop me an email, in case you need help with the Code :)

      Delete
  3. wow nice script helps me a lot anyone a solution how to add multiple AppCategories I was unable to do it only one will be added..

    ReplyDelete
    Replies
    1. Hi there,

      If you take a look at the help for the parameter -AppCategories at the link -> https://technet.microsoft.com/en-us/library/jj821745(v=sc.20).aspx

      You will see that it says:
      Set-CMApplication -Id [-AppCategories ]

      The parameter takes an array, so I think it can be done by passing an array of Appcategories to the cmdlet like below :
      Set-CMApplication -Name "Quest Active Roles Managment Shell for AD" -LocalizedApplicationName "Quest AD Snapin" -LocalizedApplicationDescription "PowerShell Snapin to be used by AD Admins" -AppCategories "ADAdministration" ,"AppCategory2"

      Delete
    2. thank you for the feedback this is what i tried

      Set-CMApplication -name "IRIST CT Test AppCat" -LocalizedApplicationName "IRIST CT Test AppCat" -AppCategories "Env P","Env Q"

      but results in...

      Set-CMApplication : ConfigMgr Error Object:
      instance of __ExtendedStatus
      {
      Operation = "ExecQuery";
      ParameterInfo = "SELECT * FROM SMS_CategoryInstance WHERE CategoryTypeName='AppCategories' and
      LocalizedCategoryInstanceName in ('Env P';'Env Q')";
      ProviderName = "WinMgmt";
      };
      Error Code:
      InvalidQuery
      In Zeile:1 Zeichen:1
      + Set-CMApplication -name "IRIST CT Test AppCat" -LocalizedApplicationName "IRIST ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : NotSpecified: (Microsoft.Confi...licationCommand:SetApplicationCommand) [Set-CMApplicati
      on], WqlQueryException
      + FullyQualifiedErrorId : UnhandledExeception,Microsoft.ConfigurationManagement.Cmdlets.AppMan.Commands.SetApplica
      tionCommand

      hope anyone have a good hint..

      Delete
    3. I finally tried this and it work on the CM Module I have on my machine (updated the module using Cmdlet Library).

      PS DEX:\> Get-Module ConfigurationManager | select name,version

      Name Version
      ---- -------
      ConfigurationManager 5.0.8249.1128

      PS DEX:\> Set-CMApplication -Name Notepad++ -AppCategory 'PSCreatedApps','OpenSource'
      PS DEX:\> Get-CMApplication -Name Notepad++ | select *category*

      CategoryInstance_UniqueIDs LocalizedCategoryInstanceNames PlatformCategoryInstance_UniqueIDs
      -------------------------- ------------------------------ ----------------------------------
      {AppCategories:28762b10-1b9d-49bd-84... {PSCreatedApps, OpenSource} {}

      Delete
    4. Check this one out, if you are still not able to get this working with the CM Cmdlet.

      http://www.dexterposh.com/2015/11/powershell-sccm-wmi-scripting.html

      Delete
  4. The AppCategories... my last part prevent of a fully automation hope you have me a solution...

    ReplyDelete
  5. i search too the big hint for add multiple AppCategories :(

    ReplyDelete
    Replies
    1. Wow, this is really a sought after thing. I don't work with ConfigMgr anymore but will give it a try.

      Delete
    2. Hey Guys,

      Can you try this and let me know , it seems to work for me :
      PS DEX:\> Get-Module ConfigurationManager | select name,version

      Name Version
      ---- -------
      ConfigurationManager 5.0.8249.1128

      PS DEX:\> Set-CMApplication -Name Notepad++ -AppCategory 'PSCreatedApps','OpenSource'
      PS DEX:\> Get-CMApplication -Name Notepad++ | select *category*

      CategoryInstance_UniqueIDs LocalizedCategoryInstanceNames PlatformCategoryInstance_UniqueIDs
      -------------------------- ------------------------------ ----------------------------------
      {AppCategories:28762b10-1b9d-49bd-84... {PSCreatedApps, OpenSource} {}

      Delete
    3. I did a post around this problem to be tackled with WMI only.
      If the cmdlet method still doesn't workout, you can follow that path:
      http://www.dexterposh.com/2015/11/powershell-sccm-wmi-scripting.html

      Delete
  6. Great post Dexter :)

    I had to remove and re-add some deployment today on tons of Collections.

    Weird they call it Start-CMDeploymentApplication, Start ? Should it be New ? What do you think ?

    ReplyDelete
    Replies
    1. Thanks FX Sir :)

      I think the verb should be "Start" as the cmdlet actually starts pushing out advertisements to the remote machines.

      Delete
  7. Great script!!!

    Would be really nice if you could show some examples with other application types (scripted installation, .exe, app-v) and also other detestion rules like Registry, File and Manual Windows Installer.

    I'm creating a tool for automation of application creation and deployment i CM and would really need some help with the above.

    ReplyDelete
    Replies
    1. Can you drop me a mail (through the contact widget at the bottom) on the exact scenario ?
      I can spin out some time and do a post on what you are looking for.

      Delete
  8. How can we set the requirements tab?

    ReplyDelete
    Replies
    1. There is a way mentioned in the SDK. Check that out.

      Delete
  9. Hello
    thank you for all
    I have a question
    I retrieved the information from an application with the command Get-Cmapplication - name "****"
    After I deleted this Application (****)
    How to remix this application (****) in production with powershell

    I'm really stuck on this subject
    Thank you for your help

    ReplyDelete
    Replies
    1. Hi there,

      Sorry, I do not understand your question.
      "How to remix this application?"

      What does remix mean here?

      Delete
  10. Gosh, you've just saved my life!

    ReplyDelete
  11. Thank you very much, it worked like a charm for me!

    ReplyDelete
    Replies
    1. You're welcome.
      Thanks for the comment.

      Delete