Auditing the VMware UEM Configuration Share

 

I want to start this blog post by saying that the content of this post is based upon great solutions and work by others. A special thanks and appreciation go out to Boe Prox for providing his PowerShell function New-FileSystemWatcher and to Mike Bijl for providing the configuration steps and his PowerShell script for looking up file/folder changes and user name and machine name lookup.

Introduction

VMware User Environment Manager (UEM) does not have auditing build in. However, VMware UEM is all file/folder based, and therefore a solution that audits files and folders should normally be sufficient. In this blog post I want to describe a solution which is easy to implement and which can easily be adjusted to your own needs. The solution is built using

  • A Group Policy Object (GPO)
  • A PowerShell script
  • A scheduled task

 

One important thing to mention: This solution only works using a Windows file server (share) that hosts the VMware UEM configuration.

Auditing GPO

A GPO that audits the file system and file share is required for being able to look up the user name that made the change and for looking up the system name from which the change happened.

Use the following steps for creating the Auditing GPO.

Open Group Policy Management and create a new GPO and apply it to your file server hosting the VMware UEM Configuration Share.

In this example my domain controller (INFRA01) is also the server hosting the VMware UEM Configuration Share.

 Edit the GPO and browse to Computer Configuration –> Policies –> Windows Settings –> Security Settings –>Advanced Audit Policy Configuration –> Audit Policies –> Object Access

Configure the following Subcategories and enable the Audit Events for Success

  • Audit Detailed File Share
  • Audit File Share
  • Audit File System
Applying the above GPO to the server hosting the VMware UEM Configuration Share results in events in the Security event log as pictured.

Audit VMware UEM Configuration Share PowerShell Script

The Audit VMware UEM Configuration Share PowerShell Script is the actual brain in this solution. It uses the FileSystemWatcher class for setting up a listener that watches predefined folders and/or files. The following script is an example of how I implemented it in my LAB environment and it does the following (high level).

  • Creates an event log for VMware UEM Configuration Share auditing (VMware UEM)
  • “Listens” for changes in the specified local path (C:\Shares\UEM_Config –> \\INFRA01.lab.local\UEM_Config)
  • Creates events for changes in the specified local path in the specified event log (VMware UEM)

This is the actual content of my script.

$EventLogName = "VMware UEM"
$EventSource = "VMware UEM Configuration"
$UEMConfigPath = "C:\Shares\UEM_Config"
 
$logFileExists = Get-EventLog -list | Where-Object {$_.logdisplayname -eq $EventLogName} 
if (! $logFileExists) {
    New-EventLog -LogName $EventLogName -Source $EventSource
}
 
#
# Credits go to Boe Prox for this part --> https://mcpmag.com/articles/2015/09/24/changes-to-a-folder-using-powershell.aspx
#
 
Function Start-FileSystemWatcher  {
 
  [cmdletbinding()]
  Param (
  [parameter()]
  [string]$Path,
  [parameter()]
  [ValidateSet('Changed','Created','Deleted','Renamed')]
  [string[]]$EventName,
  [parameter()]
  [string]$Filter,
  [parameter()]
  [System.IO.NotifyFilters]$NotifyFilter,
  [parameter()]
  [switch]$Recurse,
  [parameter()]
  [scriptblock]$Action
  )
 
  #region Build  FileSystemWatcher
 
  $FileSystemWatcher  = New-Object  System.IO.FileSystemWatcher
  If (-NOT $PSBoundParameters.ContainsKey('Path')){
  $Path  = $PWD
  }
 
  $FileSystemWatcher.Path = $Path
  If ($PSBoundParameters.ContainsKey('Filter')) {
  $FileSystemWatcher.Filter = $Filter
  }
  If ($PSBoundParameters.ContainsKey('NotifyFilter')) {
  $FileSystemWatcher.NotifyFilter =  $NotifyFilter
  }
  If ($PSBoundParameters.ContainsKey('Recurse')) {
  $FileSystemWatcher.IncludeSubdirectories =  $True
  }
  If (-NOT $PSBoundParameters.ContainsKey('EventName')){
  $EventName  = 'Changed','Created','Deleted','Renamed'
  }
  If (-NOT $PSBoundParameters.ContainsKey('Action')){
  $Action  = {
  Switch  ($Event.SourceEventArgs.ChangeType) {
  'Renamed'  {
  $Object  = "{0} was  {1} to {2} at {3}" -f $Event.SourceArgs[-1].OldFullPath,
  $Event.SourceEventArgs.ChangeType,
  $Event.SourceArgs[-1].FullPath,
  $Event.TimeGenerated
  }
  Default  {
  $Object  = "{0} was  {1} at {2}" -f $Event.SourceEventArgs.FullPath,
  $Event.SourceEventArgs.ChangeType,
  $Event.TimeGenerated
  }
  }
  $WriteHostParams  = @{
  ForegroundColor = 'Green'
  BackgroundColor = 'Black'
  Object =  $Object
  }
  Write-Host  @WriteHostParams
  }
  }
 
#endregion  Build FileSystemWatcher
    #region  Initiate Jobs for FileSystemWatcher
  $ObjectEventParams  = @{
  InputObject =  $FileSystemWatcher
  Action =  $Action
  }
  ForEach  ($Item in  $EventName) {
  $ObjectEventParams.EventName = $Item
  $ObjectEventParams.SourceIdentifier =  "File.$($Item)"
  Write-Verbose  "Starting watcher for Event: $($Item)"
  $Null  = Register-ObjectEvent  @ObjectEventParams
  }
  #endregion  Initiate Jobs for FileSystemWatcher
}
 
Start-FileSystemWatcher -Path $UEMConfigPath -Recurse -Action {
 
	#
	# Credits go to Mike Bijl for this part --> https://www.linkedin.com/in/mikebijl/
	#
 
	$name = $Event.SourceEventArgs.Name
	$changeType = $Event.SourceEventArgs.ChangeType
	$timeStamp = $Event.TimeGenerated
	$after = $timeStamp.addSeconds(-2) 
	$before = $timeStamp.addSeconds(+2)
	start-sleep -Seconds 2
	$evententries = @(Get-WinEvent -FilterHashtable @{logname="Security"; starttime=$after;endtime=$before; ID = 5145 } -MaxEvents 10 )
	foreach($evententry in $evententries) {
		$user = ""
		$null = $($evententry.Message) -match '.*Account\sName:\s*(?.*)\x0D'
		$user = $($matches['content'])
		$null = $($evententry.Message) -match '.*Source\sAddress:\s*(?.*)\x0D'
		$machine = $($matches['content']) + " `($([system.net.dns]::gethostentry("$($matches['content'])").HostName)`)"
		If ($user -ne "") {break}
	}
 
	$Object  = "{0} was {1} at {2} by {3} on {4}" -f $Event.SourceEventArgs.FullPath,
	($Event.SourceEventArgs.ChangeType | Out-String).ToUpper(),
	$Event.TimeGenerated,
	$user.ToUpper(),
	$machine.ToUpper()
	$WriteHostParams  = @{
		ForegroundColor = 'Green'
		BackgroundColor =  'Black'
		Object =  $Object
	}
 
	Write-Host @WriteHostParams
	Write-EventLog -LogName "VMware UEM" -Source "VMware UEM Configuration" -EntryType "Information" -EventId "1001" -Message $Object
}

You can download the script and change it to your own needs.

Scheduled Task Configuration

Follow the next steps for creating the scheduled task that runs the PowerShell script.

 Start Task Scheduler and create a new Task (not a Basic Task)

On the General tab, give the task a name and use the SYSTEM account for running the task and select Run with highest privileges

On the Triggers tab, create a new trigger and select At startup for Begin the task

Select Delay task for 1 minute

Select Repeat task every 1 hour for a duration of Indefinitely

Select Enabled

On the Actions tab, create a new action and select Start a program for Action

For Program/script enter C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

For Add arguments (optional) enter -noexit -executionpolicy bypass -file “D:\Audit VMware UEM Configuration Share.ps1”

Change the path to the script when needed.

Select Run task as soon as possible after a scheduled start is missed

That’s all for creating the scheduled task.

End Results

When I now create/edit/delete configurations in the VMware UEM Management Console it will be picked up by the PowerShell script that’s running (scheduled task) and it will create events in the event log, specifying the file/folder, action (Create/Delete/Change), date/time, user name and source computer name.

Ivan de Mes

Ivan de Mes

Ivan de Mes works as an EUC Solution Architect for Login Consultants in The Netherlands. Ivan has over 19 years of experience in delivering workspace solutions at large customers in banking, health care, education and others.

In 2017, 2018 and 2019, Ivan was rewarded with the VMware vExpert status. In 2018, Login VSI rewarded Ivan with the Login VSI Technology Advocate status.

 

For more information, please read the about page.

You may also like...