AADUserInfo Function
This commit is contained in:
Родитель
83525d19a7
Коммит
58b3642d56
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"ms-azuretools.vscode-azurefunctions",
|
||||
"ms-vscode.PowerShell"
|
||||
]
|
||||
}
|
|
@ -8,12 +8,17 @@
|
|||
"name": "Launch Program",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"args": ["${relativeFile}"],
|
||||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
|
||||
"args": [
|
||||
"${relativeFile}"
|
||||
],
|
||||
"runtimeArgs": [
|
||||
"--nolazy",
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"protocol": "inspector",
|
||||
|
||||
"protocol": "inspector"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
|
@ -26,7 +31,11 @@
|
|||
"--colors",
|
||||
"${workspaceFolder}/.script/test"
|
||||
],
|
||||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
|
||||
"runtimeArgs": [
|
||||
"--nolazy",
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
},
|
||||
|
@ -41,9 +50,21 @@
|
|||
"--colors",
|
||||
"${file}"
|
||||
],
|
||||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
|
||||
"runtimeArgs": [
|
||||
"--nolazy",
|
||||
"-r",
|
||||
"ts-node/register"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
},
|
||||
{
|
||||
"name": "Attach to PowerShell Functions",
|
||||
"type": "PowerShell",
|
||||
"request": "attach",
|
||||
"customPipeName": "AzureFunctionsPSWorker",
|
||||
"runspaceId": 1,
|
||||
"preLaunchTask": "func: host start"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"powershell.codeFormatting.addWhitespaceAroundPipe": true
|
||||
"powershell.codeFormatting.addWhitespaceAroundPipe": true,
|
||||
"azureFunctions.deploySubpath": "DataConnectors\\AADUserInfo",
|
||||
"azureFunctions.projectLanguage": "PowerShell",
|
||||
"azureFunctions.projectRuntime": "~3",
|
||||
"debug.internalConsoleOptions": "neverOpen"
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "func",
|
||||
"command": "host start",
|
||||
"problemMatcher": "$func-powershell-watch",
|
||||
"isBackground": true,
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/DataConnectors\\AADUserInfo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.git*
|
||||
.vscode
|
||||
local.settings.json
|
||||
test
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
# Azure Functions artifacts
|
||||
bin
|
||||
obj
|
||||
appsettings.json
|
||||
local.settings.json
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"bindings": [
|
||||
{
|
||||
"name": "Timer",
|
||||
"type": "timerTrigger",
|
||||
"direction": "in",
|
||||
"schedule": "0 */1440 * * * *"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# TimerTrigger - PowerShell
|
||||
|
||||
The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule. This sample demonstrates a simple use case of calling your function every 5 minutes.
|
||||
|
||||
## How it works
|
||||
|
||||
For a `TimerTrigger` to work, you provide a schedule in the form of a [cron expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)(See the link for full details). A cron expression is a string with 6 separate expressions which represent a given schedule via patterns. The pattern we use to represent every 5 minutes is `0 */5 * * * *`. This, in plain text, means: "When seconds is equal to 0, minutes is divisible by 5, for any hour, day of the month, month, day of the week, or year".
|
||||
|
||||
## Learn more
|
||||
|
||||
<TODO> Documentation
|
|
@ -0,0 +1,83 @@
|
|||
# Input bindings are passed in via param block.
|
||||
param($Timer)
|
||||
|
||||
# Get the current universal time in the default string format
|
||||
$currentUTCtime = (Get-Date).ToUniversalTime()
|
||||
|
||||
# The 'IsPastDue' porperty is 'true' when the current function invocation is later than scheduled.
|
||||
if ($Timer.IsPastDue) {
|
||||
Write-Host "PowerShell timer is running late!"
|
||||
}
|
||||
|
||||
Import-Module AzureAD -UseWindowsPowerShell
|
||||
|
||||
# Function to build the Authorization signature for the Log Analytics Data Connector API
|
||||
Function Build-Signature ($customerId, $sharedKey, $date, $contentLength, $method, $contentType, $resource)
|
||||
{
|
||||
$xHeaders = "x-ms-date:" + $date
|
||||
$stringToHash = $method + "`n" + $contentLength + "`n" + $contentType + "`n" + $xHeaders + "`n" + $resource
|
||||
|
||||
$bytesToHash = [Text.Encoding]::UTF8.GetBytes($stringToHash)
|
||||
$keyBytes = [Convert]::FromBase64String($sharedKey)
|
||||
|
||||
$sha256 = New-Object System.Security.Cryptography.HMACSHA256
|
||||
$sha256.Key = $keyBytes
|
||||
$calculatedHash = $sha256.ComputeHash($bytesToHash)
|
||||
$encodedHash = [Convert]::ToBase64String($calculatedHash)
|
||||
$authorization = 'SharedKey {0}:{1}' -f $customerId,$encodedHash
|
||||
|
||||
# Dispose SHA256 from heap before return.
|
||||
$sha256.Dispose()
|
||||
|
||||
return $authorization
|
||||
}
|
||||
|
||||
# Function to create and invoke an API POST request to the Log Analytics Data Connector API
|
||||
Function Post-LogAnalyticsData($customerId, $sharedKey, $body, $logType)
|
||||
{
|
||||
$method = "POST"
|
||||
$contentType = "application/json"
|
||||
$resource = "/api/logs"
|
||||
$rfc1123date = [DateTime]::UtcNow.ToString("r")
|
||||
$contentLength = $body.Length
|
||||
$signature = Build-Signature `
|
||||
-customerId $customerId `
|
||||
-sharedKey $sharedKey `
|
||||
-date $rfc1123date `
|
||||
-contentLength $contentLength `
|
||||
-method $method `
|
||||
-contentType $contentType `
|
||||
-resource $resource
|
||||
$uri = "https://" + $customerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
|
||||
|
||||
$headers = @{
|
||||
"Authorization" = $signature;
|
||||
"Log-Type" = $logType;
|
||||
"x-ms-date" = $rfc1123date;
|
||||
}
|
||||
|
||||
$response = Invoke-RestMethod -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body
|
||||
#$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
|
||||
return $response.StatusCode
|
||||
|
||||
}
|
||||
|
||||
# Get Managed Service Identity info from Azure Functions Application Settings
|
||||
$msiEndpoint = $env:MSI_ENDPOINT
|
||||
$msiSecret = $env:MSI_SECRET
|
||||
|
||||
# Define the Log Analytics Workspace ID and Key
|
||||
$CustomerId = $env:workspaceId
|
||||
$SharedKey = $env:workspaceKey
|
||||
|
||||
connect-azaccount -identity
|
||||
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
|
||||
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.windows.net").AccessToken
|
||||
Connect-AzureAD -AadAccessToken $aadToken -AccountId $context.Account.Id -TenantId $context.tenant.id
|
||||
$Users = Get-AzureADUser -All $True
|
||||
$json = ConvertTo-Json $Users -Depth 3
|
||||
|
||||
Post-LogAnalyticsData -customerId $customerId -sharedKey $sharedKey -body ([System.Text.Encoding]::UTF8.GetBytes($json)) -logType "AADUserInfov2"
|
||||
|
||||
# Write an information log with the current time.
|
||||
Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"
|
Двоичный файл не отображается.
|
@ -0,0 +1,88 @@
|
|||
# Deploy a Function App for collecting Azure AD User Information data into Azure Sentinel
|
||||
This function app run daily, query Azure AD for all users and write the information to Log Analyitcs.
|
||||
|
||||
Note: There is a parser avaialbe [here](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/AADUserInfo/AADUserInfo.txt)
|
||||
### Deploy the Function App
|
||||
The easiest way is via the provided ARM templates:
|
||||
|
||||
#### 1: Deploy via Azure ARM Template
|
||||
1. Deploy the template.
|
||||
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FAADUserInfo%2Fazuredeploy.json" target="_blank">
|
||||
<img src="https://aka.ms/deploytoazurebutton""/>
|
||||
</a>
|
||||
|
||||
2. Deploy permissions for the function to the Key Vault.
|
||||
|
||||
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FAADUserInfo%2Fazuredeploy_kv.json" target="_blank">
|
||||
<img src="https://aka.ms/deploytoazurebutton""/>
|
||||
</a>
|
||||
|
||||
Alternatively you can deploy the elements manually.
|
||||
#### 2: Deploy via VS Code
|
||||
Note: You will need to prepare VS code for Azure function development. See https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-function-powershell#prerequisites
|
||||
1. Download the [Zip](https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AADUserInfo/AADUserInfo_template.zip?raw=true) file of the Azure Funciton app from Github.
|
||||
2. Extract to a location on your local host.
|
||||
3. Open VS Code.
|
||||
4. Click File -> Open Folder.
|
||||
5. Select the top level folder from extracted files.
|
||||
6. Type Crtl+Shift+P.
|
||||
7. Click Azure Functions: Deploy to function app. You maybe asked to sign in to Azure.
|
||||
8. Click Create New function app in Azure (advanced).
|
||||
9. Provide a unique name like "AADUserInfo". Press Enter.
|
||||
10. Click Windows.
|
||||
11. Click Consumption.
|
||||
12. Click PowerShell.
|
||||
13. Click Create new Resource Group.
|
||||
14. Press enter to accept the name.
|
||||
15. Click Create a new storage Account.
|
||||
16. Press enter to accept the name.
|
||||
17. Click Create new Application Insights resource.
|
||||
18. Press enter to accept the name.
|
||||
19. Pick a location to deploy in.
|
||||
20. Deployment will begin.
|
||||
21. Wait for the deployment to complete, then click upload settings in the bottom right.
|
||||
22. Click yes to all to upload.
|
||||
23. Go to the Azure Portal.
|
||||
24. Go to the resource group that was created. Click the Function.
|
||||
25. Click Stop.
|
||||
26. Click Identity.
|
||||
27. Click On under system assigned. Click Save. Click Yes.
|
||||
29. Click Configuration
|
||||
30. Click General Settings.
|
||||
31. Change Platform to 64 Bit. Click Save.
|
||||
|
||||
### Create a Key Vault
|
||||
1. Go to the Azure Portal.
|
||||
2. Go to the resource group that was created. Click Add.
|
||||
3. Type Key Vault.
|
||||
4. Create a Key vault.
|
||||
5. Go to the resource created.
|
||||
6. Click Access Policies.
|
||||
7. Click Add Access Policy.
|
||||
8. Select Secret Management from Configure from template.
|
||||
9. Click Select Principal.
|
||||
10. Search for the name of the function app. Click Select.
|
||||
11. Click Add.
|
||||
12. Click Save.
|
||||
13. Click Secrets.
|
||||
14. Click Generate.
|
||||
15. Enter WorkspaceKey. Paste in your Azure Sentinel Workspace Key. Click Create.
|
||||
16. Click Generate.
|
||||
17. Click WorkspaceKey and copy the current version string to a temporary location.
|
||||
|
||||
### Configure Settings for the Function
|
||||
1. Go to the Azure Portal.
|
||||
2. Go to the resource group that was created. Click the Function.
|
||||
3. Click Configuration.
|
||||
4. Click edit next to workspaceKey.
|
||||
5. Update the value using the string copied from KeyVault.
|
||||
* @Microsoft.KeyVault(SecretUri=https://<dnsname>/secrets/workspaceKey/<versionstring>)
|
||||
6. Click Ok.
|
||||
7. Click edit next to workspaceId.
|
||||
8. Update the value with your Sentinel Workspace Id.
|
||||
9. Click Ok.
|
||||
11. Click Save.
|
||||
|
||||
If sucessfully deployed you should start to see events appear in your Azure Sentinel workpsace as soon as they are generated.
|
||||
If you run into issues there are a number of options for [monitoring](https://docs.microsoft.com/en-us/azure/azure-functions/functions-monitoring?tabs=cmd) and [deugging](https://docs.microsoft.com/en-us/azure/azure-functions/functions-debug-powershell-local) your Function App.
|
|
@ -0,0 +1,251 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"FunctionName": {
|
||||
"defaultValue": "AADUserInfo",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceID": {
|
||||
"type": "string",
|
||||
"defaultValue": "<workspaceID>"
|
||||
},
|
||||
"workspaceKey": {
|
||||
"type": "string",
|
||||
"defaultValue": "<workspaceKey>"
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Insights/components",
|
||||
"apiVersion": "2015-05-01",
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"kind": "web",
|
||||
"properties": {
|
||||
"Application_Type": "web",
|
||||
"ApplicationId": "[parameters('FunctionName')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.KeyVault/vaults",
|
||||
"apiVersion": "2016-10-01",
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"sku": {
|
||||
"family": "A",
|
||||
"name": "standard"
|
||||
},
|
||||
"tenantId": "[subscription().tenantId]",
|
||||
"enabledForDeployment": false,
|
||||
"enabledForDiskEncryption": false,
|
||||
"enabledForTemplateDeployment": true,
|
||||
"enableSoftDelete": true,
|
||||
"accessPolicies": [
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.KeyVault/vaults/secrets",
|
||||
"apiVersion": "2016-10-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/workspaceKey')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.KeyVault/vaults', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"value": "[parameters('workspaceKey')]",
|
||||
"contentType": "string",
|
||||
"attributes": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[tolower(parameters('FunctionName'))]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"kind": "StorageV2",
|
||||
"properties": {
|
||||
"networkAcls": {
|
||||
"bypass": "AzureServices",
|
||||
"virtualNetworkRules": [
|
||||
],
|
||||
"ipRules": [
|
||||
],
|
||||
"defaultAction": "Allow"
|
||||
},
|
||||
"supportsHttpsTrafficOnly": true,
|
||||
"encryption": {
|
||||
"services": {
|
||||
"file": {
|
||||
"keyType": "Account",
|
||||
"enabled": true
|
||||
},
|
||||
"blob": {
|
||||
"keyType": "Account",
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"keySource": "Microsoft.Storage"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"apiVersion": "2018-02-01",
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "Y1",
|
||||
"tier": "Dynamic"
|
||||
},
|
||||
"kind": "functionapp",
|
||||
"properties": {
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"workerSize": "0",
|
||||
"workerSizeId": "0",
|
||||
"numberOfWorkers": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/default')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(parameters('FunctionName')))]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"properties": {
|
||||
"cors": {
|
||||
"corsRules": [
|
||||
]
|
||||
},
|
||||
"deleteRetentionPolicy": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/fileServices",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/default')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(parameters('FunctionName')))]"
|
||||
],
|
||||
"sku": {
|
||||
"name": "Standard_LRS",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"properties": {
|
||||
"cors": {
|
||||
"corsRules": [
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', tolower(parameters('FunctionName')))]",
|
||||
"[resourceId('Microsoft.Web/serverfarms', parameters('FunctionName'))]",
|
||||
"[resourceId('Microsoft.KeyVault/vaults', parameters('FunctionName'))]",
|
||||
"[resourceId('Microsoft.Insights/components', parameters('FunctionName'))]"
|
||||
],
|
||||
"kind": "functionapp",
|
||||
"identity": {
|
||||
"type": "SystemAssigned"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[parameters('FunctionName')]",
|
||||
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('FunctionName'))]",
|
||||
"httpsOnly": true,
|
||||
"clientAffinityEnabled": true
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"apiVersion": "2018-11-01",
|
||||
"type": "config",
|
||||
"name": "appsettings",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Web/sites/', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"use32BitWorkerProcess": false,
|
||||
"FUNCTIONS_EXTENSION_VERSION": "~3",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "powershell",
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', parameters('FunctionName')), '2015-05-01').InstrumentationKey]",
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', parameters('FunctionName')), '2015-05-01').ConnectionString]",
|
||||
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(parameters('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(parameters('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
|
||||
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(parameters('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(parameters('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
|
||||
"WEBSITE_CONTENTSHARE": "[toLower(parameters('FunctionName'))]",
|
||||
"workspaceID": "[parameters('workspaceID')]",
|
||||
"workspaceKey": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('FunctionName'), 'workspaceKey')).SecretUriWithVersion, ')')]",
|
||||
"WEBSITE_RUN_FROM_PACKAGE": "https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/AADUserInfo/AADUserInfo_template.zip?raw=true" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Web/sites/hostNameBindings",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/', parameters('FunctionName'), '.azurewebsites.net')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"siteName": "[parameters('FunctionName')]",
|
||||
"hostNameType": "Verified"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/default/azure-webjobs-hosts')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publicAccess": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/default/azure-webjobs-secrets')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publicAccess": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/default/', tolower(parameters('FunctionName')))]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', parameters('FunctionName'), 'default')]",
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', parameters('FunctionName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"shareQuota": 5120
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"FunctionName": {
|
||||
"defaultValue": "AADUserInfo",
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.KeyVault/vaults/accessPolicies",
|
||||
"apiVersion": "2016-10-01",
|
||||
"name": "[concat(parameters('FunctionName'), '/add')]",
|
||||
"properties": {
|
||||
"accessPolicies": [
|
||||
{
|
||||
"tenantId": "[subscription().tenantId]",
|
||||
"objectId": "[reference(concat(resourceId('Microsoft.Web/sites', parameters('FunctionName')), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2018-11-30').principalId]",
|
||||
"permissions": {
|
||||
"keys": [
|
||||
],
|
||||
"secrets": [
|
||||
"Get",
|
||||
"List",
|
||||
"Set",
|
||||
"Delete",
|
||||
"Recover",
|
||||
"Backup",
|
||||
"Restore"
|
||||
],
|
||||
"certificates": [
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"enabledForDeployment": false,
|
||||
"enabledForDiskEncryption": false,
|
||||
"enabledForTemplateDeployment": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"logging": {
|
||||
"applicationInsights": {
|
||||
"samplingSettings": {
|
||||
"isEnabled": true,
|
||||
"excludedTypes": "Request"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extensionBundle": {
|
||||
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||
"version": "[1.*, 2.0.0)"
|
||||
},
|
||||
"managedDependency": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Azure Functions profile.ps1
|
||||
#
|
||||
# This profile.ps1 will get executed every "cold start" of your Function App.
|
||||
# "cold start" occurs when:
|
||||
#
|
||||
# * A Function App starts up for the very first time
|
||||
# * A Function App starts up after being de-allocated due to inactivity
|
||||
#
|
||||
# You can define helper functions, run commands, or specify environment variables
|
||||
# NOTE: any variables defined that are not environment variables will get reset after the first execution
|
||||
|
||||
# Authenticate with Azure PowerShell using MSI.
|
||||
# Remove this if you are not planning on using MSI or Azure PowerShell.
|
||||
if ($env:MSI_SECRET) {
|
||||
Disable-AzContextAutosave -Scope Process | Out-Null
|
||||
Connect-AzAccount -Identity
|
||||
}
|
||||
|
||||
# Uncomment the next line to enable legacy AzureRm alias in Azure PowerShell.
|
||||
# Enable-AzureRmAlias
|
||||
|
||||
# You can also define functions or aliases that can be referenced in any of your PowerShell functions.
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/proxies",
|
||||
"proxies": {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file enables modules to be automatically managed by the Functions service.
|
||||
# See https://aka.ms/functionsmanageddependency for additional information.
|
||||
#
|
||||
@{
|
||||
'Az' = '5.*'
|
||||
'AzureAD' = '2.*'
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Usage Instruction :
|
||||
// Paste below query in log analytics, click on Save button and select as Function from drop down by specifying function name and alias as AADUserInfo.
|
||||
// Function usually takes 10-15 minutes to activate. You can then use function alias from any other queries (e.g. AADUserInfo | take 10).
|
||||
// Reference : Using functions in Azure monitor log queries : https://docs.microsoft.com/azure/azure-monitor/log-query/functions
|
||||
AADUserInfo_CL
|
||||
| summarize arg_max(TimeGenerated, *) by ObjectId_g
|
||||
| project TimeGenerated,
|
||||
ExtensionProperty_createdDateTime=columnifexists('ExtensionProperty_createdDateTime_s', ""),
|
||||
ExtensionProperty_userIdentities=columnifexists('ExtensionProperty_userIdentities_s', ""),
|
||||
ExtensionProperty_onPremisesDistinguishedName=columnifexists('ExtensionProperty_onPremisesDistinguishedName_s', ""),
|
||||
ObjectId=columnifexists('ObjectId_g', ""),
|
||||
ObjectType=columnifexists('ObjectType_s', ""),
|
||||
AccountEnabled=columnifexists('AccountEnabled_b', ""),
|
||||
DirSyncEnabled=columnifexists('DirSyncEnabled_b', ""),
|
||||
DisplayName=columnifexists('DisplayName_s', ""),
|
||||
GivenName=columnifexists('GivenName_s', ""),
|
||||
MailNickName=columnifexists('MailNickName_s', ""),
|
||||
OnPremisesSecurityIdentifier=columnifexists('OnPremisesSecurityIdentifier_s', ""),
|
||||
PasswordPolicies=columnifexists('PasswordPolicies_s', ""),
|
||||
ProxyAddresses=columnifexists('ProxyAddresses_s', ""),
|
||||
RefreshTokensValidFromDateTime=columnifexists('RefreshTokensValidFromDateTime_t', ""),
|
||||
SignInNames=columnifexists('SignInNames_s', ""),
|
||||
Surname=columnifexists('Surname_s', ""),
|
||||
UserPrincipalName=columnifexists('UserPrincipalName_s', ""),
|
||||
UserType=columnifexists('UserType_s', ""),
|
||||
CompanyName=columnifexists('CompanyName_s', ""),
|
||||
Department=columnifexists('Department_s', ""),
|
||||
JobTitle=columnifexists('JobTitle_s', ""),
|
||||
Mail=columnifexists('Mail_s', ""),
|
||||
SipProxyAddress=columnifexists('SipProxyAddress_s', ""),
|
||||
UsageLocation=columnifexists('UsageLocation_s', ""),
|
||||
PasswordProfile=columnifexists('PasswordProfile_s', ""),
|
||||
UserState=columnifexists('UserState_s', ""),
|
||||
City=columnifexists('City_s', ""),
|
||||
Mobile=columnifexists('Mobile_s', ""),
|
||||
PhysicalDeliveryOfficeName=columnifexists('PhysicalDeliveryOfficeName_s', ""),
|
||||
PostalCode=columnifexists('PostalCode_s', ""),
|
||||
State=columnifexists('State_s', ""),
|
||||
StreetAddress=columnifexists('StreetAddress_s', ""),
|
||||
Country=columnifexists('Country_s', "")
|
Загрузка…
Ссылка в новой задаче