运行代码时,我从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
答案 0 :(得分:0)
所需模块:
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)
如有疑问,请阅读documentation。 OpenRemoteBaseKey()
方法期望RegistryHive
对象作为其第一个参数,而不是SID。这应该有效:
$hkcu = [Microsoft.Win32.RegistryHive]::CurrentUser
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hkcu, $ipuser)