Created
December 19, 2019 15:29
-
-
Save bmcguirk/8214196b66e49f4833413a2649c7cc54 to your computer and use it in GitHub Desktop.
Powershell script to get all the machines in a particular OU and then get all the programs installed on those machines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A Powershell Script to Get AD Machines from a certain OU and then query/export a CSV of their installed software inventory. | |
# 2019-10-17 - v1 - Author: Brian McGuirk - The Script works, but could maybe use a progress bar. Next up. | |
# 2019-11-14 - v2 - Author: Brian McGuirk - Added a progress bar. Limited properties to just useful ones. I think. | |
# Pre-requisites: | |
# - The Active Directory Powershell modules. In Windows 10, this should be an enable-able "Optional Feature." | |
# - The target machines must WMI enabled. | |
# Go here for more information: https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-start-page | |
Write-Host "Starting Inventory Script..." | |
# THE SCRIPT | |
# 1. Establish a path for the output file containing the machine names and store it in the $machine_path variable. | |
$machine_path="your_target_list_of_machines.txt" | |
# 2. Get machine names that match a particular pattern. | |
# Some notes: | |
# In this instance, we're getting all the computers that in the 'Accounting' OU. | |
# That's what `-Filter * -SearchBase "OU=Accounting,OU=Workstations,DC=enterprise,DC=contoso,DC=com"` is specifying. | |
# You should update this parameter for your desired naming convention or OU. | |
# Check this out for more information on filtering: | |
# https://docs.microsoft.com/en-us/powershell/module/addsadministration/get-adcomputer?view=win10-ps#examples | |
# Using the `.Name` accessor allows you to just export a flat, simple file with just the machine names. | |
# Pipe the output of this command to `Out-File` and provide it the `$machine_path` variable you established above. | |
Write-Host "Exporting machine names to: $machine_path ." | |
(Get-ADComputer -Filter * -SearchBase "OU=Accounting,OU=Workstations,DC=enterprise,DC=contoso,DC=com").Name | Out-File $machine_path | |
# 2. Invoke Get-WmiObject in the format below to gather everything in "Add/Remove Programs" in Control Panel. | |
# Some notes: | |
# - The `-ComputerName (Get-Content $machine_path)` parameter reads in the CSV you just created | |
# - The `ErrorAction SilentlyContinue` is designed to not raise and error and crash the script if the command can't run (because the PC is off, for example). | |
# - The `$installed_programs_export` variable is the path (relative or absolute) where you want to export this CSV. | |
# - This filename is now set up to auto-update the filename using datetime data so it never gets overwritten. | |
# - The `Get-WmiObject` command pipes its output to `Select-Object *` which takes every possible bit of data about these programs. | |
# - This data is then piped to `Export-Csv` which gets passed your `$installed_programs_export` path. | |
# - This path is generated dynamically everytime with the datetime, so you never overwrite files and you know when you ran it. | |
$installed_programs_export=".\$(get-date -f "yyyy-MM-dd_HH_mm_s")-all_installed_programs.csv" | |
# $installed_programs_export=".\$(get-date -f "yyyy-MM-dd_HH_mm_s")-my_ou_installed_programs.csv" | |
$machine_count = (Get-Content $machine_path | Measure-Object).Count | |
Write-Host "Gathering inventory for $machine_count machines and exporting to $installed_programs_export ." | |
Write-Host "Please note, this may take quite a few minutes, depending on how many machines you asked this script to analyze." | |
Write-Host "It generally doesn't crash, though, so don't freak out. Just let it run." | |
Write-Host "Update: Trying a progress bar..." | |
# The properties below are the most useful, I've found, but it's up to you. | |
$properties = @("PSComputerName", "Vendor", "Name", "Caption", "Version", "Description", "InstallDate", "InstallSource", "LocalPackage", "PackageCache", "PackageName", "IdentifyingNumber", "InstallLocation", "Language", "PackageCode", "ProductID", "RegCompany", "RegOwner", "HelpLink", "HelpTelephone", "URLInfoAbout", "URLUpdateInfo", "InstallState", "AssignmentType", "__SERVER", "Transforms") | |
$programs = @() | |
$i = 0 | |
foreach ($machine in (Get-Content $machine_path)){ | |
$completion = (($i/$machine_count)*100) | |
Write-Progress -Activity "Cataloguing $machine..." -Status "Overall Progress: $completion %" -PercentComplete $completion | |
$machine_programs = Get-WmiObject win32_product -computername $machine -ErrorAction SilentlyContinue | Select-Object $properties | |
$programs += $machine_programs | |
Write-Host "$machine complete." | |
$i+=1 | |
} | |
$programs | Export-Csv $installed_programs_export | |
Write-Host "Script complete. Please note: it is possible not all machines were inventoried. They may have been offline or misconfigured." | |
Write-Host "Check the machines in $machine_path against what showed up in $installed_programs_export to see which machines may be missing." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment