尝试使用Powershell在活动目录中的OU中查找计算机,以查看它们是否为特定软件

时间:2019-04-11 00:00:19

标签: windows powershell active-directory

我对PowerShell还是很陌生,并且仍在学习如何使用它。我看到我可以使用一个名为Get-WmiObject的cmdlet,但是我不确定这是正确的选择。我见过有人说使用它时,它可能会在用户端引发错误,这会使用户感到困惑。

因此,人们在四处搜寻,我可以在OU中查询所有计算机的注册表,该注册表将在此处搜索“ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall”,并可能在此处搜索“ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall”。我遇到的问题是我不确定要开始使用哪个cmdlet(如果根本没有cmdlet),如何告诉它在特定注册表中进行搜索,同时还告诉它要通过OU中的每台计算机?检查。

我需要搜索所有安装了“ Microsoft Office”的计算机。谁能指出我正确的方向?我该怎么做?

1 个答案:

答案 0 :(得分:1)

首先,您需要在OU中获取计算机名称的列表,为此,您需要获取该OU的DistinghuishedName属性。 (在ADUC中查找-> OU属性->属性-> DistinghuishedName)

使用此功能,可以使用以下功能测试已安装的软件:

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() }
        }
    }
}

注意:如果您使用的是PowerShell 3.0或更高版本,则可以将行$system = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computer更改为$system = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $computer -Verbose:$false,这将使执行速度更快

像这样使用它:

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

注意:此功能可以在您的PC上完成所有工作,因此您必须确保以具有读取所有计算机上注册表项权限的用户身份运行它。

此外,为了远程打开密钥,服务器和客户端计算机都必须运行远程注册表服务,并且启用远程管理。 < / p>