PDQ PowerShell scanner is here, and we think it is incredible! Once you are done jumping for joy, you may be wondering how to get started. Well, we have a few scripts available for you right out of the gate. There are a lot of great options in there to not only get you started but also help you see how to write your own and get the best results. Watch the accompanying video to this blog post here.
How to get Mapped Drives
With that in mind, let’s break down the Mapped Drives script that Colby wrote here. Is there such a thing as too much data? We don’t think so; We created this to help you have some more in-depth insights into your current environment.
Breaking down the script
The most important part of this script is grabbing the drives, this is a really quick one-liner. (See more about HKEY_USERS)
$Drives = Get-ItemProperty "Registry::HKEY_USERS\*\Network\*"
We are grabbing all this information for the currently logged-on user. It is possible to grab this for all users, but you get into some dicey territory where a lot can go wrong. It involves grabbing registry of all users, but if you plan to do that please pay special attention to his warning in those blogs.
Now that we have grabbed all these mapped drives, we are done, right? You could be, but you might not be thrilled with how the output looks. If all you are looking for is the drive path and drive letter, you could go with this. (See Get-ItemProperty, Select-Object)
$Drives = Get-ItemProperty "Registry::HKEY_USERS\*\Network\*" | Select-Object pschildname, remotepath
This will work, but you are getting less info, and the titles are not really clear either. So we took that output and put it into a pscustomobject where we can customize what we are getting. First, we need to break down the parent path for the SID. We will use this to put out both the SID as well as the user name.
$SID = ($Drive.PSParentPath -split '\\')[2]
Now that we have that we just need to put all that we have captured into the pscustomobject.
[PSCustomObject]@{
# Use .NET to look up the username from the SID
Username = ([System.Security.Principal.SecurityIdentifier]"$SID").Translate([System.Security.Principal.NTAccount])
DriveLetter = $Drive.PSChildName
RemotePath = $Drive.RemotePath
# The username specified when you use "Connect using different credentials".
# For some reason, this is frequently "0" when you don't use this option. I remove the "0" to keep the results consistent.
ConnectWithUsername = $Drive.UserName -replace '^0$', $null
SID = $SID
}
That should be all you need, but let’s show what it looks like when it is all put together. This will make it clear, as well as highlight that Colby explains it all way better with just a few comments!
Put it all together
# This is required for Verbose to work correctly.
# If you don't want the Verbose message, remove "-Verbose" from the Parameters field.
[CmdletBinding()]
param ()
# On most OSes, HKEY_USERS only contains users that are logged on.
# There are ways to load the other profiles, but it can be problematic.
$Drives = Get-ItemProperty "Registry::HKEY_USERS\*\Network\*"
# See if any drives were found
if ( $Drives ) {
ForEach ( $Drive in $Drives ) {
# PSParentPath looks like this: Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-21-##########-##########-##########-####\Network
$SID = ($Drive.PSParentPath -split '\\')[2]
[PSCustomObject]@{
# Use .NET to look up the username from the SID
Username = ([System.Security.Principal.SecurityIdentifier]"$SID").Translate([System.Security.Principal.NTAccount])
DriveLetter = $Drive.PSChildName
RemotePath = $Drive.RemotePath
# The username specified when you use "Connect using different credentials".
# For some reason, this is frequently "0" when you don't use this option. I remove the "0" to keep the results consistent.
ConnectWithUsername = $Drive.UserName -replace '^0$', $null
SID = $SID
}
}
} else {
Write-Verbose "No mapped drives were found"
}