Application Detection Using Powershell

Chris NienaberNetwork Analyst
CERTIFIED EXPERT
IT is my life...SCCM my passion! I work full time with SCCM, Exchange, and Windows Server. I have a beautiful family and love Star Trek!
Published:
Updated:
The following article is intended as a guide to using PowerShell as a more versatile and reliable form of application detection in SCCM.
When I first started using PowerShell I found it extremely intimidating. I had taken basic programming in High School and while a lot of the syntax and concepts were similar, PowerShell still had its own unique differences. While I would not pretend to be an expert in programming by any stretch I had the opportunity to take a PowerShell course through work which helped to ease my apprehension. Additionally, one of my coworkers is able to dissect code at an instinctive level after only a few moments of looking it. I owe a lot of what I have learned to him in the way of PowerShell, and I wish I had such instinctive ability myself.
 
While I have found a lot of uses for PowerShell in the Exchange world I have not up until now used it all that extensively in SCCM. That changed a couple of months back at our Monthly SITPRO user group meeting when I was introduced to the PowerShell App Deployment Toolkit by a fellow SITPRO Colleague, Kyle Erickson. Kyle had an extremely engaging presentation on the toolkit and I was hooked out of the gate. Any of you who deal in application deployments with SCCM owe it to yourselves to check out this toolkit. It is essentially a deployment wrapper with a huge amount of options, my favorite is the built in logging.
 
Through using the tool and converting our legacy batch file deployments I began thinking of additional ways of leveraging PowerShell in our deployments. My immediate thought was for detection rules. This has long been a sore spot for me. In our environment we heavily leverage the SCCM Software Center & User Driven Installations as opposed to Zero Touch Installations. We used to run detections based on the file version of application .exe’s however this in itself can be cumbersome. Case in point is Java, each update tends to install to a named folder of its current version. Due to the nature of our deployment model we wanted a way of using a detection method that would find all old versions of the software if present so that if any exist then the user can trigger the uninstall from SCCM and reinstall the newer version.

I got off to a great start with a post by David O’Brien. In it he provided the key piece of information to construct the detection method I was looking for:
 
if (Test-Path C:\Apps\Test.html)
                      { 
                      	Write-Host "Installed" 
                      } 
                      else
                      {
                      }

Open in new window

The above code snippet illustrates that the SCCM Client is looking for a state of “Installed” , the if statement contains the logic to indicate what is tested before this state is set. I expanded upon this code with the following:
 
 Set-ExecutionPolicy -ExecutionPolicy Bypass
                      
                      ##Global Variable Declaration
                      
                      [version]$InstallerVersion = '8.0.1210.13'
                      #Application Name as it appears in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{appGUID}\DisplayName
                      #Append a * as a wildcard ex. '7-Zip*'
                      $AppName = 'Java*'
                      
                      ##32-Bit Detection
                      
                      $32BitApp = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | where {$_.displayname -like $AppName}
                          Foreach ($item in $32BitApp)
                          {
                              [version]$InstalledVersion = $item.DisplayVersion
                              if ($InstalledVersion -ge $InstallerVersion)
                              {
                                  Write-Host "Installed"
                              }
                              else
                              {
                              }
                          }
                              
                      ##64-Bit Detection
                      
                      $64BitApp = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | where {$_.displayname -like $AppName}
                          Foreach ($item in $64BitApp)
                          {
                              [version]$InstalledVersion = $item.DisplayVersion
                              if ($InstalledVersion -ge $InstallerVersion)
                              {
                                  Write-Host "Installed"
                              }
                              else
                              {
                              }
                          } 

Open in new window


The script above checks HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\ for any registered applications where the DisplayName of the application is like Java*. If their is a registered application matching these settings then a check is made to determine whether the version is greater than or equal to the version specified in the $CurrentVersion variable. If the conditions hold true then “Installed” is written to the host and the Configuration Manager believes the application is installed. The advantage of the above detection method is that it uses the “Uninstall” key where 99% of applications are registered, which makes the detection method highly reliable. It also supports the use of wildcards.
 

Once the script is ready you can add it as a PowerShell Script type on the properties of the package as shown below:

Power_Shell_Detection_Method.PNGWe have been using the above method in our environment with a lot of success so far. There are many ways to expand upon the above, with PowerShell scripts the options are endless!
1
6,133 Views
Chris NienaberNetwork Analyst
CERTIFIED EXPERT
IT is my life...SCCM my passion! I work full time with SCCM, Exchange, and Windows Server. I have a beautiful family and love Star Trek!

Comments (2)

Albert WidjajaIT Professional
CERTIFIED EXPERT

Commented:
Hi SCCMCanuck,

Which of the Powershell line that I can edit safely to suit my environment ?
Chris NienaberNetwork Analyst
CERTIFIED EXPERT

Author

Commented:
Thanks for your interest. At the moment the following lines are safe to change

[version]$InstallerVersion = '8.0.1210.13'
$AppName = 'Java*'

The value of $AppName variable is a wildcard string that corresponds with the DisplayName registry value, where as $InstalledVersion corresponds to DisplayVersion.

You can modify any part of the script to accommodate any type of detection method and use and/or statements to create a more restrictive set of criteria. The goal of my example is to make the SCCM client agent believe that Java is installed if its version is greater than or equal to the value of $InstallerVersion in the Variable Declaration section

Registry.PNG

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.