PowerShell Objects Printers and Patterns
In this post, I'm going to discuss how I used PowerShell custom objects to identify patterns in system data for a very intermittent printer problem. I'm not going to focus on the mechanics. There is always a better way to query the registry, and WMI. By literally painting a picture with PowerShell I am going to focus on what to store as custom PowerShell objects and how to tie it altogether. Redirected printers, Remote Desktop, and an old custom application are like the "Magic Man" from #TalledegaNights.
"Now you see them, now you don't!"
Printers are supposed to be simple. It is mind boggling how I have been working this issue for 4 straight days. First off, I'm new to this environment. I know that some use Citrix and some folks use Remote Desktop (RD).
The problem of the day: Printers keep disappearing from an old custom application. I totally understand, these people print for their job. It is kind of a big deal. #RonBurgundy
How do I peel back the onion on this one? PowerShell and custom objects of course!
To start painting the picture, I start asking questions and answering them with PowerShell. Who is using the server? Who might have the problem? I know there is a query user /server:<ServerName> command. That command provides a wealth of information. Woudn't it be nice if that came back as objects that I could sort by time? I really need to know who is actively working and pass that on to the next step. I already have a function to start a process, redirect the standard output, and return an object. I also tagged the output object with a SessionType property since I am dealing with both CITRIX and Remote Desktop session. For this particular problem, I only care about Remote Desktop. After the objects are built, I can easily tell who is not idle, what kind of session they had, and immediately start looking into those accounts.
It took a while to parse the output and turn it into objects, however it was well worth it. I highly recommend adding this capability to your toolbox. From an operational perspective, quickly being able to answer the question “Who is actively using the server?” is a great tool to have. Other folks have done this, however, like many of you I like to adapt concepts and ideas to fit my own style and format. I usually learn something along the way that makes the time investment well worth it.
The next question is about the printers. What is the default that folks have on their workstations? In the remote session? What does the registry look like? How does it work? This problem is indeed intermittent. If I wait for the users to tell me what is happening, I’ll never get the answer. I’d much rather crush this problem with PowerShell anyway.
On to the PowerShell:
I need a way to remotely query the HKCU registry on the workstation and in the remote session. To do that, I will need the user SID. To get the SID, I ended up modifying the Session tool (query user) to query win32_userprofile and match the user name from the session to the LocalPath. There are many ways to do this one (SID). I did the quick and dirty for now and will likely revisit when I have more time.
For the actual registry query I had to use stdregprov through WMI since the “RemoteRegistry” service is turned off. I absolutely think it is AMAZING that I can remotely query HKCU registry keys without the “RemoteRegistry” service. The syntax is a little complicated, however another great capability to add to your toolbox.
For the actual problem investigation, here are the keys that I ended up gathering:
HKEY_USERS\<UserSID>\Software\Microsoft\Windows NT\CurrentVersion\Windows - Device (Contains the default printer)
HKEY_USERS\<UserSID>\Software\Microsoft\Windows NT\CurrentVersion\Windows\SessionDefaultDevices (Enum Key – this was to get the session key)
HKEY_USERS\<UserSID>\Software\Microsoft\Windows NT\CurrentVersion\Windows\SessionDefaultDevices\<sessionkey> - Device (Contains the default printer in the session)
HKEY_USERS\<UserSID>\Software\Microsoft\Windows NT\CurrentVersion\Devices (Enum Values - This key had many copies of session printers that didn’t seem to get cleaned up between sessions. In addition to retrieving the values, I also counted them)
I was also quick to realize that there was a direct correlation between the local print spooler and what was available in the session. For example, if the local print spooler was stopped, the local printers did not show up in the session. So just as another data point, I captured the CreationDate and memory for “spoolsv.exe” from Win32_Process. Why not …
The absolute key to managing all of this information and data point is storing the information in custom PowerShell object. Otherwise, I’d be looking at user registry keys until I’m blue in the face. Here are the properties that the object has:
Computer (Name of the computer/server)Online (True/False
SID (Value of the user SID)
UserName (UserId that belongs to the SID)
SessionType (Remote Desktop or Citrix – for this problem I only cared about RD)
DefaultPrinter (Reg key that is used when there are not redirected session printers)
SessionDefaultPrinter (Reg key that shows the default when there are redirected printers)
DevicesKey (List of Devices)
DeviceKeyCount (Number since they aren’t cleaned up)
SessionDefaultNotInDevices (True/False – found that printers were missing when this was true. Why keep looking if I could just do an IF/Then?)
PrintSpooler_CreationDate (Time the Print Spooler was started – just more data points)
PrintSpooler_WorkingSetSize_MB (Memory of the Print Spooler – just more data points)
A lot of work so far, however now I can quickly look across all Remote Desktop users of the server and identify when they have printer issues.
Through custom PowerShell object, I’ve been able to shed a little light on printer redirection and some nuances of how it works. Now I can focus my time to looking for further patterns in the system data to solve this intermittent problem.
Answering the “What does the system look like?” question with PowerShell objects generally has helped me sharpen my skills and work more productively in an industry that is overwhelmed at times with information.
I’ll update this post when I do find the solution.
Feedback is welcome and follow Dustin Higgins on Twitter
#PowerShell #CustomObjects #SharpenTheSaw #PatternsInData
-DHB
Edited by user Monday, October 28, 2019 9:04:43 AM(UTC)
| Reason: Not specified