2015-06-19 44 views
2

我正在嘗試編寫一個腳本來檢查我們網絡上的哪些打印服務器用戶正在連接到。爲此,我試圖檢查Printer \ Connections下列出的註冊表值。在我的本地機器下面兩種方法都工作:使用Powershell遠程驗證註冊表項

1)

GET-ChildItem HKCU:\打印機\連接

輸出:

Hive: HKEY_CURRENT_USER\Printers\Connections 

Name        Property 
-----        -------- 
,,printServer,printerName   GuidPrinter  : {guid} 
            Server    : \\printserver.domain 
            Provider   : win32spl.dll 
            LocalConnection : 1 
2)
>> Get-ChildItem HKCU:\Printers\Connections | ForEach-Object {Get-ItemProperty $_.pspath} 

而且該命令的輸出是:

GuidPrinter  : {guid} 
Server   : \\printServer.domain 
Provider  : win32spl.dll 
LocalConnection : 1 
PSPath   : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Printers\Connections\,,printServerName,printerName 
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Printers\Connections 
PSChildName  : ,,printServerName, printerName 
PSProvider  : Microsoft.PowerShell.Core\Registry  

通過本身,無論這些實現的被容易地應用到遠程機器。我最近試圖從遠程機器上獲取上面顯示的相同信息是:

$machine = 'computerName'; 
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('CurrentUser',$machine); 
$regKey = $reg.OpenSubKey("Printers\Connections"); 
$regKey.GetValueName() 

# I also tried the following which I didn't think 
# would work, but I was grasping at straws: 
# Get-ChildItem $regKey; 

上面的代碼不返回任何內容。它不會引發錯誤,但是regKey會返回一個空字符串。

有誰知道一種替代解決方案來獲取我正在查找的信息或在上面的實現中看到錯誤嗎?

謝謝。

回答

3

這是因爲您正在尋找的密鑰是HKEY當前用戶,雖然這是正確的,但每個用戶都會根據登錄的用戶而改變,所以當您遠程運行時,不會加載用戶的配置單元。你必須讓用戶運行它,最簡單的方法之一是通過它進入機器的啓動文件夾,它會運行並向他們報告,而他們不知道。

+0

好的,這是一個好主意。這樣我就可以使用我在第一篇文章中提到的前兩行中的任意一行,然後實現一種方法將結果發回給我。我現在不在我的電腦,但是我會在我回來後再測試一下。謝謝回覆。 – wrigley06

+0

沒問題,讓我們知道你是否需要幫助,不要忘了標記答案,以幫助其他人誰有這個相同的問題 – Luke

+0

@ Luke雖然是真的,使用HKCU不會給你的結果還需要其他方法來遠程獲取這些信息。它在很大程度上取決於環境,你可以用.net和wmi做到這一點。 – Matt

1

不完美,但我想出了這個。在研究其各部分時,有幾種不同的方法可以獲得相同的結果,但這是第一個能夠得到明顯結果的方法。功能缺乏,但我想展示的結果不僅僅是手段。

Function Get-NetworkPrinters($computer){ 
    # This was the only consistent way I could get the "users" to show up. win32_computersystem has a username but its null for me (UAC maybe?) 
    $remoteUsers = Get-WmiObject win32_process -ComputerName $computer -Filter 'Name = "explorer.exe"' -ErrorAction SilentlyContinue | ForEach-Object{ 
     $_.GetOwner().User 
    } 

    # Get the users sids from active directory. We need these to check the user hives. 
    $users = $remoteUsers | Get-ADUser | Select-Object samaccountname,name,sid 

    $users | ForEach-Object{ 
     # Keep the user for use in another pipe 
     $user = $_ 

     # Key that contains the mappings 
     $keyPath = "$($user.Sid)\Printers\Connections" 

     # Open the remote registry keys 
     $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::Users, $computer) 

     # Get the key names of connections which "match" printer mappings 
     $reg.OpenSubKey($keyPath).GetSubKeyNames() | ForEach-Object{ 
      $props = @{ 
       Printer = $_.Replace(",","\") 
       Computer = $computer 
       UserName = $user.samaccountname 
      } 

      New-Object -TypeName PSCustomObject -Property $props 
     } 
    } 
} 

您可以將個人計算機名稱傳遞給函數,它會找到登錄的用戶。通過這種方式,可以確定誰登錄的用戶是基於一個具有關聯的explorer.exe進程的用戶。對於這些用戶名中的每一個,再次檢查活動目錄以獲得他們的SID(Get-AdUser可能不是最好的方式,但它是簡單的)。然後我們使用該信息打開遠程註冊表並獲取網絡打印機配置。

一些樣本輸出:

UserName Printer      Computer 
-------- -------      -------- 
matt  \\printserver\kanexecutive01  mypc 
matt  \\printserver\kanlabel02   mypc 
matt  \\printserver\kanpublications01 mypc 
matt  \\printserver\kanpublications02 mypc 
matt  \\printserver\kantechrecords01  mypc 
matt  \\printserver\yowengineering02  mypc 
matt  \\printserver\ywglabel01   mypc 
matt  \\printserver\YEGlabelmtce01  mypc 

但是也有一些不佔幾個潛在的錯誤。所以這肯定會隨着時間的推移而改善。

你也可以考慮this question中涵蓋的其他遠程註冊表選項,如果我有什麼不能幫助你,可能會將它們適用於邏輯。

+0

感謝您提出這個問題。我一直想這樣做一段時間,但並不在乎解決方案。現在我有一個......至少對我來說。 – Matt