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)"
}