~/2013/09/03/powershell-find-installed-netapp-products.md
PowerShell: Find Installed NetApp Products
--- author: Tom Lasswell 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.csvfile in the same folder as the script, with acomputernamecolumn (for example an Active Directory export).
Parameters
The script takes no parameters. Edit these values before running it.
| Name | Type | Required | Description |
|---|---|---|---|
$LikePublisher | String | Yes | Publisher name to search for. Matched with -like "*value*"; defaults to NetApp. |
computerlist.csv | File | Yes | Input file in the script folder. Needs a computername column with one computer per row. |
Usage
Create computerlist.csv next to the script.
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).
.\Find-InstalledNetAppProducts.ps1
To search for another vendor, change $LikePublisher at the top of the script.
Script
<#
.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.