远程注册表项提取器PowerShell脚本

远程注册表项提取器PowerShell脚本,powershell,active-directory,Powershell,Active Directory,我正在尝试创建一个PowerShell脚本,该脚本远程检查域中的每台计算机的注册表项,然后将该注册表项值和计算机名一起输出到.csv文件 到目前为止,脚本将域上的所有计算机输出到一个.csv文件,但将其本地注册表项值而不是远程计算机的值 任何帮助都将不胜感激,这是我迄今为止所得到的 Import-Module ActiveDirectory $SRVS = Get-ADComputer -Filter * -SearchBase 'DC=mydomain,DC=local' |

我正在尝试创建一个PowerShell脚本,该脚本远程检查域中的每台计算机的注册表项,然后将该注册表项值和计算机名一起输出到.csv文件

到目前为止,脚本将域上的所有计算机输出到一个.csv文件,但将其本地注册表项值而不是远程计算机的值

任何帮助都将不胜感激,这是我迄今为止所得到的

Import-Module ActiveDirectory

$SRVS = Get-ADComputer -Filter * -SearchBase 'DC=mydomain,DC=local' |
        select dnshostname

foreach ($SRV in $SRVS) {
    $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
    $REGKEY = $REG.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\QualityCompat")
    $MELT = $REGKEY.GetValue('cadca5fe-87d3-4b96-b7fb-a231484277cc')
    "$($SRV);$($MELT)" | Out-File C:\Users\user1\Desktop\regkeys.CSV -Append
}

实例化后,
RegistryKey
类不会公开它是远程密钥。这意味着您必须自己记录计算机名。远程注册表值也没有标准格式

如果我有一个PowerShell v5+,我会使用如下内容:

Import-Module ActiveDirectory

# No need for the Select-Object here since we're using $SRV.Name later
$SRVS = Get-ADComputer -Filter * -SearchBase 'DC=mydomain,DC=local'

# Create an arraylist to save our records
$Report = New-Object System.Collections.ArrayList

# This try finally is to ensure we can always write out what we've done so far
try {
    foreach ($SRV in $SRVS) {
        # Test if the remote computer is online
        $IsOnline = Test-Connection -ComputerName $SRV.Name -Count 1 -Quiet;
        if ($IsOnline) {
            # If system is Online
            $REG = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
            $REGKEY = $REG.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\QualityCompat")
            $MELT = $REGKEY.GetValue('cadca5fe-87d3-4b96-b7fb-a231484277cc')

            # Create a PSObject record for convenience
            $Record = [PSCustomObject]@{
                ComputerName = $SRV;
                Key          = $REGKEY.Name;
                Value        = $MELT;
            }
        }
        else {
            # If system is Offline
            # Create a PSObject record for convenience
            $Record = [PSCustomObject]@{
                ComputerName = $SRV;
                Key          = '';
                Value        = '';
            }
        }

        # Add our record to the report
        $Report.Add($Record);
    }
}
finally {
    # Always write out what we have whether or not we hit an error in the middle
    $Report | Export-Csv -Path "C:\Users\user1\Desktop\regkeys.csv" -NoTypeInformation
}

这可能在PowerShell v3+上运行,但我已经没有它可供测试了。

您为什么要打印实际的regkey而不是只检查它的存在

它要么存在,要么不存在。比如说用

Clear-Host 
Import-Module ActiveDirectory

$SRVS = (Get-ADComputer -Filter * -SearchBase (Get-ADDomainController).DefaultPartition)
$MeltHive = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\QualityCompat'
$MeltHiveKey = 'cadca5fe-87d3-4b96-b7fb-a231484277cc'

ForEach($Srv in $SRVS)
{
    Invoke-Command -ComputerName $Srv.Name -ScriptBlock {
            If (Get-ItemProperty -Path $Using:MeltHive -Name $MeltHiveKey -ErrorAction SilentlyContinue)
            {"On Host $env:COMPUTERNAME MELT registry information exists"}
            Else {Write-Warning -Message "On host $env:COMPUTERNAME MELT registry information does not exist"}
        }
}



ForEach($Srv in $SRVS)
{
    Invoke-Command -ComputerName $Srv.Name -ScriptBlock {
            If ((Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion) -match 'QualityCompat')
            {"On Host $env:COMPUTERNAME MELT registry information exists"}
            Else {Write-Warning -Message "On host $env:COMPUTERNAME MELT registry information does not exist"}
        }
}


Results of both the above is:

WARNING: On host DC01 MELT registry information does not exist
WARNING: On host EX01 MELT registry information does not exist
WARNING: On host SQL01 MELT registry information does not exist
On Host IIS01 MELT registry information exists
声明

$SRVS = Get-ADComputer ... | select dnshostname
[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
提供仅具有一个属性的自定义对象列表:
dnshostname
。但是,在循环中,您试图使用那些自定义对象没有的属性
名称
。因此声明

$SRVS = Get-ADComputer ... | select dnshostname
[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $SRV.name)
有效地成为

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $null)
这意味着您正在打开本地注册表,而不是远程主机上的注册表


$SRV.name
更改为
$SRV.dnshostname
,问题将消失。

$SRV.name
的值是多少?我想您可能需要
$SRV.dnshostname
。OP已经包含了主机名部分。他们的问题是
select dnshostname
只使用属性
dnshostname
为他们构建一个自定义对象列表,但随后他们尝试在循环中使用(不存在的)属性
name
。这将导致调用:OpenRemoteBaseKey('LocalMachine',$null),打开本地注册表。在第一个
调用命令中,
$MeltHiveKey
上缺少一个
$using:
,此方法比OP使用的WMI查询更具侵入性。在每台服务器上创建会话的开销要大得多。