调用OpenRemoteBaseKey时转换错误

时间:2015-07-31 15:46:54

标签: powershell remote-registry

运行代码时,我从powershell收到转换错误。我得到了一个"无法转换参数" 0",有价值:"无论用户是什么的sid",对于OpenRemoteBasekey。任何人都可以看看我的代码,看看我哪里出错了?

该脚本应该通过查看其注册表项为我提供域中特定用户的打印机列表。我必须将他们的用户名转换为他们的SID才能正确映射他们的注册表。

echo "What is the User name?"  

$user = [Console]::ReadLine()

#Convert Given username into an SID variable
$sid = ([wmi]"win32_userAccount.Domain='mydomain',Name='$user'").sid

echo "What is it's ip address?" 

#This can be an ip address or a host name
$ipuser = [Console]::ReadLine() 

Write-Host "Check 1"

#Get Local printers   
$Printers = @(Get-WmiObject win32_printer -computername $ipuser | Select Name)

#Get Network Printers 

$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey( $sid, $ipuser)

$RegKey = $Reg.OpenSubkey('Printers\Settings') 
$Printers += @($RegKey.GetValueNames())

#Output List of Printer
Write-Output $Printers |
  ft -Property @{Name="Printer Name"; Expression={$_.Name}} -AutoSize

#Get Default Printer
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($sid, $ipuser)
$RegKey= $Reg.OpenSubKey('Software\Microsoft\Windows NT\CurrentVersion\Windows')
$DefaultPrinter = $RegKey.GetValue("Device")

#Output the Default Printer
Write-Output $DefaultPrinter |
  ConvertFrom-Csv -Header Name, Provider, Order |
  Select Name |
  ft -Property @{Name="Default Printer Name";Expression={$_.Name}} -AutoSize

2 个答案:

答案 0 :(得分:0)

你看过这样一个完全是PowerShell的脚本吗?

所需模块:
PSRemoteRegistry和Active Directory

脚本如何运作:
创建一个文本文件,其中包含要获取映射的网络打印机信息的计算机名称列表 执行脚本,系统将提示您输入包含列表的文本文件的路径 通过对每台计算机进行ping操作,将验证每台计算机的连接性 通过WMI,它将检查哪个用户登录到响应ping的计算机 接下来,它将查询Active Directory以获取当前登录到其中一个轮询的活动计算机的每个用户的SID 使用用户SID创建远程注册表查询以枚举已登录用户的映射网络打印机列表。

包含映射打印机列表的日志文件和CSV文件位于C:\ temp \ logs
中 文件名:
MappedPrinters-(currentdate).csv - 包含映射打印机列表 NoMappedPrinters-(currentdate).log - 包含未在其计算机上映射网络打印机的用户列表。
NoReply-(currentdate).csv - 包含未响应ping的计算机列表 NoUsrLoggedIn-(currentdate).log - 包含响应ping但没有用户登录的计算机列表。
RemoteRegNotRunning-(currentdate).log - 包含远程注册表服务未运行的计算机列表。
WmiError-(currentdate).log - 如果有计算机无法通过wmi连接,则会在此处列出。

function global:Ping-Host {   
BEGIN {  

}  
    PROCESS {  
    $results = gwmi -Query "SELECT * FROM Win32_PingStatus WHERE Address = '$_'"  
    $obj2 = New-Object psobject  
    $obj2 | Add-Member Noteproperty Computer $_  
    $obj2 | Add-Member Noteproperty IPAddress ($results.protocoladdress)  

    if ($results.statuscode -eq 0) {  
    $obj2 | Add-Member NoteProperty Responding $True  
    } else {  
    $obj2 | Add-Member NoteProperty Responding $False  
}  
    Write-Output $obj2  

}  
END {}  

}  
function VerifyConnectivity {  
param (  
[parameter(ValueFromPipeline=$true)]  
$compList  
)  
BEGIN {  
$modeMSG = "Verifying Connectivity to Desktops"  
$HostComputer = @()  
$d = Get-Date  
$strDate = $d.ToString()  
$month = $d.Month  
$day = $d.Day  
$year = $d.Year  
$cDate = "$month-$day-$year"  
$logFilePath = "C:\temp\logs\"  
$NoReplyLog = $logFilePath + "NoReply-" + $cDate + ".csv"  
}  
PROCESS {  
$i = 1  
$numComp = $compList.Count  
If ($numComp -ge 1){  
Talk $modeMSG  
$HostComputer = $HostComputer + $(  
foreach ($computer in $compList){  
Write-Progress -Activity $modeMSG -Status "Currently Processing: $computer" -CurrentOperation "$i of $numComp" -PercentComplete ($i/$numComp*100)  
$computer | Ping-Host  
$i = $i + 1  

})  

}  
ElseIf ($numComp -lt 1){  
Write-Host "No Computers to Process"  
Exit  
}  
}  
END {  
$Alive = $HostComputer | Where {$_.Responding -eq "$true"}  
$global:Dead = $HostComputer | Where {$_.Responding -ne "$true"}  
$global:Dead | select Computer | Export-Csv -Path $NoReplyLog  
$Acomp = $Alive | select Computer  
$Acomp  
}  

}  

function GetPrinterInfo {  
param (  
[parameter(ValueFromPipeline=$true)]  
$compList  
)  
BEGIN {  
$d = Get-Date  
$strDate = $d.ToString()  
$month = $d.Month  
$day = $d.Day  
$year = $d.Year  
$cDate = "$month-$day-$year"  
$global:logFilePath = "C:\temp\logs\"  
$NoPrtMapLog = $logFilePath + "NoMappedPrinters-" + $cDate + ".log"  
$WmiErrorLog = $logFilePath + "WmiError-" + $cDate + ".log"  
$MappedPrinters = $logFilePath + "MappedPrinters-" + $cDate + ".csv"  
$NoUsrLoggedIn = $logFilePath + "NoUsrLoggedIn-" + $cDate + ".log"  
$RemoteRegNotRunning = $logFilePath + "RemoteRegNotRunning-" + $cDate + ".log"  
$ErrorActionPreference = 'SilentlyContinue'  
Import-Module activedirectory  
Import-Module psremoteregistry  
$global:wmiErrors = @()  
$global:NoUserLoggedIn = @()  
$CompUserInfo = @()  
$arrCompLogonInfo = @()  
$arrRemoteRegSvcStopped = @()  
$arrNoMappedPrinters = @()  
$arrMappedPrinters = @()  
$statusMSG = "Getting Logged on User Information"  
$statusMSG2 = "Getting User SID from Active Directory"  
$statusMSG3 = "Collecting Mapped Printer Information"  
}  
PROCESS {  
$u = 1  
$Responded = VerifyConnectivity $compList  
if ($Responded.count -gt 0){  
Talk $statusMSG  
foreach ($client in $Responded){  
[string]$c = $client.Computer  
$numClient = $Responded.Count  
$logonInfo = $null  
Write-Progress -Activity $statusMSG -Status "Currently Processing: $c" -CurrentOperation "$u of $numClient" -PercentComplete ($u/$numClient*100)    
$logonInfo = Get-WmiObject -ComputerName $c -Query "select * from win32_computersystem" | select Username  
if ($?){  
    if ($logonInfo.Username -ne $null){  
        [string]$strUserName = $logonInfo.Username  
        $arrStrUserName = $strUserName.Split("\")  
        $strUser = $arrStrUserName[1]   
        $objCUinfo = New-Object psobject  
        $objCUinfo | Add-Member NoteProperty Workstation $c  
        $objCUinfo | Add-Member NoteProperty User $strUser  
        $CompUserInfo = $CompUserInfo + $objCUinfo              
    }  
    elseif ($logonInfo.Username -eq $null){  
    $global:NoUserLoggedIn = $global:NoUserLoggedIn + $c  
    }  
}  
else {  
    $global:wmiErrors = $global:wmiErrors + "Could not Execute WMI Query to collect user logon information on $c"  
}  
$u = $u + 1  
}  
if ($CompUserInfo.Count -ge 1){  
    $u = 1  
    Talk $statusMSG2  
    foreach ($logon in $CompUserInfo){  
    [string]$userLN = $logon.User  
    $userCount = $CompUserInfo.count  
    [string]$wrksta = $logon.Workstation  
    Write-Progress -Activity $statusMSG2 -Status "Currently Processing: $userLN" -CurrentOperation "$u of $userCount" -PercentComplete ($u/$userCount*100)  
    $getSID = Get-ADUser -Identity $userLN | select SID  
    if ($?){  
        [string]$sid = $getSID.sid  
        $LoggedOnUserInfo = New-Object psobject  
        $LoggedOnUserInfo | Add-Member Noteproperty Workstation $wrksta  
        $LoggedOnUserInfo | Add-Member Noteproperty User $userLN  
        $LoggedOnUserInfo | Add-Member Noteproperty SID $sid  
        $arrCompLogonInfo = $arrCompLogonInfo + $LoggedOnUserInfo  
    }  
    $u = $u + 1  
    }  
}  
if ($arrCompLogonInfo.count -ge 1){  
    $u = 1  
    Talk $statusMSG3  
    foreach ($comp in $arrCompLogonInfo){  
    $numT = $arrCompLogonInfo.Count  
    $Printers = $null  
    [string]$cn = $comp.Workstation  
    [string]$usid = $comp.sid  
    [string]$uName = $comp.User  
    Write-Progress -Activity $statusMSG3 -Status "Currently Processing: $cn" -CurrentOperation "$u of $numT" -PercentComplete ($u/$userCount*100)  
    $regStat = Get-Service -ComputerName $cn -Name "RemoteRegistry"  
    If ($?){  
        If ($regStat.Status -eq "Running"){  
            $Printers =  Get-RegKey -ComputerName $cn -Hive "Users" -Key "$usid\Printers\Connections" -Recurse  
            If ($Printers -ne $null){  
            foreach ($printer in $Printers){  
            [string]$printerKey = $printer.key  
            $arrPrinterKey = $printerKey.Split("\")  
            $PrinterNamePiece = $arrPrinterKey[3]  
            $arrPrinterParts = $PrinterNamePiece.Split(",")  
            $printServer = $arrPrinterParts[2]  
            $PrinterName = $arrPrinterParts[3]  
            $PrinterUnc = "\\$printServer\$PrinterName"  
            $printInfo = New-Object psobject  
            $printInfo | Add-Member NoteProperty Workstation $cn  
            $printInfo | Add-Member NoteProperty User $uName  
            $printInfo | Add-Member NoteProperty PrintServer $printServer  
            $printInfo | Add-Member NoteProperty PrinterName $PrinterName  
            $printInfo | Add-Member NoteProperty PrinterUNC $PrinterUnc  
            $arrMappedPrinters = $arrMappedPrinters + $printInfo  
            }  
            }  
            ElseIf ($Printers -eq $null){  
                $arrNoMappedPrinters = $arrNoMappedPrinters + "$uName has no mapped printers on $cn"  
                }  
        }  
        ElseIf ($regStat.Status -eq "Stopped"){  
            $arrRemoteRegSvcStopped = $arrRemoteRegSvcStopped + $cn  
        }  
    }  
    $u = $u + 1  
    }  


}  

}  
}  
END {  
$arrMappedPrinters | Export-Csv -Path $MappedPrinters  
Add-Content $NoPrtMapLog $arrNoMappedPrinters  
Add-Content $WmiErrorLog $wmiErrors  
Add-Content $NoUsrLoggedIn $global:NoUserLoggedIn  
Add-Content $RemoteRegNotRunning $arrRemoteRegSvcStopped  
}  
}  

function Talk {  
 param (  
 [parameter(ValueFromPipeline=$true)]  
$talk  
)  
 Add-Type -AssemblyName System.Speech  
 $synthesizer = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer  
 $synthesizer.Speak($talk)  

}  

 cls  
$getPath = $(Read-Host "Enter path to the text file that contains the list of Computer Names`n")  
cls  
if ($getPath -like "*.txt"){  
$valid = Test-Path -Path $getPath  
if ($valid -eq $true){  
    $compList = get-content -Path $getPath   
    GetPrinterInfo $compList  
    Write-Host "The Script Output is located in $logfilepath"  
    Exit  

}  

Else {  
Write-Host "Path to file is not valid" -ForegroundColor Red  
}  
}  
Elseif ($getPath -notlike "*.txt"){  
Write-Host "Path to file is not valid"  
Exit  
} 

我也不能相信我刚刚使用过的脚本,但脚本位于here

答案 1 :(得分:0)

如有疑问,请阅读documentationOpenRemoteBaseKey()方法期望RegistryHive对象作为其第一个参数,而不是SID。这应该有效:

$hkcu = [Microsoft.Win32.RegistryHive]::CurrentUser
$Reg  = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hkcu, $ipuser)