The Application Catalog in System Center 2012 Configuration Manager allows users to browse, request, and install software that you make available to them. You might be wondering if you can tailor the Application Catalog capabilities to better suit your business requirements. The answer is yes, and this post provides some examples.
The Application Catalog website role includes the ASP.NET web service that runs alongside the catalog web page. This service supports Application Catalog operations, such as retrieving the list of applications or submitting application request.
The first step is to configure the web service to publish its interface so that connecting clients can use the service. To do that, locate the web.config file in the root of the physical folder for the Application Catalog website. The folder might appear in one of the following locations, based on your configuration:
Find the “webServices” section in web.config:
Modify web.config to delete <remove name=”Documentation”> node:
Then you can get the service reference from the following source (assuming the default virtual name for the Application Catalog website role):
- where <myserver> is the server hosting the Application Catalog website role.
If you are using Visual Studio, you can add a service reference to the Application Catalog, as shown in the following screenshot:
You should now be able to call the available service methods from your project. In this example, the soap client class will be generated under the “ApplicationCatalogService” namespace.
After you have created the service reference, you can call the web service methods to retrieve the list of categories and applications available to the user. Note that only the applications available in the Application Catalog will be returned.
Similarly, the following service call will retrieve the list of applications represented as AppDetailView objects:
In this case the Application Catalog will return the first 20 applications, sorted by Name.
Note that the Application Catalog website role requires Windows Authentication. Without impersonation, the soap client will pass information by using the current user context.
The next example shows how to create a script by using Windows PowerShell to submit the application request. Note that this example does not include the functionality necessary to provide the approval dialog box after the application is approved.
I recommend that you use the handy New-WebServiceProxy cmdlet in Windows PowerShell 2.0 to create a service reference on the fly, as follows:
# Create web service proxy
$catalogurl = "http://myserver/CMApplicationCatalog";
$url = $catalogurl+"/ApplicationViewService.asmx?WSDL";
$service = New-WebServiceProxy $url -UseDefaultCredential;
You can then call the service to retrieve the list of applications. For simplicity, this example picks the first application from the list. Alternatively, the application ID can be retrieved using SMS Provider or the Application Catalog. Note that the Application ID parameter for the Application Catalog methods does not have the version information.
# Retrieve the first 20 applications sorted by name
# Sample app id: "ScopeId_82A46150-9A71-421A-9645-AD4B92AF1B72/Application_295530ae-5755-48fc-a04b-c01c9631c1f7"
$total = 0;
$apps = $service.GetApplications("Name",$null,"Name","",20,0,$true,"PackageProgramName",$false,$null,[ref]$total)
$appid = $apps.ApplicationId;
When the user requests an application from the Application Catalog, the device information is used to validate and track the request. Here is how you can retrieve device information by using WMI on the client computer:
# Retrieve device id to identify the machine
$clientsdk = [wmiclass]'root/ccm/clientSDK:CCM_SoftwareCatalogUtilities';
$deviceidobj = $clientsdk.GetDeviceID();
$deviceid = $deviceidobj.ClientId+","+$deviceidobj.SignedClientId;
Next, device information with the request reason is sent to the Application Catalog:
# Submit application request to the server
$reason = "Test request reason";
$reqresult = $service.RequestApplicationForUser($reason, $appid, $deviceid, $null);
To perform an administrative action on the pending request, first connect to the SMS Provider. Note that you must have application approver privileges for the following operations:
# Retrieve provider info, assumes one provider
$siteserver = "MySiteServer"
$provider = gwmi -ComputerName $siteserver -namespace "root\sms" -query "SELECT * FROM SMS_ProviderLocation";
$prov_machine = $provider.Machine;
$sitecode = $provider.SiteCode;
$namespace = "root\sms\site_"+$sitecode;
Next, run a query to find the request object for the application. This example then approves all pending requests for this application. Note that approval cannot be reverted. Also, the delete operation is not supported on the SMS_UserApplicationRequest object. Although it’s not needed for this particular operation, I’ve included an example of querying for the specific SMS_Application object:
# get the list of pending requests for this application and approve for all users
$wmiquery = "SELECT * FROM SMS_Application WHERE ModelName = '"+$appid+"' AND IsLatest='TRUE'";
$adminapp = gwmi -ComputerName $prov_machine -namespace $namespace -query $wmiquery;
$wmiquery = "SELECT * FROM SMS_UserApplicationRequest WHERE ModelName = '"+$appid+"'";
$adminrequests = gwmi -ComputerName $prov_machine -namespace $namespace -query $wmiquery;
foreach ($request in $adminrequests)
$res = $request.Approve("Approved via Windows PowerShell");
If the user browses to the Application Catalog, the request for this application will be marked as Approved.
For security purposes, make sure that you revert any changes that you made to the web.config file when you no longer require WSDL publishing for the web service.
- The Application Catalog website role provides a service layer that helps extend the Application Catalog
- SMS Provider exposes APIs to approve or deny application requests
- The operations shown in this blog post can be written in the language of your choice, including Windows PowerShell
I hope that this information helps you to extend the Application Catalog functionality. For more information about the Application Catalog and System Center 2012 Configuration Manager extensibility, see Configuring the Application Catalog and Software Center in Configuration Manager in the System Center 2012 Configuration Manager Documentation Library on TechNet, and System Center 2012 Configuration Manager SDK in the MSDN Library.
This posting is provided "AS IS" with no warranties, and confers no rights.
Microsoft should look at how Boeing installs, detects and restores applications in a corporate environment. A fully automated application management system.
This is a great example. I tried, verbatim, to run this App Catalog request through powershell, but keep getting the following error:
Exception calling "RequestApplicationForUser" with "4" argument(s): "Server was unable to process request. ---> Invalid parameter"
At line:36 char:48
Are there any logs that might indicate which parameter is incorrect or where else the problem might lie?
The Application Catalog web service log should provide more information regarding this error. You can find the log file in the CMApplicationCatalogSvc\Logs folder.
I’d also suggest checking the following:
1) The application id should correspond to an application that is present in your environment.
2) The application should be marked to require administrator approval. Using the example in this blog post, make sure $apps[index you chose].AutoApproval is equal to False.
3) The request for the application has not been approved yet if present.
Is it possible to get an application to automatically install from the Application Catalog this way? Say I have it approved automatically, how can I then force the application to install via powershell?
Is there more documentation? I would also like to install a pre-approved app via PowerShell.
I am able to call the InstallApplication method via PowerShell, but I have determined that it only makes the application available after a User Policy Evaluation. How can I script the policy to refresh and then forcefully install the app?
After referencing the web service and using the provided code, I cannot call the "GetApplications" method - only the "GetApplicationsAsync" method. When I reference and browse the address I can see that the correct method is there though...
Does anyone know why this is acting this way?
Hi, also having trouble getting the catalog to work. Issue is user account in a different domain cannot install applications from the catalog. If I run same app, on the same machine, with a different user in a different domain then the application works.
After doing some debugging we have identified the error below. Has anyone come across this or have any suggestions why this is failing?
System.ArgumentException: Unable to subscribe user "domain\username" to application ScopeId_3449E81F-C7EA-4D57-BC71-BD82689E486D/Application_b2c905a6-a063-48b3-9af0-c02032b1d9d9 on device GUID:1E3C6056-52A2-4CAC-8B7C-2A51612F7644
at Microsoft.ConfigurationManager.SoftwareCatalog.Service.RequestHandler.CreateSoftwareRequestByUser(String clientId, UserContext user, String appId, Int32 sourceValue)
at Microsoft.ConfigurationManager.SoftwareCatalog.Service.RequestHandler.InstallApplication(UserContext user, DeviceIdentity identity, String applicationId)
at Microsoft.ConfigurationManager.SoftwareCatalog.Service.ApplicationOfferService.InstallApplication(UserContext userContext, DeviceIdentity identity, String applicationID, String reserved)
[44, PID:2044][07/24/2013 16:55:23] :An exception has been thrown from the service: System.ServiceModel.FaultException`1[[Microsoft.ConfigurationManager.SoftwareCatalog.Service.ServiceError, Microsoft.ConfigurationManager.SoftwareCatalog.Service.ApplicationOfferContract, Version=126.96.36.199, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Invalid parameter
at SyncInvokeInstallApplication(Object , Object , Object )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object inputs, Object& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Hi, I want to install the available applications in Application Catalog through powershell.
does anyone know how to do that. I tried created webserviceproxy as mentioned above, but i ma getting error - 'The HTML document does not contain web service discovery information'