~/2013/09/03/powershell-find-installed-netapp-products.md

PowerShell: Find Installed NetApp Products

---
author: 
date: 
updated: 
read: 1 min
in:   [ps, scripts]
tags: [netapp, powershell]
---

$ grep -n '^#' post.md

A slightly modified version of a scriptingGuy post to find NetApp software installed from a csv file (export from active directory)

Requirements

  • Windows PowerShell 2.0 or later.
  • The Remote Registry service running on every computer in the list.
  • An account with administrative rights on those computers, and network access to them.
  • A computerlist.csv file in the same folder as the script, with a computername column (for example an Active Directory export).

Parameters

The script takes no parameters. Edit these values before running it.

NameTypeRequiredDescription
$LikePublisherStringYesPublisher name to search for. Matched with -like "*value*"; defaults to NetApp.
computerlist.csvFileYesInput file in the script folder. Needs a computername column with one computer per row.

Usage

Create computerlist.csv next to the script.

text
computername
SERVER01
SERVER02

Then run the script. Matches are shown as a table and also written to searchpublisher-NetApp_<ddMMyyyy>.csv in the script folder (an existing file with the same name is deleted first).

powershell
.\Find-InstalledNetAppProducts.ps1

To search for another vendor, change $LikePublisher at the top of the script.

Script

powershell
<#
.SYNOPSIS
    Finds software from a given publisher (NetApp by default) installed on the computers in a CSV file.
.DESCRIPTION
    Reads computerlist.csv from the script folder (it needs a computername column), opens the
    remote registry on each computer and walks HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall,
    skipping KB entries. Entries whose publisher matches $LikePublisher are displayed as a table and
    exported to searchpublisher-<publisher>_<ddMMyyyy>.csv in the script folder.
.EXAMPLE
    .\Find-InstalledNetAppProducts.ps1
.NOTES
    Author  : Thomas Lasswell (https://www.techcolumnist.com)
    Version : 1.1 (2026-09-20)
    History : 1.0 2013-09-03 Initial version.
              1.1 2026-09-20 The CSV no longer starts with a #TYPE line.
    Requires: Windows PowerShell 2.0+, Remote Registry service on the target computers
    Based on a Scripting Guy post.
#>
$ErrorActionPreference = 'silentlycontinue'
$exedir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent

# Variables
$LikePublisher = "NetApp"

$infile = ($exedir + "\computerlist.csv")
Write-Host "$infile"
$computers = Import-Csv $infile
$totalComputers = $computers.Count
$currentDate = (Get-Date -UFormat "%d%m%Y")
$outfile = ($exedir + "\" + "searchpublisher-" + $LikePublisher + "_" + $currentDate + ".csv")
Write-Host "$outfile"
$checkforoutfile = Test-Path $outfile
if ($checkforoutfile) {
    Remove-Item $outfile
}

$counter1 = 0
$array = @()
foreach ($pc in $computers) {
    $subkeys = $null
    $computername = $pc.computername
    $counter1++
    Write-Progress -Activity "Processing" -Status "Processing computer $counter1 of $totalComputers" -PercentComplete (100 * ($counter1 / $computers.Count)) -Id 1
    Write-Progress "Initializing" "Connecting to the Windows System: $computername" -ParentId 1

    # Define the variable to hold the location of currently installed programs.
    $UninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

    # Create an instance of the registry object and open the HKLM base key.
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computername)

    # Drill down into the Uninstall key using the OpenSubKey method.
    $regkey = $reg.OpenSubKey($UninstallKey)

    # Retrieve an array of strings that contain all the subkey names.
    $subkeys = $regkey.GetSubKeyNames()

    # Open each subkey and use the GetValue method to return the required values for each.
    $counter2 = 0
    foreach ($key in $subkeys) {
        $counter2++
        if ($subkeys.Count -eq $null) {
            Write-Host "Could not connect to $computername continuing ..."
        }
        if (($subkeys.Count -ne $null) -and ($key -notlike "*KB*")) {
            Write-Progress -Activity "Gathering Key information on $computername" -Status "Processing Key $key" -PercentComplete (100 * ($counter2 / $subkeys.Count)) -ParentId 1
            $thisKey = $UninstallKey + "\\" + $key
            $thisSubKey = $reg.OpenSubKey($thisKey)
            $obj = New-Object PSObject
            $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $computername
            $obj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $($thisSubKey.GetValue("DisplayName"))
            $obj | Add-Member -MemberType NoteProperty -Name "DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion"))
            $obj | Add-Member -MemberType NoteProperty -Name "InstallLocation" -Value $($thisSubKey.GetValue("InstallLocation"))
            $obj | Add-Member -MemberType NoteProperty -Name "Publisher" -Value $($thisSubKey.GetValue("Publisher"))
            $array += $obj
        }
    }
}

# Show and export the matches.
$array | Where-Object { $_.DisplayName -and $_.Publisher -like "*$LikePublisher*" } | Select-Object ComputerName, DisplayName, DisplayVersion, Publisher | Format-Table -AutoSize
$array | Where-Object { $_.DisplayName -and $_.Publisher -like "*$LikePublisher*" } | Select-Object ComputerName, DisplayName, DisplayVersion, Publisher | Export-Csv $outfile -NoTypeInformation

Notes

  • Update 2026-09-20 (v1.1): the export now uses -NoTypeInformation. Without it, Windows PowerShell 5.1 and earlier write a #TYPE ... line at the top of the CSV that breaks most importers.