I love that part of my job is helping people out in the forums as ScriptingAnswers.com. A recent post asked about finding out what network drives were mapped on a remote computer using PowerShell. The task sounded familiar so I poked around my script pile and found an old VBScript that used WMI and the Win32_NetworkConnection class. Great. Get-WMIObject to the rescue:
PS C:\> Get-WMIObject win32_networkconnection -computername Desk23
You even get a nicely formatted summary. But you me, I can’t resist tinkering so I wrote a function that enhances this basic command I call Get-NetConnections.
Function Get-NetConnections {
Param([string]$computername=$env:computername,
[switch]$progress)
#turn off the error pipeline
$ErrorActionPreference="SilentlyContinue"
#trap errors, display a message and continue
Trap {
Write-Warning "Error connecting to $computername"
Continue
}
#make $computername upper case for looks
$computername=$computername.ToUpper()
if ($progress) {
#if -progress is specified use Write-Progress to display what
#is happening
Write-Progress -Activity "Getting Network Connections" -status $computername `
-currentoperation "Executing Get-WMIObject Win32_NetworkConnection -computername $computername"
}
#get WMI information. Turn off error notification
$connections=Get-WmiObject win32_networkconnection -computername $computername -ea "Stop"
#validate connections were returned
if (!$connections) {
Write-Host "No network connections found on $computername" -foregroundcolor RED -backgroundcolor Yellow
Return $null
}
if ($progress) {
Write-Progress -Activity "Getting Network Connections" -status $computername `
-currentoperation "Parsing results"
}
$connections | select @{Name="Computer";Expression={$_.__SERVER}},`
@{Name="LocalName";Expression = {$_.LocalName.toUpper()}},`
@{Name="RemoteComputer";Expression={
#use regular expression to match the first part of the UNC
$_.RemotePath -match "[^\\]+" | Out-Null
($matches.Item(0)).ToUpper()
}},RemotePath,Status,ConnectionState
}
The function takes a computername as a parameter but defaults to the local computername. Because I realized you may want to process a list of computers and the WMI command takes a little bit of time to run, I thought having some sort of progress indication would be helpful. If you use -progress, then Write-Progress is called to display the current operation and status.
if ($progress) {
#if -progress is specified use Write-Progress to display what
#is happening
Write-Progress -Activity "Getting Network Connections" -status $computername `
-currentoperation "Executing Get-WMIObject Win32_NetworkConnection -computername $computername"
}
The main part of the function is the WMI command.
#get WMI information. Turn off error notification
$connections=Get-WmiObject win32_networkconnection -computername $computername -ea "Stop"
You’ll notice that I’m setting the common parameter -ErrorAction to “Stop”. This is because if there is an error connecting to the computer I want an exception to be raised so my Trap handler will be called.
#turn off the error pipeline
$ErrorActionPreference="SilentlyContinue"
#trap errors, display a message and continue
Trap {
Write-Warning "Error connecting to $computername"
Continue
}
I also turned off the Error pipeline to suppress any messages. But this makes me responsible for any error handling, which I do here. I also create my own notification should there be no mapped drives.
#validate connections were returned
if (!$connections) {
Write-Host "No network connections found on $computername" -foregroundcolor RED -backgroundcolor Yellow
Return $null
}
Assuming there are mapped drives found, I picked some properties that I felt you would be most interested in and tried to make them a little more user friendly. One property that I added is the remote computer name which I pull from the remote path using a regular expression.
$connections | select @{Name="Computer";Expression={$_.__SERVER}},`
@{Name="LocalName";Expression = {$_.LocalName.toUpper()}},`
@{Name="RemoteComputer";Expression={
#use regular expression to match the first part of the UNC
$_.RemotePath -match "[^\\]+" | Out-Null
($matches.Item(0)).ToUpper()
}},RemotePath,Status,ConnectionState
I realize there are other ways to use REGEX here but I wanted to stick with basic PowerShell. Here’s a sample of what you can expect:
Computer : CHAOS
LocalName : M:
RemoteComputer : JDH-NVNAS
RemotePath : \\jdh-nvnas\media
Status : OK
ConnectionState : Connected
Computer : CHAOS
LocalName : W:
RemoteComputer : WIN2K801
RemotePath : \\win2k801\c$
Status : Unavailable
ConnectionState : Disconnected
Computer : CHAOS
LocalName : X:
RemoteComputer : JDH-NVNAS
RemotePath : \\jdh-nvnas\files\vms\esx
Status : OK
ConnectionState : Connected
Computer : CHAOS
LocalName : Y:
RemoteComputer : JDHIT-DC01
RemotePath : \\jdhit-dc01\c$
Status : OK
ConnectionState : Connected
Computer : CHAOS
LocalName : Z:
RemoteComputer : JDH-NVNAS
RemotePath : \\jdh-nvnas\files\vms
Status : OK
ConnectionState : Connected
Naturally there are many ways you can use this function. Here are some examples.
PS C:\>Get-NetConnections -computer “File01” -progress
PS C:\> get-content computers.txt | foreach {
>> get-netconnections -computer $_ -progress} |
>> Where {$_.status -ne “OK”} | Export-CSV problems.csv
>>
PS C:\> #if you have the Quest cmdlets installed
PS C:\> $data=get-qadcomputer | foreach {
>> get-netconnections -computer $_.name -progress}
>>
PS C:\> $data | sort RemotePath |
>> format-table -groupby RemotePath Computer,LocalName,Status
These examples assume you’ve loaded the function into your PowerShell session.
Download the script file here.
Enjoy!
I may have been too quick on this. More testing is required.
I strongly suspect that Win32_Networkconnection is pulling information from HKCU in which case this will only work when you logon to the remote computer with the same credentials. I think I was too hasty in my blog post. I made the mistake of being logged on to the local and remote computer with the same account.