简体   繁体   中英

trying to use Powershell to look in an OU in active directory for computers to see if they specific software

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM