SCCM – Find all powershell detection scripts for applications in your environment


Updated the script to only accept 1 variable and thats DestinationPath, the rest its now automated in the script so no need to specify Siteserver or SiteCode any more but you need to run the script locally on your Siteserver, the script is also now available on Technet. 


So the other day at the office i needed to use and create a detection script for a new application and before i started to write it i had a pretty good understanding on how i wanted it to look like and in that moment i thought “wait a minute, i think i have written something like this before for another application. Lets just reuse that one!”

Perfect idea! Only one problem tho…. I couldn’t for the life of me remember which application it was (typical me) . So in the hope of that it would be my lucky day i took a few minutes to randomly trying to go through some of the applications and see if i could find it manually in SCCM. And no, lady luck wasn’t on my side that day.

So i turned to my old friend Powershell and made script that would help me out.


What do we want to achieve?


We want to be able to get the Application name and the Powershell detection script for every application that uses powershell as detection scripts. When we have that information we out put it to a file which is named after the application and output the detection script in to the file.


The Script


 Created on: 12/06/2016 
 Modified on: 3/31/2017 
 Created by: Timmy Andersson
 Contact: @Timmyitdotcom
 A description of the file.
[CmdletBinding(DefaultParameterSetName = 'DestinationPath')]
 [Parameter(Mandatory = $true,
 Position = 1)]

 [String]$Filepath = $DestinationPath
 $SiteCodeObjs = Get-WmiObject -Namespace "root\SMS" -Class SMS_ProviderLocation -ComputerName $env:COMPUTERNAME -ErrorAction Stop
 foreach ($SiteCodeObj in $SiteCodeObjs)
 if ($SiteCodeObj.ProviderForLocalSite -eq $true)
 $SiteCode = $SiteCodeObj.SiteCode
 $SitePath = $SiteCode + ":"
 Import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0, $Env:SMS_ADMIN_UI_PATH.Length - 5) + '\ConfigurationManager.psd1')
 if (-not (Test-Path $DestinationPath))
 new-item -Path $DestinationPath -ItemType Directory -Force
 Set-location $SitePath
 $Apps = (Get-CMApplication)
 foreach ($App in $Apps)
 $Script = ([Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::DeserializeFromString($App.SDMPackageXML)).DeploymentTypes[0].Installer
 if ($Script.DetectionScript -ne $Null)
 $PSscript = ([Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::DeserializeFromString($App.SDMPackageXML)).DeploymentTypes[0].Installer.DetectionScript
 if ($PSscript.Language -like "PowerShell")
 Out-File -FilePath "$Filepath$($App.LocalizedDisplayName).ps1" -InputObject $PSscript.Text





Made this youtube video showing of how the script works



Until next time, cheers Timmy !

You can find me over at

[twitter-follow screen_name=’Timmyitdotcom’]



  1. Old post, but just found this today.
    Thanks, this is great.
    One thing I changed was to pipe get-cmapplication directly into a foreach-object, instead of using a variable and foreach(), only because in my environment it takes a very, *very* long time to get all those applications, and by piping I start seeing results almost immediately.
    Another change was to handle LocalizedDisplayName with characters not allowed in filenames. Too many app names like “blah w/ plugins”
    A final change was to use Set-Content rather than Out-File. I was worried that Out-File’s default 80-column line-truncation feature could give unexpected, undesired results, say for very long registry hives, and it seemed wrong to kludge it by using a very long line length.
    Thanks again for this great script!

Leave a Reply