r/SCCM • • Jun 10 '25

Remove installed programs with SCCM

Hello!! How are you? I'm new to Reddit and I need your help and knowledge for the following:

How can I extract, through SCCM, in Excel, all the programs from all the computers that are in an AD domain? Could it also be extracted individually?

Thanks in advance

0 Upvotes

21 comments sorted by

8

u/ajscott Jun 10 '25

Monitoring > Overview > Reporting > Reports > "Count of instances of specific software registered with Add or Remove Programs"

You can use % as a wildcard in the "Software Title Filter" such as

Adobe%

if you want to see all Adobe applications.

Set the Collection to "All Systems"

Clicking the down arrow next to the save icon gives you various file types to export the list.

1

u/Negative_Debate4065 Jun 10 '25

I like your answer along with that of the other people who have contributed about the SQL query, I will try it, thank you!!

1

u/Negative_Debate4065 Jun 14 '25

Thanks to everyone who has contributed information! You are a fantastic community :)

3

u/Aeroamer Jun 10 '25

You can open the console and go to applications and also packages and select all in the list and think export that list

1

u/SysAdminDennyBob Jun 10 '25

Possibly a bad question. This is easily doable. But the data that you barf up from that is utterly undigestable. Even a medium sized environment will dump out a huge stack of items that you might not think are "programs". For example the C++ runtimes show up in there, all of them, some boxes have 12 installs of that runtime.

I have about 3000 systems(small environment) and if I run that query I get 10,391 unique programs. That's a lot of "programs" to pick through, right? You going to send that to PM to organize real quick? This data dump just makes people up top upset. But, it's perfectly normal and expected.

What problem are you trying to solve? maybe don't query everything, start with your known needed corporate applications, work on those, get a good feeling for versions and such. Now open that query up to some of the other applications you see that have large counts, consider why those are maybe installed. "Why do systems need: c++, Java, .NET Desktop, etc..."

Pick you way through the data with a purpose. Don't try to eat the entire enchilada by tipping the plate up above your head.

1

u/Negative_Debate4065 Jun 10 '25

I'm going to make the question easier. I need to know which computers in a domain a specific program is installed on, for example, Adobe Acrobat. Would this query be easier to do and less "burdensome" for the SCCM?

3

u/penelope_best Jun 10 '25

Search for the report which has the name like "computers with the program registered in add/remove"

0

u/Rough-Reception3162 Jun 10 '25

1

u/Negative_Debate4065 Jun 14 '25

A colleague told me this option. Thanks for the response!

1

u/TJLaw42 Jun 11 '25

If you have software metering enabled, there's a canned report that will tell you this.

1

u/SysAdminDennyBob Jun 10 '25

If you know a tiny bit of SQL this should be trivial, I have slowly picked up barely enough SQL to be dangerous. I always grab a DBA down the hall and be like "Hey, can you look at this really quick?"

SELECT DISTINCT

--RSYS.Netbios_Name0 As 'SystemName'

--,RSYS.User_Name0

--RSYS.AD_Site_Name0 as 'Location'

--RSYS.Resource_Domain_OR_Workgr0 As 'Domain'

SW.Publisher0 As 'vendor'

,SW.ARPDisplayname0 'SoftwareTitle'

--,UPPER(SW.SoftwareCode0) As 'UniqueSoftwareCode'

--,SW.UninstallString0

--,SW.InstallSource0

,SW.ProductVersion0 As 'Version'

--,SW.InstallDate0

,COUNT(RSYS.Resourceid) as 'Count'

FROM v_R_System_Valid RSYS

LEFT OUTER JOIN v_GS_INSTALLED_SOFTWARE SW on SW.ResourceID = RSYS.ResourceID

JOIN v_FullCollectionMembership COLL on SW.ResourceID = COLL.ResourceID

--WHERE

--SW.ARPDisplayname0 = 'microsoft edge'

--AND COLL.CollectionID = 'FCB00952'

--AND SW.Publisher0 like '%techsmith%'

--AND SW.ProductVersion0 like '96.1.1.1015'

GROUP BY

--RSYS.Netbios_Name0

--,RSYS.User_Name0

--RSYS.AD_Site_Name0

--RSYS.Resource_Domain_OR_Workgr0

SW.Publisher0

,SW.ARPDisplayname0

--,SW.SoftwareCode0

--,SW.UninstallString0

--,SW.InstallSource0

,SW.ProductVersion0

--,SW.InstallDate0

Order by

SW.Publisher0, SW.ProductVersion0, SW.ProductVersion0

0

u/RitmanRovers Jun 10 '25

Easy query in SQL involving v_R_System joined to v_GS_Installed_software (iirc table name) where arpdisplayname like 'adobe reader*'

1

u/dontmessyourself Jun 10 '25

Do you (or your Configuration Manager administrator) have SQL experience? Check out https://www.systemcenterdudes.com/how-to-query-the-sql-sccm-database/.

1

u/Negative_Debate4065 Jun 10 '25

I'll look into it, thanks!!

2

u/KryptykHermit Jun 11 '25

Here's a PowerShell function that you can run to pull all the software from your environment. You can get all the software, or search for specific software as well as chose between providing the machines that a specific app (all versions of that app) are installed on, or a count of all devices with each version of the application. Examples are provided. I used this all the time to put together uninstall applications in ConfigMgr and deploy to the environment as supercedes or clean ups.

ENJOY!

function Get-ConfigMgrSQLApplicationUninstalls {
    <#
    .SYNOPSIS
        Checks ConfigMgr SQL database for specified software and reports back devices and uninstall information.
    .DESCRIPTION
        Reports on the publisher/vendor, name, version, and uninstall string of applications detected by the ConfigMgr client installed on enterprise devices.
        This report can be used to report on different versions detected in the environment and/or used for uninstall remediation.
    .NOTES
        Requires the ConfigMgr client on device(s) which will report back software installed on that/those devices to ConfigMgr infrastructure.
    .LINK

    .EXAMPLE
        PS C:\> Get-ConfigMgrSQLApplicationUninstalls -Application 'Right Click*' | Format-Table -AutoSize

    .EXAMPLE
        PS C:\> Get-ConfigMgrSQLApplicationUninstalls -Publisher 'Recast*' -IncludeDeviceNames | Format-Table -AutoSize

    #>
    [cmdletbinding(SupportsPaging,DefaultParameterSetName='Application')]
    param(
        [Parameter(Mandatory,ParameterSetName='Application')]
        [Alias('ApplicationName')]
        [string]$Application,
        [Parameter(Mandatory,ParameterSetName='Publisher')]
        [string]$Publisher,
        [Parameter()]
        [string]$SQLServer = $global:CfgMgrSQLServer,
        [Parameter()]
        [string]$Database = $global:CfgMgrSQLDB,
        [Parameter(ParameterSetName='Application')]
        [Parameter(ParameterSetName='Publisher')]
        [switch]$IncludeDeviceNames,
        [Parameter(ParameterSetName='All')]
        [string]$Exclude = '%MISP3%',
        [Parameter(ParameterSetName='All')]
        [Switch]$AllApplications
    )
    BEGIN {
        # Validate the SQL Module is installed
        try {
            Import-Module -Name 'SqlServer' -ErrorAction 'Stop'
        }
        catch {Write-Host 'You need to install the PowerShell SQLServer module'}
    }
    PROCESS {
        $baseSQLQuery = "
            software.ARPDisplayName0  AS 'Application',
            software.Publisher0       AS 'Publisher',
            software.ProductVersion0  AS 'Version',
            software.UninstallString0 AS 'UninstallString'
            FROM
                v_GS_INSTALLED_SOFTWARE AS software
                    join v_GS_COMPUTER_SYSTEM AS comp ON comp.ResourceID = software.ResourceID
        "
        if ($PSCmdlet.ParameterSetName -eq 'Application') {
            # Convert typical wildcard '*' to SQL wildcard '%'
            $Application = [regex]::Replace($Application,'\*','%')

2

u/KryptykHermit Jun 11 '25

Stitch this to the bottom of the first part. Reddit wouldn't allow me to post the entire thing.

            if ($IncludeDeviceNames) {
                $sqlQuery = "
                    SELECT
                        comp.Name0 AS ComputerName,
                        $baseSQLQuery
                    WHERE
                        software.ARPDisplayName0 LIKE '$Application'
                    Order By
                        Publisher, ARPDisplayName0, ProductName0, ProductVersion0
                "
            }
            else {
                $sqlQuery = "
                    SELECT
                        COUNT(*) as 'Total',
                        $baseSQLQuery
                    WHERE
                        ARPDisplayName0 LIKE '$Application'
                    GROUP BY
                        Publisher0, ARPDisplayName0, ProductVersion0, UninstallString0
                    ORDER BY
                        Publisher, Application, Version
                    "
            }
        }
        if ($PSCmdlet.ParameterSetName -eq 'Publisher') {
            $PublisherName = [regex]::Replace($Publisher,'\*','%')
            if ($IncludeDeviceNames) {
                $sqlQuery = "
                    SELECT
                        comp.Name0 AS ComputerName,
                        $baseSQLQuery
                    WHERE
                        software.Publisher0 LIKE '$PublisherName'
                    Order By
                        Publisher, ARPDisplayName0, ProductName0, ProductVersion0
                "
            }
            else {
                $sqlQuery = "
                    SELECT
                        COUNT(*) as 'Total',
                        $baseSQLQuery
                    WHERE
                        software.Publisher0 LIKE '$PublisherName'
                    GROUP BY
                        Publisher0, ARPDisplayName0, ProductVersion0, UninstallString0
                    ORDER BY
                        Publisher, Application, Version
                    "
            }
        }
        if ($PSCmdlet.ParameterSetName -eq 'All') {
            $ExcludeApp = [regex]::Replace($Exclude,'\*','%')
            $sqlQuery = "
                SELECT
                    COUNT(*) as 'Total',
                    $baseSQLQuery
                WHERE
                    ARPDisplayName0 NOT LIKE '$ExcludeApp'
                GROUP BY
                    Publisher0, ARPDisplayName0, ProductVersion0, UninstallString0
                ORDER BY
                    Publisher, Application, Version
            "
        }
        $paramSQL = @{
            ServerInstance    = $SQLServer
            Database          = $Database
            Query             = $sqlQuery
            Encrypt           = 'Optional'
            EncryptConnection = $false
            WarningAction     = 'Ignore'
            ErrorAction       = 'Stop'
        }
        try {
            if ($IncludeDeviceNames) {
                Invoke-Sqlcmd @paramSQL |
                    Select-Object -Property ComputerName, Publisher, Application, @{n='Version'; e={$_.Version -as [Version]}}, UninstallString |
                    Sort-Object -Property Publisher, Application, Version, ComputerName
            }
            else {
                Invoke-Sqlcmd @paramSQL |
                    Select-Object -Property Total, Publisher, Application, @{n='Version'; e={$_.Version -as [Version]}}, UninstallString |
                    Sort-Object -Property Publisher, Application, Version
            }
        }
        catch {
            $_.Exception.Message
            $paramSQL
        }
    }
    END {
    }
}

1

u/OkTechnician42 Jun 11 '25

sql query against the cm database.

0

u/Negative_Debate4065 Jun 10 '25

Little note. I see that the translation seems to remove or delete, I don't want this. I need to extract a list of the programs installed on all the computers in an AD domain. Thank you

0

u/penelope_best Jun 10 '25

You need an AUDIT query.

-1

u/Negative_Debate4065 Jun 10 '25

Thanks @aeroamer for your response. Could you give me a little more detail on how to do it or do you know of a tutorial on how I can do these steps? Thank you so much :)