在 Powershell 中使用远程注册表

在 Powershell 中使用远程注册表

我在 Google 上搜索过,也尝试过 Stackoverflow 和其他网站上的几个示例。虽然我可以使用解决方案中的命令来获取某些内容的注册表设置,但我无法从以下路径获取信息。

HKCU:\Software\Interwoven\WorkSite\8.0\EMM\Config

我知道此路径有效,因为我可以在注册表中将其提取出来,也可以使用 Powershell 之外的远程注册表将其提取出来。我使用的命令如下。

Invoke-Command –ComputerName ABC-V-12345 -Credential: 'domain\username' {Get-ItemProperty -Path 'HKCU:\Software\Interwoven\WorkSite\8.0\EMM\Config'}

我收到的错误如下:

Cannot find path 'HKCU:\SOFTWARE\Interwoven\WorkSite' because it does not exist.
    + CategoryInfo          : ObjectNotFound: (HKCU:\SOFTWARE\Interwoven\WorkSite:String) [Get-ItemProperty], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
    + PSComputerName        : ABC-V-12345

我如何获取该命令的返回数据?

下面是从每个命令收到的命令和错误消息的屏幕截图。

各种 PS 命令和错误消息

答案1

无需使用Invoke-Command,您可以使用注册表配置单元获取此信息[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey()HKEY_USERS为此
,您需要知道 (字符串) 用户 SID,使用 cmdlet 可以轻松获取Get-ADUser

下面的代码假设您想要获取当前登录远程计算机的用户的注册表信息:

Import-Module ActiveDirectory

$computerName = 'ABC-V-12345'

# get the domain\username of the user currently logged in to the computer
$user = (Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $computerName).UserName
# get the SID for that user 
$sid = (Get-ADUser -Identity $(($user -split '\\', 2)[0])).SID
if (!$sid) {
    Throw "Could not determine the SID for user '$user'"
}

# read the values in registry key 'HKEY_USERS\$sid\Software\Interwoven\WorkSite\8.0\EMM\Config'
$hive = [Microsoft.Win32.RegistryHive]::Users
$path = "$sid\Software\Interwoven\WorkSite\8.0\EMM\Config"

try {
    $base = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, $computerName)
    $key  = $base.OpenSubKey($path)
    if (!$key) {
        Write-Warning "Registry key '$path' does not exist"
    }
    else {
        $result = foreach ($ValueName in $key.GetValueNames()) {
            [PsCustomObject]@{
                'ValueName' = if (!$ValueName -or $ValueName -eq '@') { "(Default)" } else { $ValueName }
                'ValueData' = $key.GetValue($ValueName)
                'ValueKind' = $key.GetValueKind($ValueName)
            }
        }
    }
}
catch {
    Throw
}
finally {
    if ($key)  { $key.Close() }
    if ($base) { $base.Close() }
}

# output on screen
$result | Sort-Object ValueName

# or output to CSV file
$result | Sort-Object ValueName | Export-Csv -Path 'X:\output.csv' -NoTypeInformation

PS 如果您不在 ActiveDirectory 域中,则可以使用以下函数获取用户的 SID:

function Get-UserSID {
    param (
        [Parameter(ValuefromPipeline = $true, Position = 0)]
        [Alias('Account', 'User')]
        [string]$UserName = $env:USERNAME,
        [string]$Domain   = $env:USERDOMAIN
    )
    if ($UserName.Contains("\")) { $Domain, $UserName = $UserName -split '\\', 2 }   #"# split on the backslash
    try {
        $objUser = New-Object System.Security.Principal.NTAccount($Domain, $UserName)
        $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
        $strSID.Value
    }
    catch [System.Security.Principal.IdentityNotMappedException] {
        Write-Warning "User '$UserName' does not exist in '$Domain'"
    }
    catch {
        throw
    }
}

搭配使用:

$user = (Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $computerName).UserName
$sid = Get-UserSID $user

答案2

此空间中有 3 个 cmdlet。因此,配置单元的哪个方面将决定使用哪个。你没有找到所有三个吗?

获取项目获取位于指定位置的项目。

Invoke-Command –ComputerName 'ABC-V-12345' -ScriptBlock {Get-Item -Path 'HKCU:\Software\Interwoven\WorkSite\8.0\EMM\Config'} -Credential 'domain\username'

获取项目属性获取指定项目的属性。

Invoke-Command –ComputerName 'ABC-V-12345' -ScriptBlock {Get-ItemProperty -Path 'HKCU:\Software\Interwoven\WorkSite\8.0\EMM -Name Config'} -Credential 'domain\username' 

获取项目属性值 获取指定项的一个或多个属性的值。

Invoke-Command –ComputerName 'ABC-V-12345' -ScriptBlock {Get-ItemPropertyValue -Path 'HKCU:\Software\Interwoven\WorkSite\8.0\EMM -Name Config'} -Credential 'domain\username'

如果您刚刚这样做了...

Invoke-Command –ComputerName 'ABC-V-12345' -ScriptBlock {Get-ChildItem -Path 'HKCU:\Software\Interwoven\WorkSite\8.0\EMM' -Recurse} -Credential 'domain\username'

... 您是否也得到未找到或未找到任何内容的结果?

根据您的要求更新,将我的评论移至此处

@postnote 这个方法有效。请编辑答案以显示这一点,我会接受。但是,当我转到 8.0 时,EMM 名称不存在。我手动将其放入路径中,结果返回无法找到路径错误。我尝试了另一台计算机,方法相同,我知道所有键都打开了,然后找到了它。这在交互式会话中有效。谢谢。“Get-ChildItem -Path 'HKCU:\Software\Interwoven\WorkSite\8.0'”

在交互式会话中,不要使用调用,只需像平常一样使用 GCI 来查看返回的内容。因此,GCI 只交织,然后是 WorkSite 等...每当您看到这个 ...Name[0]... 时,都意味着您没有传入所有需要的参数。但是,根据您正在做的事情,这不应该是一件事。因此,一次执行一条 GCI 路径,然后查看返回的内容。

不用担心,很高兴这能帮你得到结果。但是,交互式会话中的任何内容都应该在隐式远程会话/使用 Invoke 中工作。因此,正如你所发现的,有些系统可能没有这个,所以,修改你的代码,让它有一个 if/then 或 try/catch 来处理这个问题。

类似于这个...

Invoke-Command –ComputerName 'ABC-V-12345' -ScriptBlock {
Try { Get-ChildItem -Path 'HKCU:\Software\Interwoven\WorkSite\8.0' -Recurse}
Catch {Write-Warning -Message "The registry path / key / value was not found on $env:ComputerName"}
} -Credential 'domain\username'

相关内容