Reputation: 57
I'm still pretty new to PowerShell, and am still learning how to use it. I saw I could use a cmdlet named Get-WmiObject, but I'm not sure that's the right one to use. I've seen people saying when using it that it might throw up errors on the user-end, which would confuse users.
So digging around, people are saying I can query the registry of all the computers in an OU, which would search here "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" and possibly here "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall". The problem I'm running into is I'm not sure which cmdlet to start out using (if a cmdlet at all), how to tell it to search in that specific registry, while also telling it to go through each computer in an OU checking.
I need to search for all computers that have "Microsoft Office" installed. Can anyone point me in the right direction? How do I go about doing this?
Upvotes: 0
Views: 969
Reputation: 61068
First of all, you need to get a list of computer names in the OU and for that you need to get the DistinghuishedName
property of that OU. (look in ADUC -> OU Properties -> Attributes -> DistinghuishedName)
Using that, you can use the function below to test for installed software:
function Get-InstalledSoftware {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
[string[]]$ComputerName = $env:COMPUTERNAME,
[string]$NamePattern = '*',
[switch]$ExcludeUpdates
)
begin {
$UninstallPaths = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\',
'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'
}
process {
foreach ($computer in $ComputerName) {
if ([string]::IsNullOrEmpty($computer) -or $computer -eq '.') { $computer = $env:COMPUTERNAME }
# if the computername is its SamAccountName, it ends in a dollar sign.
$computer = $computer -replace '\$$', ''
if (!(Test-Connection -ComputerName $computer -Count 1 -Quiet)) {
Write-Warning "Computer '$computer' cannot be reached."
continue
}
$system = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer
$baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$computer)
foreach ($regPath in $UninstallPaths) {
$key = $baseKey.OpenSubKey($regPath)
# if the key exists
if ($key) {
$key.GetSubKeyNames() | ForEach-Object {
$subKey = $baseKey.OpenSubKey("$regPath$_")
$application = $subKey.GetValue('DisplayName')
if (($application) -and ($application -like $NamePattern)) {
if (!$ExcludeUpdates -or ($application -notlike "*update*")) {
[PSCustomObject]@{
'Computer' = $system.Name
'Application' = $application
'Version' = $subKey.GetValue('DisplayVersion')
'InstallLocation' = $subKey.GetValue('InstallLocation')
'UninstallString' = $subKey.GetValue('UninstallString')
'Publisher' = $subKey.GetValue('Publisher')
'LoggedOnUser' = $system.UserName
}
}
}
# close $subKey
if ($subKey) { $subKey.Close() }
}
# close $key
if ($key) { $key.Close() }
}
}
# close $baseKey
if ($baseKey) { $baseKey.Close() }
}
}
}
Note: if you have PowerShell 3.0 or better, you can change the line $system = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer
into $system = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $computer -Verbose:$false
which will perform faster
Use it like this:
Import-Module ActiveDirectory
$OuDn = 'DistinghuishedName of the OU you are interested in'
# get a list of computer names in the given OU
$computers = Get-ADComputer -Filter * -SearchBase $OuDn | Select-Object -ExpandProperty Name
# use the function to get a list of installed applicationa
$software = Get-InstalledSoftware -ComputerName $computers -NamePattern "Microsoft Office*" -ExcludeUpdates
# output to console or export to a CSV file
$software | Export-Csv -Path 'D:\software.csv' -NoTypeInformation -Encoding UTF8
Note: this function does all the work on your pc, so you must make sure you are running it as a user that has permission to read the registry keys on all of the machines.
Also, in order for a key to be opened remotely, both the server and client machines must be running the remote registry service, and have remote administration enabled.
Upvotes: 1