Function Get-Apps($ComputerName, $TableView) { $SCCMServer = "shscm01.int.samhealth.net" $SCCMNameSpace = "root\sms\site_100" $SCCMX64Query = "select SMS_G_System_ADD_REMOVE_PROGRAMS_64.DisplayName, SMS_G_System_ADD_REMOVE_PROGRAMS_64.Version, SMS_G_System_ADD_REMOVE_PROGRAMS_64.Publisher, SMS_G_System_ADD_REMOVE_PROGRAMS_64.InstallDate from SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS_64 on SMS_G_System_ADD_REMOVE_PROGRAMS_64.ResourceId = SMS_R_System.ResourceId inner join SMS_G_System_SYSTEM on SMS_G_System_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_G_System_SYSTEM.Name = '$ComputerName'" $SCCMX86Query = "select SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName, SMS_G_System_ADD_REMOVE_PROGRAMS.Version, SMS_G_System_ADD_REMOVE_PROGRAMS.Publisher, SMS_G_System_ADD_REMOVE_PROGRAMS.InstallDate from SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId inner join SMS_G_System_SYSTEM on SMS_G_System_SYSTEM.ResourceID = SMS_R_System.ResourceId where SMS_G_System_SYSTEM.Name = '$ComputerName'" $64apps = Get-WmiObject -namespace $SCCMNameSpace -DirectRead -computer $SCCMServer -query $SCCMX64Query | Select-Object -Property DisplayName | Add-Member -NotePropertyName x86/x64 -NotePropertyValue 64 -PassThru | Sort-Object -Property DisplayName $86apps = Get-WmiObject -namespace $SCCMNameSpace -DirectRead -computer $SCCMServer -query $SCCMX86Query | Select-Object -Property DisplayName | Add-Member -NotePropertyName x86/x64 -NotePropertyValue 32 -PassThru | Sort-Object -Property DisplayName #Checks if local computer if ($comp -eq $env:COMPUTERNAME) { $localapps = Get-Package -ProviderName Programs -IncludeWindowsInstaller | Select-Object @{N='DisplayName';E={$_.Name}} | Sort-Object -Property DisplayName } else { #Checks if pc is online so Invoke doesn't hang on offline pc if (Test-Connection -ComputerName $comp -Count 1) { $localapps = Invoke-Command -ComputerName $ComputerName -SessionOption $(New-PSSessionOption -MaxConnectionRetryCount 1 -NoMachineProfile) -ScriptBlock { Get-Package -ProviderName Programs -IncludeWindowsInstaller | Select-Object @{N='DisplayName';E={$_.Name}} | Sort-Object -Property DisplayName } } } $out = $86apps + $64apps $apps = @() foreach ($item in $out) { $a = New-Object -TypeName PSCustomObject $a.PSObject.TypeNames.Insert(0, 'GetPC.App') Copy-Property -From $item -To $a $apps += $a } # Blank entry for visual break $a = [PSCustomObject]@{ DisplayName = "" } $a.PSObject.TypeNames.Insert(0, 'GetPC.App') $apps += $a # Grab apps that are only returned by local query $localOnly = Compare-Object $localapps $out -Property DisplayName -PassThru | Where-Object {$_.SideIndicator -eq '<='} foreach ($item in $localOnly) { $a = New-Object -TypeName PSCustomObject $a.PSObject.TypeNames.Insert(0, 'GetPC.App') Copy-Property -From $item -To $a $apps += $a } if ($TableView) { $apps | Out-GridView -Title "Get-PC Apps - $ComputerName" } else { Write-Output $apps } } function Copy-Property ($From, $To) { $properties = Get-Member -InputObject $From -MemberType NoteProperty foreach ($p in $properties) { $To | Add-Member -MemberType NoteProperty -Name $p.Name -Value $From.$($p.Name) -Force } }