The data is received by the browser and is available to you, it's just not visible on the page.
It's extremely frustrating from an admin perspective.
Here's an example of how to access the data:
Go to the network, go to Network-wide > Clients.
Filter by the SSID that has sponsored access.
Open Dev Tools in your browser.
Go to the network tab and click Preserve Log
Clear the network log to get a fresh log, then Click on a client that has an active connection.
Once the page loads, if you see in the Splash section "Authorized by ..." then you've got the data and you can query the logs for the info.
It'll be in the response of a page similar to this:
/[Network]/n/[Some kind of unique id]/manage/usage/client_show/[unique client id]?t0=&t1=×pan=86400&filter=
In the response of that page, you'll see the variable wireless_bigacl, the data returned will be something like this:
"wireless_bigacl": [
{
"raw_auth_reason": "s-sponsor",
"auth_reason": "Sponsored Guest",
"admin_only": false,
"authorized": "11 days",
"expires": "in 3 days",
"name": "My-Guest-SSID",
"vap": 3,
"sponsor_email": "approver@mysite.com",
"guest_email": "guestEmail@example.com",
"guest_name": "John Smith",
"total_requested_time": 1209600
}
],
Now, unfortunately, this data isn't currently available in the meraki API, but the API can help you compile a report to get this data.
I use powershell (v7) to do this, but the concept is the same for however you use the api.
Here's example code:
$BASE_URI = "https://api.meraki.com/api/v1"
$HEADER = @{
"X-Cisco-Meraki-API-Key" = "1111111111111111111111111111111111111"
"Authorization" = "Bearer 1111111111111111111111111111111111111"
"Content-Type" = "application/json"
"Accept" = "application/json"
}
$networkID = "L_1111111111111111111111"
$SSID = "My-Guest-SSID"
$timespan = 604800 # 1 week
$bodyParameters = @{
"timespan" = [Math]::Min($timespan, 2678400) #The number "2678400" is equivalent to 31 days in seconds (31 days × 24 hours × 60 minutes × 60 seconds)
"perPage" = 5000
#"vlan" = "1722"
"recentDeviceConnections" = @("Wireless")
} | ConvertTo-Json
$response1 = $null
$req = Invoke-RestMethod -Uri ($BASE_URI + "/networks/$networkID/clients") -Headers $HEADER -Method "GET" -PreserveAuthorizationOnRedirect -Body $bodyParameters -FollowRelLink -ResponseHeadersVariable $response1
if (!$req) {
throw "There was an error"
}
$wirelessGuests = $req | ForEach-Object { $_ } | Where-Object { $_.ssid -eq $SSID }
This gets you all the clients connected to the SSID within the specified time period (30 days max)
Then I go to dev tools and right click the request with the data I want and click copy -> copy as powershell.
I paste it into the next section of my code excluding the line for Invoke-WebRequest
Redacted example:
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
$session.Cookies.Add((New-Object System.Net.Cookie("two_factor_auth",...
$session.Cookies.Add((New-Object System.Net.Cookie("_gid", ,...
$session.Cookies.Add((New-Object System.Net.Cookie("BAYEUX_BROWSER", ,...
$session.Cookies.Add((New-Object System.Net.Cookie("OptanonAlertBoxClosed", ,...
$session.Cookies.Add((New-Object System.Net.Cookie("login_go_url", ,...
$session.Cookies.Add((New-Object System.Net.Cookie("_session_id_for_...
$session.Cookies.Add((New-Object System.Net.Cookie("dash_auth",,...
$session.Cookies.Add((New-Object System.Net.Cookie("_ga_,...
$session.Cookies.Add((New-Object System.Net.Cookie("OptanonConsent",,...
$session.Cookies.Add((New-Object System.Net.Cookie("_ga", ,...
$session.Cookies.Add((New-Object System.Net.Cookie("_gat_UA,...
Now we can loop through every client page and pull the info using this session:
$clientPage = "https://[endpoint].meraki.com/[network]/n/[uniqueID]/manage/usage/client_show/" ## Get this url from the dev tools "copy as powershell" output you got earlier
$responses = $wirelessGuests | foreach-object -Parallel {
Invoke-RestMethod -Uri "$clientPage$($_.id)" `
-WebSession $using:session `
-Headers @{#copy headers from dev tools output and put it here
} -RetryIntervalSec 5
Write-Host "completed $($_.id)"
}
$authorizedGuests = $responses | where-object { $null -ne $_.wireless_bigacl }
$unauthorizedGuests = $responses | where-object { $_.wireless_bigacl -eq $null }
$saveFileLocation = "$env:USERPROFILE\downloads\WirelessGuestAuthorizations-$(get-date -Format "yyyy-MM-dd_hh-mm-ss").csv"
$authorizedGuests | Select-Object `
id,
description,
ip,
vlan,
mac,
@{Name = 'first_seen'; Expression = { [datetime]::UnixEpoch.AddSeconds($_.first_seen).ToLocalTime() } },
@{Name = 'last_seen'; Expression = { [datetime]::UnixEpoch.AddSeconds($_.last_seen).ToLocalTime() } },
@{Name = 'recv_RAW'; Expression = { $_.recv } },
@{Name = 'sent_RAW'; Expression = { $_.sent } },
@{Name = 'recv'; Expression = { Convert-Size $_.recv } },
@{Name = 'sent'; Expression = { Convert-Size $_.sent } },
os,
device_type_prediction,
ssid_name,
@{Name = 'Device Group Policy'; Expression = { $_.group_policy_8021x } },
psk_group,
@{Name = 'auth_reason'; Expression = { $_.wireless_bigacl.auth_reason } },
@{Name = 'authorized'; Expression = { $_.wireless_bigacl.authorized } },
@{Name = 'expires'; Expression = { $_.wireless_bigacl.expires } },
@{Name = 'Total Requested Time'; Expression = { "$($_.wireless_bigacl.total_requested_time / 86400) days" } },
@{Name = 'sponsor_email'; Expression = { $_.wireless_bigacl.sponsor_email } },
@{Name = 'guest_email'; Expression = { $_.wireless_bigacl.guest_email } },
@{Name = 'guest_name'; Expression = { $_.wireless_bigacl.guest_name } } |
Export-Csv -Path $saveFileLocation -NoTypeInformation
$unauthorizedGuests | Select-Object `
id,
description,
ip,
vlan,
mac,
@{Name = 'first_seen'; Expression = { [datetime]::UnixEpoch.AddSeconds($_.first_seen).ToLocalTime() } },
@{Name = 'last_seen'; Expression = { [datetime]::UnixEpoch.AddSeconds($_.last_seen).ToLocalTime() } },
@{Name = 'recv_RAW'; Expression = { $_.recv } },
@{Name = 'sent_RAW'; Expression = { $_.sent } },
@{Name = 'recv'; Expression = { Convert-Size $_.recv } },
@{Name = 'sent'; Expression = { Convert-Size $_.sent } },
os,
device_type_prediction,
ssid_name,
@{Name = 'Device Group Policy'; Expression = { $_.group_policy_8021x } },
psk_group,
@{Name = 'auth_reason'; Expression = { $_.wireless_bigacl.auth_reason } },
@{Name = 'authorized'; Expression = { $_.wireless_bigacl.authorized } },
@{Name = 'expires'; Expression = { $_.wireless_bigacl.expires } },
@{Name = 'Total Requested Time'; Expression = { "$($_.wireless_bigacl.total_requested_time / 86400) days" } },
@{Name = 'sponsor_email'; Expression = { $_.wireless_bigacl.sponsor_email } },
@{Name = 'guest_email'; Expression = { $_.wireless_bigacl.guest_email } },
@{Name = 'guest_name'; Expression = { $_.wireless_bigacl.guest_name } } |
Export-Csv -Path $saveFileLocation -NoTypeInformation -Append
write-host "The results file has been saved to: " -NoNewline
write-host "$saveFileLocation" -ForegroundColor Green
Write-Host
start-process excel.exe $savefilelocation
This is just an example of how I do it. The code will not work exactly as is and you would need to tweak it to work for you.
Until they provide this information natively within the API, every time you have to need to query this information, you have to grab a new session to use.
I hope it is helpful.