none
Excluding a list of program on remote computers running a 32-bit OS

    General discussion

  • Hi,

    I'm using the following powershell function to list the software installed on remote computers and export the data into various formats such as CSV, GridView or console :

    Function Get-InstalledApplication
    {
    Param(
    [Parameter(Mandatory=$true)]
    [string[]]$Computername,
    [String[]]$OutputType,
    [string[]]$outpath
    )
    
    #Registry Hives
    
    $Object =@()
    
    $excludeArray = ("Security Update for Windows",
    "Update for Windows",
    "Update for Microsoft .NET",
    "Security Update for Microsoft",
    "Hotfix for Windows",
    "Hotfix for Microsoft .NET Framework",
    "Hotfix for Microsoft Visual Studio 2007 Tools",
    "Microsoft Visual C++ 2010",
    "cwbin64a",
    "Hotfix")
    
    [long]$HIVE_HKROOT = 2147483648
    [long]$HIVE_HKCU = 2147483649
    [long]$HIVE_HKLM = 2147483650
    [long]$HIVE_HKU = 2147483651
    [long]$HIVE_HKCC = 2147483653
    [long]$HIVE_HKDD = 2147483654
    
    Foreach($EachServer in $Computername){
    $Query = Get-WmiObject -ComputerName $Computername -query "Select AddressWidth, DataWidth,Architecture from Win32_Processor" 
    foreach ($i in $Query)
    {
     If($i.AddressWidth -eq 64){            
     $OSArch='64-bit'
     }            
    Else{            
    $OSArch='32-bit'            
    }
    }
    
    Switch ($OSArch)
    {
    
     "64-bit"{
    $RegProv = GWMI -Namespace "root\Default" -list -computername $EachServer| where{$_.Name -eq "StdRegProv"}
    $Hive = $HIVE_HKLM
    $RegKey_64BitApps_64BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
    $RegKey_32BitApps_64BitOS = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    $RegKey_32BitApps_32BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
    
    #############################################################################
    
    # Get SubKey names
    
    $SubKeys = $RegProv.EnumKey($HIVE, $RegKey_64BitApps_64BitOS)
    
    # Make Sure No Error when Reading Registry
    
    if ($SubKeys.ReturnValue -eq 0)
    {  # Loop through all returned subkeys
    ForEach ($Name in $SubKeys.sNames)
     {
    $SubKey = "$RegKey_64BitApps_64BitOS\$Name"
    $ValueName = "DisplayName"
    $ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
    $AppName = $ValuesReturned.sValue
    $Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue 
    $Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue 
    $donotwrite = $false
    
    if($AppName.length -gt "0"){
    
     Foreach($exclude in $excludeArray) 
                            {
                            if($AppName.StartsWith($exclude) -eq $TRUE)
                                {
                                $donotwrite = $true
                                break
                                }
                            }
                if ($donotwrite -eq $false) 
                            {                        
                $Object += New-Object PSObject -Property @{
                Application = $AppName;
                Architecture  = "64-BIT";
                ServerName = $EachServer;
                Version = $Version;
                Publisher= $Publisher;
               }
                            }
    
    }
    
      }}
    
    #############################################################################
    
    $SubKeys = $RegProv.EnumKey($HIVE, $RegKey_32BitApps_64BitOS)
    
    # Make Sure No Error when Reading Registry
    
    if ($SubKeys.ReturnValue -eq 0)
    
    {
    
      # Loop Through All Returned SubKEys
    
      ForEach ($Name in $SubKeys.sNames)
    
      {
    
        $SubKey = "$RegKey_32BitApps_64BitOS\$Name"
    
    $ValueName = "DisplayName"
    $ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
    $AppName = $ValuesReturned.sValue
    $Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue 
    $Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue 
     $donotwrite = $false
    
    if($AppName.length -gt "0"){
     Foreach($exclude in $excludeArray) 
                            {
                            if($AppName.StartsWith($exclude) -eq $TRUE)
                                {
                                $donotwrite = $true
                                break
                                }
                            }
                if ($donotwrite -eq $false) 
                            {                        
                $Object += New-Object PSObject -Property @{
                Application = $AppName;
                Architecture  = "32-BIT";
                ServerName = $EachServer;
                Version = $Version;
                Publisher= $Publisher;
               }
                            }
               }
    
        }
    
    }
    
    } #End of 64 Bit
    
    ######################################################################################
    
    ###########################################################################################
    
    "32-bit"{
    
    $RegProv = GWMI -Namespace "root\Default" -list -computername $EachServer| where{$_.Name -eq "StdRegProv"}
    
    $Hive = $HIVE_HKLM
    
    $RegKey_32BitApps_32BitOS = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
    
    #############################################################################
    
    # Get SubKey names
    
    $SubKeys = $RegProv.EnumKey($HIVE, $RegKey_32BitApps_32BitOS)
    
    # Make Sure No Error when Reading Registry
    
    if ($SubKeys.ReturnValue -eq 0)
    
    {  # Loop Through All Returned SubKEys
    
      ForEach ($Name in $SubKeys.sNames)
    
      {
    $SubKey = "$RegKey_32BitApps_32BitOS\$Name"
    $ValueName = "DisplayName"
    $ValuesReturned = $RegProv.GetStringValue($Hive, $SubKey, $ValueName)
    $AppName = $ValuesReturned.sValue
    $Version = ($RegProv.GetStringValue($Hive, $SubKey, "DisplayVersion")).sValue 
    $Publisher = ($RegProv.GetStringValue($Hive, $SubKey, "Publisher")).sValue 
    
    if($AppName.length -gt "0"){
    
    $Object += New-Object PSObject -Property @{
                Application = $AppName;
                Architecture  = "32-BIT";
                ServerName = $EachServer;
                Version = $Version;
                Publisher= $Publisher;
               }
               }
    
      }}
    
    }#End of 32 bit
    
    } # End of Switch
    
    }
    
    #$AppsReport
    
    $column1 = @{expression="ServerName"; width=15; label="Name"; alignment="left"}
    $column2 = @{expression="Architecture"; width=10; label="32/64 Bit"; alignment="left"}
    $column3 = @{expression="Application"; width=80; label="Application"; alignment="left"}
    $column4 = @{expression="Version"; width=15; label="Version"; alignment="left"}
    $column5 = @{expression="Publisher"; width=30; label="Publisher"; alignment="left"}
    
    if ($outputType -eq "Console")
    {
    "#"*80
    "Installed Software Application Report"
    "Number of Installed Application count : $($object.count)"
    "Generated $(get-date)"
    "Generated from $(gc env:computername)"
    "#"*80
    $object |Format-Table $column1, $column2, $column3 ,$column4, $column5
    }
    
    elseif ($OutputType -eq "GridView")
    {
    $object|Out-GridView 
    }
    elseif ($OutputType -eq "CSV")
    {
    [string]$FileDS = Get-Date -Format "yyyyMMdd"
    [string]$outFile = $outpath+'\'+$computername+'_'+$FileDS+'.csv'
    New-Item -ItemType file $outfile -Force
    $object | export-csv -path $outfile
    }
    else
    {
    write-host " Invalid Output Type $OutputType"
    }
    
    
    }

    I'm also using the code to exclude some application from a list. I have a problem on PCs running a 32-bit version of Windows (tested on a 32-bit Windows 7) : applications excluded from this list still appear in the output. No problem on 64-bit systems however.

    The appnames are mostly the same on both 32 and 64-bit pc's. For example, the "Security Update for Microsoft ..." are well excluded on the 64-bit but not on the 32.
    Ideas of what's wrong ?

    Also, there are applications that are duplicated in the output. How can I delete them ?

    Thanks

    Friday, December 7, 2018 5:54 PM

All replies

  • Look in the Gallery for CmdLets that do this correctly.  WMI is the old and very hard way to read the registry.  Net and PowerShell use the remote registry Net class to do this.


    \_(ツ)_/

    Friday, December 7, 2018 6:14 PM