Skip to content

Instantly share code, notes, and snippets.

@darrenjrobinson
Created July 15, 2020 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenjrobinson/d5ef1c1d20e61834da405cb545c349ae to your computer and use it in GitHub Desktop.
Save darrenjrobinson/d5ef1c1d20e61834da405cb545c349ae to your computer and use it in GitHub Desktop.
Graph Recent Azure AD SignIns with a PowerShell Jupyter Notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Get Azure AD Recent SignIns and display on a Graph\n",
"\n",
"Use an Azure AD Registered Application with **AuditLog.Read.All** permissions to query the most recent 1000 Azure AD SignIns\n",
"Using the MSAL.PS PowerShell Module to simplify Microsoft Graph integration using PowerShell\n",
"\n",
"[Reference - https://blog.darrenjrobinson.com/microsoft-graph-using-msal-with-powershell/]( https://blog.darrenjrobinson.com/microsoft-graph-using-msal-with-powershell/ )\n",
"\n",
"To execute this example you will need to register an Azure AD Application with AuditLog.Read.All Application Microsoft Graph permissions then update the cell variables below for;\n",
"* your Registered App ClientID\n",
"* your Registered App ClientSecret\n",
"* your Azure AD TenantID"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<script type=\"text/javascript\">#!javascript\r\n",
"if ((typeof(requirejs) !== typeof(Function)) || (typeof(requirejs.config) !== typeof(Function))) { \r\n",
" let script = document.createElement(\"script\"); \r\n",
" script.setAttribute(\"src\", \"https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js\"); \r\n",
" script.onload = function(){\r\n",
" loadDotnetInteractiveApi();\r\n",
" };\r\n",
" document.getElementsByTagName(\"head\")[0].appendChild(script); \r\n",
"}\r\n",
"else {\r\n",
" loadDotnetInteractiveApi();\r\n",
"}\r\n",
"\r\n",
"function loadDotnetInteractiveApi(){\r\n",
" let apiRequire = requirejs.config({context:\"dotnet-interactive.48357.33315\",paths:{dotnetInteractive:\"http://localhost:33315/resources/dotnet-interactive\"}});\r\n",
" apiRequire(['dotnetInteractive'], \r\n",
" function(api) { \r\n",
" api.createDotnetInteractiveClient(\"http://localhost:33315/\", window);\r\n",
" },\r\n",
" function(error){\r\n",
" console.log(error);\r\n",
" });\r\n",
"}</script>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Count Name\n",
"----- ----\n",
" 77 11-07-2020\n",
" 171 12-07-2020\n",
" 227 13-07-2020\n",
" 483 14-07-2020\n",
" 92 15-07-2020\n",
"\n"
]
}
],
"source": [
"Install-Module -Name MSAL.PS -Force -AcceptLicense\n",
"Import-Module MSAL.PS\n",
"\n",
"$clientID = \"<AADRegisteredAppID>\"\n",
"$clientSecret = (ConvertTo-SecureString \"<AADRegisteredAppSecret>\" -AsPlainText -Force)\n",
"$tenantID = \"<AADTenantID>\"\n",
"$myAccessToken = Get-MsalToken -ClientId $clientID -ClientSecret $clientSecret -TenantId $tenantID -RedirectUri \"https://localhost\" \n",
"\n",
"$signIns = Invoke-RestMethod -Method Get `\n",
" -Uri \"https://graph.microsoft.com/beta/auditLogs/signIns?`$top=1000\" `\n",
" -Headers @{Authorization = \"Bearer $($myAccessToken.AccessToken)\" } \n",
"\n",
"$groupedByDate = $signIns.value | Group-Object {$_.createdDateTime.toString(\"dd-MM-yyyy\")} | Select-Object Count, Name\n",
"$groupedByDate"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bar Graph\n",
"An example of using New-PlotlyChart for a Bar Chart showing Azure Active Directory SignIns summarised by date. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div id=\"cd8d1900-71ad-4097-a8b0-b23f7f3c5edc\" style=\"width: 900px; height: 500px;\"></div>\r\n",
"<script type=\"text/javascript\">\n",
"\r\n",
"var renderPlotly = function() {\r\n",
" var xplotRequire = requirejs.config({context:'xplot-3.0.1',paths:{plotly:'https://cdn.plot.ly/plotly-1.49.2.min'}});\r\n",
" xplotRequire(['plotly'], function(Plotly) {\n",
"\n",
" var data = [{\"type\":\"bar\",\"x\":[\"11-07-2020\",\"12-07-2020\",\"13-07-2020\",\"14-07-2020\",\"15-07-2020\"],\"y\":[77,171,227,483,92],\"name\":\"Recent Azure AD SignIns\"}];\n",
" var layout = {\"title\":\"Recent Azure AD SignIns\",\"height\":350.0};\n",
" Plotly.newPlot('cd8d1900-71ad-4097-a8b0-b23f7f3c5edc', data, layout);\n",
" \n",
"});\r\n",
"};\r\n",
"if ((typeof(requirejs) !== typeof(Function)) || (typeof(requirejs.config) !== typeof(Function))) { \r\n",
" var script = document.createElement(\"script\"); \r\n",
" script.setAttribute(\"src\", \"https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js\"); \r\n",
" script.onload = function(){\r\n",
" renderPlotly();\r\n",
" };\r\n",
" document.getElementsByTagName(\"head\")[0].appendChild(script); \r\n",
"}\r\n",
"else {\r\n",
" renderPlotly();\r\n",
"}\n",
"</script>\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"$signInsGraphData = [Graph.Bar]::New()\n",
"$signInsGraphData.name = \"Recent Azure AD SignIns\"\n",
"$signInsGraphData.x = $groupedByDate.Name\n",
"\n",
"$signInSummaryCount = @()\n",
"foreach ($signInCount in $groupedByDate) {\n",
" $signInSummaryCount += $signInCount.Count\n",
"} \n",
"$signInsGraphData.y = $signInSummaryCount\n",
"\n",
"$graphLayout = [Layout]::New()\n",
"$graphLayout.title = \"Recent Azure AD SignIns\"\n",
"$graphLayout.height = 350\n",
"\n",
"New-PlotlyChart -Layout $graphLayout -Trace @($signInsGraphData) -Title \"Recent Azure AD SignIns\" | Out-Display\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Scatter Graph\n",
"An example of using New-PlotlyChart for a Scatter Chart showing Azure Active Directory SignIns summarised by date. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div id=\"829171a7-495c-4a13-a95c-bdd6328c2286\" style=\"width: 900px; height: 500px;\"></div>\r\n",
"<script type=\"text/javascript\">\n",
"\r\n",
"var renderPlotly = function() {\r\n",
" var xplotRequire = requirejs.config({context:'xplot-3.0.1',paths:{plotly:'https://cdn.plot.ly/plotly-1.49.2.min'}});\r\n",
" xplotRequire(['plotly'], function(Plotly) {\n",
"\n",
" var data = [{\"type\":\"scatter\",\"x\":[\"11-07-2020\",\"12-07-2020\",\"13-07-2020\",\"14-07-2020\",\"15-07-2020\"],\"y\":[77,171,227,483,92],\"name\":\"Recent Azure AD SignIns\"}];\n",
" var layout = {\"title\":\"Recent Azure AD SignIns\",\"height\":350.0};\n",
" Plotly.newPlot('829171a7-495c-4a13-a95c-bdd6328c2286', data, layout);\n",
" \n",
"});\r\n",
"};\r\n",
"if ((typeof(requirejs) !== typeof(Function)) || (typeof(requirejs.config) !== typeof(Function))) { \r\n",
" var script = document.createElement(\"script\"); \r\n",
" script.setAttribute(\"src\", \"https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js\"); \r\n",
" script.onload = function(){\r\n",
" renderPlotly();\r\n",
" };\r\n",
" document.getElementsByTagName(\"head\")[0].appendChild(script); \r\n",
"}\r\n",
"else {\r\n",
" renderPlotly();\r\n",
"}\n",
"</script>\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"$signInsGraphDataLine = [Graph.Scatter]::New()\n",
"$signInsGraphDataLine.name = \"Recent Azure AD SignIns\"\n",
"$signInsGraphDataLine.x = $groupedByDate.Name\n",
"\n",
"$signInSummaryCount = @()\n",
"foreach ($signInCount in $groupedByDate) {\n",
" $signInSummaryCount += $signInCount.Count\n",
"} \n",
"$signInsGraphDataLine.y = $signInSummaryCount\n",
"\n",
"New-PlotlyChart -Layout $graphLayout -Trace @($signInsGraphDataLine) -Title \"Recent Azure AD SignIns\" | Out-Display"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (PowerShell)",
"language": "PowerShell",
"name": ".net-powershell"
},
"language_info": {
"file_extension": ".ps1",
"mimetype": "text/x-powershell",
"name": "PowerShell",
"pygments_lexer": "powershell",
"version": "7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment