Forwarding on prem logs to Azure & Microsoft Sentinel

7 min readDec 23, 2023


TL;DR IaCing an Azure VM and forwarding logs to Sentinel weren’t much on their own, so I’m mashing them together.

Welcome to Part XI of our Back to the Basics Series!

Part I: NTDS.dit vs SAM

Part II: Ownership Matters

Part III: Recovering from a Crash

Part IV: Setting up a Simple Honeypot Account

Part V: Automating DC Deployment

Part VI: Sometimes it’s the dumbest thing

Part VII: Merry Christmas, macros, & Base64

Part VIII: Why old 0 Days make great teaching tools

Part IX: PowerShell & PS1s without PowerShell.exe

Part X: Ownership & so called “effective permissions”

Part XI: Windows Event Forwarding & SACLs

Part XII: Poorly planned honeypots & other Bad Ideas

Part XIII: Setting up a simple honey token

Part XIV: Smartcards and Pass-the-Hash

Part XV: Forwarding logs to Sentinel & basic alerts

Part XVI: Automating VM deployments in Hyper-V

Part XVII: Migrating the lab from ESXi to Hyper-V


I’m in a college class on Azure and the lab environment they gave us was … funky. They also didn’t give us full access to it. Hence I’m using the free $200 credit on my own Azure account for this.

We ran through spinning up & configuring an Azure VM simply by using the Azure AD module in PowerShell.

After that we finally got around to something I’d been meaning to do for months now; forwarding our home lab’s logs to Azure so we can look at them in Microsoft Sentinel.

IaC an Azure VM

This will connect to Azure, create a Resource Group, create a VM, create a public IP address & link it to the VM, and finally allow port 80 through the NSG. By default only ports 3389 and 5985 are allowed, which of course are used by RDP and WinRM for remote management of Windows systems.

Install-Module -Name Az -Repository PSGallery -Force
Update-Module -Name Az -Force
Install-Module -Name PSReadline
Install-Module -Name Az.Tools.Predictor
Enable-AzPredictor -AllSession

New-AzResourceGroup -Name "Test" -Location "EastUS"
New-AzVM -ResourceGroupName "Test" -Name "TestAZ" -Location "East US" -SecurityType TrustedLaunch -Image Win2022AzureEditionCore -Size "Standard_B1s"

#Stop the VM when you're not using it, start it to run a config via PS1
Stop-AzVM -Name "TestAZ" -ResourceGroupName "Test"
Start-AzVM -Name "TestAZ" -ResourceGroupName "Test"

#Create a public IP
New-AzPublicIpAddress -Name "TestPublicIP" -ResourceGroupName "Test" -AllocationMethod Static -Location "EastUS"
#Get the VM's NIC
#$TestAZNIC = (Get-AzVM -Name TestAZ -ResourceGroupName Test).NetworkProfile.NetworkInterfaces
$NIC = Get-AzNetworkInterface -Name "TestAZ" -ResourceGroupName "Test"
$vnet = Get-AzVirtualNetwork -Name "TestAZ" -ResourceGroupName "Test"
$subnet = Get-AzVirtualNetworkSubnetConfig -Name "TestAZ" -VirtualNetwork $vnet
$TestAZIP = Get-AzPublicIpAddress -Name TestPublicIP
#$NIC | Set-AzNetworkInterfaceIpConfig -Name "TestIPConfig" -PublicIPAddress $TestAZIP -Subnet $subnet
$NIC | Set-AzNetworkInterfaceIpConfig -Name "TestAZ" -PublicIPAddress $TestAZIP -Subnet $subnet
$NIC | Set-AzNetworkInterface

#Set the NSG to allow port 80
# Get the NSG resource
$nsg = Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $RGname
# Add the inbound security rule.
$nsg | Add-AzNetworkSecurityRuleConfig -Name $rulename -Description "Allow app port" -Access Allow `
-Protocol * -Direction Inbound -Priority 3891 -SourceAddressPrefix "*" -SourcePortRange * `
-DestinationAddressPrefix * -DestinationPortRange $port
# Update the NSG.
$nsg | Set-AzNetworkSecurityGroup

#Random stuff just for the class
#Create an Azure Key Vault
New-AzKeyVault -Name "MiskyKeyVault" -ResourceGroupName "Test" -Location "East US"
#Create a new recovery vault
New-AzRecoveryServicesVault -Name "MishkyRecoveryVault" -ResourceGroupName "Test" -Location "East US"
#Create a storage account
Register-AzResourceProvider –ProviderNamespace Microsoft.Storage
New-AzStorageAccount -Name "mishkyblobstorage" -ResourceGroupName "Test" -Location "East US" -AccessTier Hot -Kind BlobStorage -SkuName Standard_LRS
#Register for Microsoft.Insights to run queries on Key Vault logs
Register-AzResourceProvider –ProviderNamespace Microsoft.Insights

#Azure proves a simple way to configure VMs as one can simply run a PS1 that stored locally:
#Run commands & PS1s on Azure VMs
Set-Location ".\WGU\Cloud Security"
Invoke-AzVMRunCommand -VMName "TestAZ" -ResourceGroupName "Test" -CommandId "RunPowerShellScript" -ScriptPath ".\Test.ps1"

There’s more commands than ‘RunPowerShellScript’ one can do:

| Name | Description |
| RunPowerShellScript | Executes a PowerShell script |
| DisableNLA | Disable Network Level Authentication |
| DisableWindowsUpdate | Disable Windows Update Automatic Updates |
| EnableAdminAccount | Enable administrator account |
| EnableEMS | Enable EMS |
| EnableRemotePS | Enable remote PowerShell |
| EnableWindowsUpdate | Enable Windows Update Automatic Updates |
| IPConfig | List IP configuration |
| RDPSettings | Verify RDP Listener Settings |
| ResetRDPCert | Restore RDP Authentication mode to defaults |
| SetRDPPort | Set Remote Desktop port |

For example one could run

Invoke-AzVMRunCommand -VMName "TestAZ" -ResourceGroupName "Test" -CommandId "DisableNLA"

If NLA is enabled on the VM and stopping you from RDPing in.

Test.ps1 contains the below:

Get-Date | Out-File C:\Users\Mishky\Desktop\test.txt -Append
whoami | Out-File C:\Users\Mishky\Desktop\test.txt -Append
hostname | Out-File C:\Users\Mishky\Desktop\test.txt -Append

Install-WindowsFeature -name Web-Server -IncludeManagementTools

Move-Item "C:\inetpub\wwwroot\iisstart.png" -Destination "C:\inetpub\wwwroot\iisstart.png.bak"
Invoke-WebRequest "" -OutFile "C:\inetpub\wwwroot\iisstart.png"
$File = "C:\inetpub\wwwroot\iisstart.htm"
$LineNumber = 3
$TextToAdd = "<p>Welcome to Mishky's unicorn Azure VM!</p>"
$fileContent = Get-Content $File
$fileContent[$LineNumber-1] += $TextToAdd
$fileContent | Set-Content $File

I just wanted to confirm everything was working and the webserver was reachable.

One can RDP into the VM via:

mstsc /v: $TestAZIP.IpAddress

One can view the website via:

$MishkyIP = $TestAZIP.IpAddress
$MishkyPage = "http://$MishkyIP"
Start-Process MSEdge $MishkyPage

Mishka was amused.

Clean up

It costs money to keep VMs and public IPs around in Azure, so we removed them afterwards.

#Remove the Public IP, VM, and VM disk afterwards
#Detach the public IP
$TestAZIP = Get-AzPublicIpAddress -Name TestPublicIP
$NIC = Get-AzNetworkInterface -Name "TestAZ" -ResourceGroupName "Test"
$vnet = Get-AzVirtualNetwork -Name "TestAZ" -ResourceGroupName "Test"
$subnet = Get-AzVirtualNetworkSubnetConfig -Name "TestAZ" -VirtualNetwork $vnet
$NIC | Set-AzNetworkInterfaceIpConfig -Name "TestAZ" -PublicIPAddress $null -Subnet $subnet
$NIC | Set-AzNetworkInterface
Remove-AzPublicIpAddress -Name "TestPublicIP" -ResourceGroupName Test

Remove-AzVM -Name "TestAZ" -ResourceGroupName Test
Get-AzDisk -ResourceGroupName TestAZ | Remove-AzDisk -Force

Setup log forwarding & Sentinel

This was actually really straightforward. This guide was very helpful as well.

We had previously setup Windows Event Forwarding here. Hence all that was required for Sentinel was

  • Setup Azure Arc on TestWEC
  • Create a Log Analytics Workspace in Azure
  • Deploy Sentinel
  • Add the “Windows Forwarded Events” connector to Sentinel

The linked guide already does a great job showing how to set everything up on Azure, so I won’t re-invent the wheel here. Once it’s complete you will see the logs in Azure.

Test it out

I set an alert in Sentinel to trigger on over 100 failed logins in one hour. Just make sure that you are logging failed logins in Group Policy. This is located under

Computer Configuration \ Windows Settings \ Security Settings \ Advanced Audit Policy Configuration \ Audit Policies \ Logon/Logoff -> Set to ‘Configure the following audit events: Success & Failure’

Please note that this will generate Event ID 4625. If you want to verify that failed logins are getting logged then just run this query on your Windows Event Collector (TestWEC in our case):

Get-WinEvent -Path “$env:SystemRoot\System32\Winevt\Logs\ForwardedEvents.evtx” | Where-Object {($_.Id -eq “4625”) -and ($_.TimeCreated -gt (Get-Date).AddHours(-1))}

I then caused the alert to trigger by jumping on our Kali VM and running a brute force attack on the builtin Administrator account.

crackmapexec smb -u Administrator -p /home/kali/Downloads/Wordlists/rockyou.txt
use auxiliary/scanner/smb/smb_login
set PASS_FILE /home/kali/Downloads/Wordlists/rockyou.txt
set SMBUser Administrator
set SMBDomain test.local

Within minutes Miska got an email alert.

I’m not much of a SIEM Guy, so this is pretty primative. I just wanted to make sure everything worked and could generate alerts. I had been meaning to setup log forwarding to Sentinel for awhile and we finally got around to it.

We went over some things you might want to check logs for and how to check here, how to setup a simple honey token and an alert if anyone accesses it here, and how to setup a honey account that would alert if someone password sprayed here. Those howtos were all done in PowerShell on premise however. We have much to learn still regarding Sentinel. If anyone has good tips & tricks on utilizing Sentinel then please feel fee to put them in the comments!


I have to finish up the paper for this college class, but Azure has helped quite a bit already. Microsoft helpfully suggests utilizing their builtin capabilities to vulnerability scan your VMs, using Defender to help protect them, deploying a Firewall on your virtual network, deploying health monitoring, leveraging Azure’s backup feature, and so on. These are all good suggestions for the fictional organization in the college assignment. I have been researching them and including them in the suggested course of action.

I just hate college style writing, so it’s been slow going.


Steps to deploy Sentinel:

Add a server to Azure Arc:

Install Azure PowerShell & Connect-AzAccount:

Add a public IP to AZ VM:

Allow a port in NSG:

Azure Key Vaults:

Event Id 4625:

Querying by date/time, PowerShell:

Querying by date/time, Sentinel:

Customize Sentinel alerts:

Easily create ASCII tables:




I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.