When administering a Windows Server 2016 environment, one common pain point is determining which SMB protocol versions your connected clients are using. While Get-SmbConnection
shows outgoing connections, we need a different approach for inbound client connections.
Here are three reliable techniques to identify client SMB versions:
1. PowerShell with WMI:
Get-WmiObject -Class MSFT_SmbSession -Namespace Root\Microsoft\Windows\SMBServer |
Select-Object ClientComputerName, Dialect
2. Using Performance Counters:
Get-Counter -Counter "\SMB Server Sessions(*)\Dialect" |
Select-Object -ExpandProperty CounterSamples |
Where-Object {$_.CookedValue -ne 0} |
Format-Table -AutoSize
Combine these approaches into a reusable script:
function Get-SmbClientVersions {
$sessions = Get-SmbSession
$results = @()
foreach ($session in $sessions) {
$clientInfo = [PSCustomObject]@{
ClientIP = $session.ClientComputerName
Username = $session.UserName
SMBVersion = switch ($session.Dialect) {
"2.002" { "SMB 2.0" }
"2.???" { "SMB 2.1" }
"3.000" { "SMB 3.0" }
"3.002" { "SMB 3.1.1" }
default { "Unknown ($_)" }
}
SessionId = $session.SessionId
}
$results += $clientInfo
}
return $results
}
The dialect strings correspond to specific SMB versions:
- 2.002 = SMB 2.0 (Windows Vista/Server 2008)
- 2.??? = SMB 2.1 (Windows 7/Server 2008 R2)
- 3.000 = SMB 3.0 (Windows 8/Server 2012)
- 3.002 = SMB 3.1.1 (Windows 10/Server 2016)
For continuous monitoring, configure SMB auditing:
# Enable SMB auditing
Set-SmbServerConfiguration -AuditSmb1Access $true -Force
Set-SmbServerConfiguration -AuditSmb2Access $true -Force
# Query SMB connection events
Get-WinEvent -LogName "Microsoft-Windows-SmbClient/Security" |
Where-Object {$_.Id -eq 30800} |
Select-Object TimeCreated, Message
If you're not seeing expected results:
- Verify the SMB server service is running
- Check firewall settings (TCP 445 must be open)
- Ensure proper permissions (requires admin rights)
- Confirm clients are actually connected to shares
When administering a Windows Server 2016 environment, you might need to audit which SMB protocol versions (SMBv1, SMBv2, or SMBv3) your connected clients are using. While Get-SmbConnection
shows outgoing connections from the server, we need different techniques to monitor incoming client connections.
This approach taps into Windows Management Instrumentation to reveal active SMB sessions:
# Get all active SMB sessions with protocol version Get-WmiObject -Class Win32_ServerSession -ComputerName $env:COMPUTERNAME | Where-Object { $_.Active } | Select-Object UserName, ClientComputerName, @{Name="SMBVersion";Expression={ switch ($_.ProtocolType) { 0 { "SMB1" } 1 { "SMB2" } 2 { "SMB3" } default { "Unknown" } } }}
Windows Server logs SMB connection details in the Microsoft-Windows-SMBServer/Operational log:
# Query SMB server operational logs Get-WinEvent -LogName "Microsoft-Windows-SMBServer/Operational" -MaxEvents 100 | Where-Object { $_.Id -eq 3080 } | Select-Object TimeCreated, @{Name="ClientIP";Expression={ $_.Properties[0].Value }}, @{Name="SMBVersion";Expression={ $dialect = $_.Properties[4].Value if ($dialect -like "*2.1*") { "SMB3" } elseif ($dialect -like "*2.0*") { "SMB2" } else { "SMB1" } }}
SMB Server performance counters can reveal protocol version usage patterns:
# Check SMB protocol distribution Get-Counter -Counter "\SMB Server Sessions(*)\Dialect" | Select-Object -ExpandProperty CounterSamples | Where-Object { $_.InstanceName -notlike "*_Total*" } | Select-Object InstanceName, CookedValue
Combine these methods into a persistent monitoring solution:
# Persistent SMB version monitor $query = @" <QueryList> <Query Id="0" Path="Microsoft-Windows-SMBServer/Operational"> <Select Path="Microsoft-Windows-SMBServer/Operational"> *[System[Provider[@Name='Microsoft-Windows-SMBServer'] and (EventID=3080)]] </Select> </Query> </QueryList> "@ Register-WinEvent -Query $query -Action { param($event) $clientIP = $event.Properties[0].Value $dialect = $event.Properties[4].Value $version = switch -Wildcard ($dialect) { "*2.1*" { "SMB3" } "*2.0*" { "SMB2" } default { "SMB1" } } Write-Host "$(Get-Date -Format 'HH:mm:ss') - $clientIP connected via $version ($dialect)" }