Category Archives: Security

Lightweight LAPS solution for INtune (MEM)

Managing local admin accounts using Intune has a lot of quirks, my tele-colleague Rudy Ooms has already written extensively about this. He also wrote a PowerShell solution to rotate a specific local admin’s password and had the genius idea of using Proactive Remediations (a MEM feature) to display passwords to admins, integrated / free in the Intune Console.

However, I felt I needed a more lightweight solution that;

  • does not require/modify registry keys
  • does not store the password locally
  • does not need separate detection and remediation scripts
  • automatically provisions a local admin account
  • can remove any other local admin accounts if desired
  • is language/locale-agnostic (e.g. ‘Administrators’ vs ‘Administradores’….)

Thus LeanLAPS was born!

To install/use:

1. head into the Proactive Remediations section of MDE and click Create script package:

2. Fill out some details:

3. Download and doublecheck the config of LeanLAPS.ps1 (e.g. configure if other local admins should be removed, what the local admin name should be and the password length). Make sure to use NotePad++ / that the file stays UTF-8 Encoded without a BOM.

4. Set both the detection and remediation script to LeanLAPS.ps1 and run it in 64 bit:

5. Assign to a device group (user groups won’t work) and deploy. By default it will run every day, but you can also let it run more or less frequently, which determines how often the password is reset (hourly in below example):

6. Deploy, and then click on the script package:

7. Go to Device status and add both output columns:

Congratulations, you can now see the current local admin passwords for all managed Windows 10 devices!

Note: if you wish to trigger a quick remediation, delete the correct keys under Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\IntuneManagementExtension\SideCarPolicies\Scripts\Execution and Reports in the client’s registry, then restart the IntuneManagementExtension service and the remediation will re-run within 5 minutes.

RBAC

If you provide e.g. your helpdesk with the correct Intune roles, they will be able to see local admin passwords as reported by above solution:

Previewing image.png

Self scheduling cleanup job for MEM kiosk machines

Normally I’d recommend using the Unified Write Filter in Windows 10 to keep Kiosk machines in a semi-decent state.

For a customer that did not have this luxury, I wrote a tiny self-scheduling PowerShell script that will run as SYSTEM and clean up any of the specified folders in any of the user profiles on the machine.

This example can be used for many purposes to drop a script and maintain a scheduled task. Redeploying it will overwrite the dropped script and scheduled task as per the new config.

Git link or direct code here:

#Module name:      Invoke-wipeSpecifiedProfileFolders
#Author:           Jos Lieben
#Author Blog:      https://www.lieben.nu
#Date:             18-12-2020
#License:          Free to use and modify non-commercially, leave headers intact. For commercial use, contact me
#Purpose:          Delete all files in the specified folder names in all user profiles on the machine, self-installs as a scheduled task
#Setup:            Deploy to machines, in system context
#Requirements:     Windows 10 build 1803 or higher

$folderWipeList = "Downloads,Network Shortcuts,Temp,Documents" #comma seperated list of folders to wipe

$desiredScriptFolder = Join-Path $env:ProgramData -ChildPath "Lieben.nu"
$desiredScriptPath = Join-Path $desiredScriptFolder -ChildPath "Invoke-wipeSpecifiedProfileFolders.ps1"
if(![System.IO.Directory]::($desiredScriptFolder)){
    New-Item -Path $desiredScriptFolder -Type Directory -Force
}
Start-Transcript -Path (Join-Path $desiredScriptFolder -ChildPath "\folderWiperInstaller.log")

Write-Output "Configuring scheduled task..."

$taskname = "Invoke-wipeSpecifiedProfileFolders"
$taskdescription = "Delete all files in the specified folder names in all user profiles on the machine"
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-NoProfile -WindowStyle Hidden -NonInteractive -ExecutionPolicy ByPass -File `"$desiredScriptPath`""
$triggers =  @()
$triggers += (New-ScheduledTaskTrigger -AtStartup)
$triggers += (New-ScheduledTaskTrigger -Daily -At 23:00)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 5) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
$task = Register-ScheduledTask -Action $action -Trigger $triggers -TaskName $taskname -Description $taskdescription -Settings $settings -User "System" -Force -RunLevel Highest

Write-Output "task info: "
Write-Output $task

Write-Output "Writing script file to local disk..."

$scriptContent = "
Start-Transcript -Path (Join-Path $desiredScriptFolder -ChildPath `"\folderWiper.log`")
`$folderWipeList = `"$folderwipeList`"
`$folderWipeList = `$folderwipeList.Split(`",`")
Get-ChildItem 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList' | ForEach-Object {
    `$rootPath =  `$_.GetValue('ProfileImagePath') 
    Write-Output `"Parsing folders in `$rootPath`"
    `$childItems = `$Null
    `$childItems = Get-ChildItem -Path `$rootPath -Directory -ErrorAction SilentlyContinue -Recurse -Force | where{`$folderWipeList -contains `$_.BaseName}
    if(`$childItems){
    	foreach(`$folder in `$childItems){
    		Write-Output `"Wiping matched folder: `$(`$folder.FullName)`"
    		Get-ChildItem -Path `$folder.FullName -Force -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue -Recurse -Confirm:`$False
    	}
    }
}

Stop-Transcript"

Set-Content -Value $scriptContent -Path $desiredScriptPath -Force -Confirm:$False

Write-Output "Starting script as task for the first time..."

Start-ScheduledTask -InputObject $task

Write-Output "Install script has finished running"

Stop-Transcript

Grouping devices in MDATP based on registered users

Microsoft Defender Advanced Threat Protection seems to be becoming the defacto leader in the A/V industry, at least when Windows is concerned, but other OS’es seem to be following quickly 🙂

At one of my international customers, many different locations and departments exist and we’d like to group devices in MDATP based on their primary user so we can assigned different administrators automatically, and apply different web filtering policies.

MDATP has the following options available for grouping:

These membership rules don’t say anything about the user, and the machine domains are all cloud native (no hybrid joins). So we need to use Tags to gain flexible targeting in MDATP.

The following PowerShell script can be scheduled as an Azure Runbook to automatically tag all your MDATP devices based on the ‘Company’ attribute of the device’s primary user. It could also be modified easily to e.g. parse a user’s group membership or UPN’s domain.

https://gitlab.com/Lieben/assortedFunctions/-/blob/master/set-MDATPCustomTags.ps1

If you have a lot of devices, it may take a while for the first run (beyond Azure Automation limits), in that case run it locally first and then schedule it.

Sensitive group protection

It is best practise in IT to secure access to resources with Groups.

Membership of a security group means access to whatever resources are secured by that group. Sometimes these groups are self-managed by an owner, sometimes centrally.

In all cases, fairly low privileged users, that are not global admins, can add users to these groups including themselves. Imagine that you have a group called ‘Global Admins’, and your helpdesk user assigns himself to that group. You’d like to know right?

With Privileged Access Groups in Azure AD (Preview) you can protect groups like these actively, but, this requires a P2 license and still lacks some customization features.

An alternative method is to use a simple alerting rule in MCAS (Microsoft Cloud App Security), where you set an alert when ‘someone’ joins a specific group, or if you want to do more than alerting you could also run an automation playbook.

Here’s how to protect a specific Azure AD or Office 365 group with MCAS:

  1. look up its GUID in AzureAD
  2. Create an Activity Policy in the MCAS console
  3. Specify the group GUID as ‘Activity object ID’ in the policy and the correct action type: