3

Windows 7:

cscript C:\Windows\System32\Printing_Admin_Scripts\en-US\prnmngr.vbs -g

Windows XP:

cscript C:\windows\system32\prnmngr.vbs -g

These will get the default printer of the current system. I was wondering if there is a way to run this on my computer to get the default printer of a remote computer by computer name?

I tried running:

psexec \\c78572 -i -d cscript C:\Windows\System32\Printing_Admin_Scripts\en-US\prnmngr.vbs -g

And it appears to run.. but I only see the results in a quick popup cmd line window on the remote computer and not on mine. All I see on my end is:

cscript started with process ID 568.

In powershell gwmi win32_printer -computername c78572 works.. but I don't know how to sort it to show me the default printer.

EDIT 12/20/13 I am trying to combine it with a show all printers and the default but I can't get it to work:

while (1) {
$tag1 = Read-Host 'Enter tag # or Q to quit'
if ($tag1 -eq "Q") {
    break;
}

cls

sc.exe \\$tag1 start RemoteRegistry;

cls

start-sleep -seconds 2

cls

$OSInfo = get-wmiobject -class win32_operatingsystem -computername $tag1;
$OSInfo | Format-Table -Property @{Name="OS Name";Expression={$_.Caption}},@{Name="System Boot Time";Expression={$_.ConvertToDateTime($_.LastBootUpTime)}} -AutoSize;


gwmi win32_printer -computername $tag1 | ft -Property @{Name="Printer Name";Expression={$_.Name}} -AutoSize;

$Computer = $tag1
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('currentuser', $Computer)
$RegKey= $Reg.OpenSubKey('Software\Microsoft\Windows NT\CurrentVersion\Windows')
$DefaultPrinter = $RegKey.GetValue("Device")
$DefaultPrinter | ConvertFrom-Csv -Header Name, Provider, Order| Select Name

# Alt method: Get-WmiObject win32_printer -computername c60311

}

Aaron
  • 3,135
  • 20
  • 51
  • 78

2 Answers2

9

You can use wmi32_printer to get the default. Here is the code:

$AllPrinters = gwmi win32_printer -computername c78572
$DefaultPrinter = $AllPrinters | where {$_.Default -eq $true}

This will return all locally attached printers. If you want to get a list of network attached printers (as Aaron commented below), you run into a little bit of an issue. The above script doesn't work because WMI operates on the local machine, and not on the user level. After much research, one way of getting this information is to have a log on script that runs, because there is essentially no other way of remotely using WMI to get the logged in user's information.

How to really do it if we can't use WMI? Use the back door. All the pertinent information is stored in the registry. The output may not be pretty, but it will give you all the information that we need. We are only concerned about 3 key locations:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers

This contains all Locally Installed printers. Forget about it, use the gwmi win32_printer command to get this list.

HKEY_CURRENT_USER\Printers\Settings

This contains all the Currently logged in User Installed printers. It does not have the default printer information.

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device

This is where to get the Currently logged in User Installed Default printer. i.e. This is what Aaron is specifically looking for.

So, we can use PowerShell to connect to the remote registry, and read the currently logged in user's default printer with the following script:

$Computer = "c78572"
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('currentuser', $Computer)
$RegKey= $Reg.OpenSubKey('Software\Microsoft\Windows NT\CurrentVersion\Windows')
$DefaultPrinter = $RegKey.GetValue("Device")
$DefaultPrinter | ConvertFrom-Csv -Header Name, Provider, Order| Select Name

----EDIT - to get a list of all printers----

To list all printers on the remote computer:

$Computer = "c78572"

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

#Get List of Network Printers:
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('currentuser', $Computer)
$RegKey= $Reg.OpenSubKey('Printers\Settings')
$Printers += @($RegKey.GetValueNames())

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


#Get Default Printer
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('currentuser', $Computer)
$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
HAL9256
  • 12,384
  • 1
  • 34
  • 46
  • Looks like the right command but the only problem is that they are network printers so it doesn't list them as default when in actuality they are set to one when you go and look. – Aaron Dec 18 '13 at 18:07
  • You are right, using WMI can't get the network printers of the users. Please see the above edits. I have added a way to get to the network printer for the currently logged in user. It can easily be modified to get the information from all the other non-logged in users on the box as well. – HAL9256 Dec 19 '13 at 18:29
  • I am trying to combine what you have with a printer list, then the default one below it...but it won't work. I edited my OP with my code. – Aaron Dec 20 '13 at 15:22
  • 2
    I know this is over a year old, but my comment. The Settings key doesn't contain the network printers, I see them listed under HKCU\Printers\Connections – Wayne In Yak Mar 20 '15 at 23:01
1

This script will return the specified computer's currently-logged-in user's default printer (read from the Registry).

We're trying to clean up some network printer connections, and a script like this that shows the shared printers that a user is connected to is something we really need.

My primary challenge was figuring out a way to get at the "current user" information (as opposed to the "computer" information). The shared printer connections are stored in the user area, so that's where I needed to be.

I pieced together information from several sources to do it this way:

  • Determine the logged-in user (account)
  • Get the SID for that user
  • Use the SID to navigate to the user's HKEY_USERS Registry hive
  • Output the value in SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Device. Before coding I determined that this Registry value is updated immediately upon a default printer change. BONUS: You can also change/set the user's default printer by updating this Registry value.
# ---------------------------------------------------------------------------
#
# This script requires a computer name.  It will return the computer's 
# currently logged-in user's default printer.
#
# ---------------------------------------------------------------------------

# Set the variable below to choose your computer
$Computer = "computer_name"


# get the logged-in user of the specified computer
$user = Get-WmiObject –ComputerName $computer –Class Win32_ComputerSystem | Select-Object UserName

# get that user's AD object
$AdObj = New-Object System.Security.Principal.NTAccount($user.UserName)

# get the SID for the user's AD Object 
$strSID = $AdObj.Translate([System.Security.Principal.SecurityIdentifier])

# get a handle to the "USERS" hive on the computer
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("Users", $Computer)

# get a handle to the current user's USERS Registry key where the default printer value lives
$regKey = $reg.OpenSubKey("$strSID\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows")

# read and show the new value from the Registry for verification
$regValue = $regKey.GetValue("Device")
write-output $regValue
write-output " "
write-output " "
[void](Read-Host 'Press Enter to continue…')
CraigD
  • 91
  • 5
  • Thanks. I commented my code pretty thoroughly and thought that would suffice. I'll add some more explanation in the body. – CraigD Apr 06 '20 at 21:50